warmup-7c9673 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited warmup-7c9673 (Agent Skill) and scored it 96/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 1 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 1 flagged
The text {match} tells the agent to skip the normal "ask the user first" gate. Used adversarially it removes the human-in-the-loop check before destructive or sensitive actions, turning a normally-gated agent into a fire-and-forget executor.
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
In the gym, a warmup is not optional. You do not walk under the bar cold. A warmup primes your nervous system, surfaces what is tight, and tells you whether today's session needs to be adjusted before the work begins. It is the ten minutes that makes the next ninety honest.
The Warmup does the same thing for your workday. Before you open your inbox, before you take the first meeting, before you have the conversation that shapes the next quarter — you know what moved. You know who is active. You know what the field looks like this morning.
You do not go under the bar cold.
The name comes from Mission Built, where the principle is: prepare like the result matters, because it does.
Activate this skill when the user asks you to do any of the following:
Trigger phrases include: "warmup", "run warmup", "run the warmup", "start my warmup", "give me my warmup", "what's in the brief today", "warmup setup", "set up the warmup", "configure the warmup", "warmup config", "add [source] to my warmup", "remove [source] from warmup", "show my warmup sources", "exclude [source] from warmup".
Signal over noise. Every source labeled. Every claim attributed.
The Warmup has a point of view: authoritative sources first, flagged sources clearly marked, nothing buried in volume. A brief that forces you to sort through noise is not a brief — it is a second inbox.
Four principles:
1. Tier before topic. Every item in the brief carries its source's trust tier visually. A Tier 1 government advisory and a Tier 3 community post are not the same weight of evidence. The brief treats them differently because they are different. The user always knows what they are reading.
2. Absence is information. If a source returns nothing today, that is reported. If a source is unavailable, that is reported. A blank section is never padded. Silence from a source that usually speaks is itself a signal.
3. The source panel is not optional. Every run of the brief ends with a full disclosure of every source that was consulted — active, quiet, or excluded. The user must always be able to audit what their brief was built on. This is the contract.
4. Recommendations, not mandates. When the skill recommends sources, it explains why. When it flags a source as lower tier, it says so and says why. The user decides what goes in their brief. The skill's job is to make sure those decisions are informed.
Three modes. Each is triggered by a natural phrase.
| Mode | When | What this skill does |
|---|---|---|
| SETUP | First time, or reconfiguring from scratch | Establish the user's profile, build their source suite, save to WARMUP.md, run a test brief |
| RUN | Any time the user wants their brief | Read WARMUP.md, fetch live intelligence from each active source, synthesize sections, render the Iron Log artifact |
| CONFIGURE | Modifying sources without full re-setup | Show active sources, apply changes (add / remove / exclude), update WARMUP.md |
Brief types available at SETUP:
| Brief type | Who it's for | Core focus |
|---|---|---|
| CISO | Security executives | Threat actors, CVEs, research, vendor market, regulatory |
| Product Leader | GMs, PMs, anyone steering a product | Company signal, competitors, AI in product, funding, platform risk, vertical-specific |
| Custom | Anyone | User-defined interests, fully flexible source suite |
If no WARMUP.md exists in the project root and the user asks to RUN, prompt for SETUP first: "No Warmup config found. Run 'warmup setup' to build your source suite — it takes about two minutes."
Trigger: "warmup setup", "set up the warmup", "configure the warmup for the first time"
Ask the user: "Three brief types to choose from — which fits you best? · CISO — cybersecurity executive brief · Product Leader — GM / PM intelligence brief · Custom — describe your own interests and I'll build a source suite around them"
source suite curated for security executives. Provide your company name and sector, region, and peer vendors are looked up automatically — one confirmation and you're done.
Provide your company name and competitors, vertical, region, and model are researched automatically. Confirm what's right, answer two quick follow-ups, and the brief is ready.
interests. Takes a few more questions.
Once the mode is chosen, ask: "What's your name? I'll use it in your brief header." Examples: "Mike", "Sarah", "Alex" — or they can skip with anything like "doesn't matter" or "just leave it blank". Stored only in the local WARMUP.md, never sent anywhere. Save as name: in the profile. If skipped, leave blank.
Lead with company name. Auto-fill everything derivable. Ask only what can't be looked up.
Ask: "What's your company name? I'll look up your sector, region, and typical peer vendors automatically. Or say 'skip' and I'll ask instead."
If the user provides a company name:
Call the WebSearch tool with query: "[Company]" company overview industry sector headquarters cybersecurity
From the results, determine:
Present all findings in a single confirmation message:
"Here's what I found for [Company]: · Sector: [X] · Region: [Y] · Peer vendors to track: [A, B, C] Does that look right? Edit anything or say 'looks good' to continue."
Accept natural-language edits. Update any field the user corrects. Save company, sector, and region to WARMUP.md.
Then ask these two follow-up questions — do not skip them:
Follow-up 1 — People to follow: "Anyone in the security world you want to follow closely — executives, CISOs, researchers, threat intel voices? I can suggest a few based on [Company]'s space." Suggest 2–3 relevant names based on sector and company (e.g., known CISOs at peer companies, prominent threat researchers, security journalists). Present as: "People like [A], [B], [C] are worth following if you're in [sector]. Anyone to add, or skip this?" Save confirmed names to track_people: in WARMUP.md. If skipped, leave blank.
Follow-up 2 — Personal interests: "Last one — anything you want at the end of your brief that's not work? Sports, markets, a hobby, a team?" Save to special_interests: in WARMUP.md. If skipped, omit the section. Accept any answer — "skip", "nothing", or an actual interest. Do not pressure.
If the user skips the company name:
Ask these four questions one at a time:
Examples: "Healthcare", "Financial Services", "Energy / Utilities", "Technology", "Government", "Manufacturing / OT", "Retail", "Critical Infrastructure" Accept open-form. Map to the Sector Sources table below.
Examples: "United States", "European Union", "APAC", "Latin America", "Global"
Examples: "Palo Alto, CrowdStrike, Wiz", "Microsoft Sentinel, Splunk, SentinelOne", "skip"
Build the source suite from the CISO Source Suite tables below. Add sector-specific sources from the Sector Sources table.
Lead with company name. Auto-fill sector, region, and competitors. Ask only what can't be looked up.
Ask: "What's your company name — and what product or area are you responsible for? I'll look up your sector, region, and top competitors automatically. Or describe it yourself and I'll go from there."
Examples: "Acme Corp, security platform", "Blue Yonder, supply chain", "skip — I'll describe it"
If the user provides a company name:
Call the WebSearch tool with query: "[Company]" product overview market competitors B2B B2C industry
From the results, determine:
b2b / b2c / platform / marketplace / hybrid. If ambiguous, note it and ask.Present all findings in a single confirmation message:
"Here's what I found for [Company]: · Product: [what they build] · Model: [B2B / B2C / platform] · Vertical: [customer industry] · Region: [Y] · Top competitors: [A, B, C, D] Does that look right? Edit anything or say 'looks good' to continue."
Accept natural-language edits. If B2B/B2C is still unclear after the search, ask: "One quick one — are you selling to businesses, consumers, or is it a platform other developers build on?"
If the user's vertical doesn't map cleanly, ask: "What does a bad week look like for your business — what external event would most disrupt your roadmap?" Use the answer to infer the right vertical section.
Then ask these three follow-up questions — do not skip them:
Follow-up 1 — AI vendors: "Which AI vendors or tools matter most to your roadmap? I'd default to OpenAI, Anthropic, Google DeepMind, and Meta AI — plus any tools your team uses (Copilot, Cursor, Mistral). Anything to add or drop?" Save confirmed list to ai_vendors: in WARMUP.md. If skipped, use the default set.
Follow-up 2 — People to follow: "Anyone you want to track closely — executives, investors, analysts, journalists, or researchers? I can suggest a few based on [Company]'s space." Suggest 2–3 relevant names based on vertical and company (e.g., for a security platform: relevant VCs, CISOs at peer companies, prominent analysts). Present: "People like [A], [B], [C] are worth following if you're in [vertical]. Anyone to add, or skip this?" Save confirmed names to track_people: in WARMUP.md. If skipped, leave blank.
Follow-up 3 — Personal interests: "Last one — anything you want at the end of your brief that's not work? Sports, markets, a hobby, a team?" Save to special_interests: in WARMUP.md. If skipped, omit the section. Do not pressure.
If the user skips the company name:
Ask these five questions one at a time:
Accept open-form. Infer product focus, B2B/B2C, and vertical from the answer.
Map to the vertical source options below.
Generate a suggested list based on what they've described. Present: "Based on what you've told me, I'd start with: [A, B, C]. Does that look right?"
Suggest the standard default set and let them edit.
Ask: "Describe what you want in your warmup. Be specific — topics, companies, industries, markets, regions, anything that matters to how you start your day."
From the described interests, map each to one or more recommended sources using the Custom Mode Source-Building Rules below.
For each mapped source, state:
Items from it will be labeled in the brief. Worth including?"*
Recommend any sources the user likely wants but did not mention.
Show the full proposed source suite before saving. Format:
Tier 1 — Authoritative
● CISA Alerts & Advisories
● CISA Known Exploited Vulnerabilities (KEV)
● NVD / CVE Database
...
Tier 2 — Research
◉ CrowdStrike Intelligence Blog
◉ Palo Alto Unit 42
...
Tier 3 — News
○ Krebs on Security
...
Excluded from this run: (none)
Special Interests (if provided)
○ [Interest 1] — list the 1–3 sources that will cover it
e.g. "Formula 1 → motorsport.com, ESPN F1, AP Sports"
e.g. "SEC football → ESPN, 247Sports, AP Sports"
e.g. "Bourbon releases → Whisky Advocate, BourbonBlog.com"
e.g. "Markets → Reuters Markets, Yahoo Finance"
○ [Interest 2] — same formatIf special interests were provided, always list them here. The user deserves to see what sources their brief will pull from — this section is not optional when interests exist.
Ask: "Any sources to add or remove before I save this?"
Before saving, ask: "Last thing — how far back should I look for your first brief? The default is 1 day, but since this is your first run I'd recommend 7 days to get up to speed, or 30 days for a full month of context. What works for you?"
Accept any natural phrasing: "7 days", "go back two weeks", "just today", "one month". Save the answer as window_override in WARMUP.md if the user wants a persistent window, or use it only for this run if they say so. If the user says "default" or "1 day", use adaptive lookback (no override). Remind them: "You can always override this at run time — just say 'warmup, go back 2 weeks' and I'll use that window for that run only."
Also ask about search depth:
"One more setting — search depth. By default I cap each search batch to 5 results and 200 words per article. This keeps the brief fast and token-efficient (typically 40–60K tokens for the fetch phase). If you have more token budget, 'deep' mode doubles both — 10 results per batch, 400 words per article — for broader coverage at roughly 2× the fetch cost. Standard is what I'd recommend for daily use. Which do you prefer?"
Save as search_depth: standard or search_depth: deep in WARMUP.md. If the user skips or has no preference, default to standard.
Save the config file at the project root using the WARMUP.md Config Format defined below.
Immediately run a RUN cycle. If any sources return nothing, report: "[Source] returned no signal in the test run. It may be temporarily unavailable or the search found nothing recent. I've kept it in your config — it will be checked each run."
Do not remove sources from config due to a single empty result.
Trigger: "warmup", "run warmup", "run the warmup", "start my warmup", "give me my warmup", "what's in the brief today"
Override trigger: The user can specify a custom lookback at run time: "run the warmup one month back", "run warmup since April 15", "give me the last two weeks", "warmup — go back 30 days". If a lookback phrase is detected, use that window instead of the computed window and note it in the chat summary line.
First: find workspace root — call list_artifacts:
"the-warmup" exists → take its html_path and strip the filename.e.g. "/Users/jane/Projects/loadout/warmup.html" → "/Users/jane/Projects/loadout"
"the-warmup" artifact → find the user's selected workspace folder in your system context.It is the folder the user mounted in Cowork — a short, human-readable path like /Users/[name]/Projects/[folder]. It is NOT the working directory, outputs folder, or any session/temp path.
Validate — if the workspace root contains any of these strings, you have the WRONG path: "Application Support" · "sessions" · "outputs" · "uploads" · "local-agent" · "tmp"
A correct workspace root looks like: /Users/mike/Projects/loadout
If you cannot determine a valid workspace root, stop and ask the user to confirm their workspace folder.
Then use the Read file tool (not bash) to read [workspace-root]/WARMUP.md. If WARMUP.md does not exist, stop and prompt for SETUP.
Note: mode (CISO or Custom), user profile, active source list, excluded sources, last_run date, window_override if set.
Compute the lookback window:
today = current date (YYYY-MM-DD)
last_run_date = parsed from WARMUP.md `last_run` field (YYYY-MM-DD)
gap_days = (today - last_run_date) in calendar days
# Override checks — apply first, skip the rest if matched
if user stated a lookback phrase in this run (e.g. "go back 30 days", "since April 15"):
window = user-specified value # note in summary line, skip remaining logic
elif window_override is set in WARMUP.md:
window = window_override
elif last_run is missing or empty:
window = 30 # first run — bootstrap with a month of context
elif gap_days == 1 AND daily_mode: true in WARMUP.md:
window = 2 # daily fast-path: skip re-fetching a full 7-day window
elif gap_days <= 7:
window = 7 # standard — always covers at least a week
else:
window = min(gap_days, 30) # catch-up run, capped at 30 days
# Weekend bridge (run after computing window above)
region = WARMUP.md `region` field (default: Sat+Sun weekend; IL/Israel: Fri+Sat)
if today == first working day after regional weekend AND gap_days <= 2:
window = max(window, gap_days + 2) # cover full weekend
note in summary: "Lookback extended to cover weekend"
if gap_days > 7 AND interval spans a user-declared holiday (Notes: "holiday: YYYY-MM-DD"):
note in summary: "Catch-up run — verify holiday coverage manually if needed"
# Search date parameter
search_after_date = today - (window + 1) days # +1 catches late-yesterday and early-todayNote the computed window in the summary line. Hard date filter: every item in the brief MUST have a publication date within the lookback window — no exceptions. If a source has no in-window items, mark it "status": "quiet".
Before starting any searches, output this line in chat: "🔍 Gathering intelligence from [N] sources · [M] search batches · lookback [X] days — this takes a few minutes."
Run all batches concurrently. Do not wait for one batch to complete before starting the next — they are independent. Fire all batches in a single parallel pass, then synthesize after all return.
For each active source, search for recent content using WebSearch.
Search using compound batch queries — not one query per source. This cuts fetch volume from ~38 calls to ~10 without losing coverage. Run batches concurrently where possible; they do not depend on each other.
Batch query table (CISO mode):
| Batch | Sources covered | Query pattern |
|---|---|---|
| Gov pulse | CISA + NSA + FBI + FTC | (site:cisa.gov OR site:nsa.gov OR site:ic3.gov OR site:ftc.gov) advisory alert after:YYYY-MM-DD |
| Research | MSTIC + CrowdStrike + Red Canary + Wiz + Unit 42 | (site:microsoft.com/security OR site:crowdstrike.com/blog OR site:redcanary.com/blog OR site:wiz.io/blog OR site:unit42.paloaltonetworks.com) [sector] threat after:YYYY-MM-DD |
| CVE sweep | NVD + CISA KEV | (site:nvd.nist.gov OR site:cisa.gov/known-exploited-vulnerabilities) CVE critical after:YYYY-MM-DD |
| News | BleepingComputer + SecurityWeek + Krebs + THN + Dark Reading | (site:bleepingcomputer.com OR site:securityweek.com OR site:krebsonsecurity.com OR site:thehackernews.com OR site:darkreading.com) [sector] after:YYYY-MM-DD |
| Market | Reuters + Bloomberg + sector vendors | [company OR sector] acquisition OR breach OR regulatory site:reuters.com OR site:bloomberg.com after:YYYY-MM-DD |
| Social | X + r/netsec + LinkedIn | [sector] security debate OR disclosure site:reddit.com/r/netsec after:YYYY-MM-DD |
| Interests | One per special interest | Targeted query per interest (e.g., Ironman 70.3 results 2026) |
Replace YYYY-MM-DD with the computed lookback start date. Adapt queries to the user's sector and profile (e.g., a Healthcare CISO adds site:hhs.gov hc3 to the gov batch). Run Gov, Research, CVE, News, Market, and Interests batches all concurrently — fire all batches in a single parallel pass, then synthesize after all return. Do not wait for one batch before starting the next.
WebSearch result budget: Check search_depth from WARMUP.md:
standard (default): top 5 results per batch · 200 words per articledeep: top 10 results per batch · 400 words per articleStandard is recommended for daily use — keeps fetch-phase cost at 40–60K tokens. Deep roughly doubles that for broader coverage. If search_depth is not set or unrecognized, use standard.
Record for each found item: source name, trust tier, URL, headline, 2–3 sentence summary, relevant tags (CVE ID, MITRE TTP ID, vendor name, M&A flag, regulatory flag, community flag).
skipScan fast-path: If skip_scan: true is set in WARMUP.md, skip the URL safety check entirely. Set config.skipScan: true, safety.domains: [], and safety.totalUrls: 0 in WARMUP_DATA. Do not call URLScan.io. Do not perform Step A allowlist checks. Proceed directly to synthesis. A friendly disclaimer will render in the artifact in place of the Link Safety panel.
URL safety check — run before adding any item to the brief:
For every URL returned by search, check it against the trusted-domain allowlist and URLScan.io before including it in the report.
Step A — Allowlist check (instant, no API call):
If the URL's registered domain matches the allowlist below → VERIFIED SAFE.
This covers all known-good sources across CISO and Product Leader modes.
CISO allowlist domains:
cisa.gov, nsa.gov, ic3.gov, fbi.gov, ftc.gov, nvd.nist.gov, attack.mitre.org,
crowdstrike.com, unit42.paloaltonetworks.com, redcanary.com, cloud.google.com,
microsoft.com, blog.talosintelligence.com, secureworks.com, recordedfuture.com,
wiz.io, krebsonsecurity.com, thehackernews.com, darkreading.com,
securityweek.com, bleepingcomputer.com, arstechnica.com, scmagazine.com,
crn.com, techcrunch.com, cybersecurityventures.com,
hhs.gov, h-isac.org, fsisac.com, occ.gov, eisac.com, cio.gov,
pcisecuritystandards.org, dragos.com, claroty.com, nozominetworks.com
Product Leader allowlist domains:
sec.gov, crunchbase.com, a16z.com, sequoiacap.com, cbinsights.com,
gartner.com, forrester.com, producthunt.com,
techcrunch.com, theverge.com, wired.com, fastcompany.com,
reuters.com, bloomberg.com, lennysnewsletter.com, reforge.com,
news.ycombinator.com, linkedin.com, g2.com, capterra.com, trustpilot.com,
openai.com, anthropic.com, deepmind.google, ai.meta.com, research.facebook.com,
mistral.ai, huggingface.co, arxiv.org,
github.blog, github.com, stackoverflow.com, changelog.com,
paymentsdive.com, pymnts.com, consumerfinance.gov,
rockhealth.com, himss.org, cms.gov, fda.gov,
socialmediatoday.com, saastr.com, chartmogul.com,
digitalcommerce360.com, freightwaves.com, supplychaindive.com,
nfx.com, bvp.com
User-configured sources (from WARMUP.md `competitors:` and `ai_vendors:` fields):
Extract the registered domain from each configured URL. These are user-chosen
sources that passed their initial review at SETUP. Treat as allowlisted.
Example: if competitors includes "https://www.splunk.com", splunk.com is allowlisted.
Step B — URLScan.io check (for domains not on the allowlist):
Query: https://urlscan.io/search/#domain:<domain>
If result exists AND verdict is explicitly clean → VERIFIED SAFE.
All other outcomes → NOT VERIFIED: treat as flagged and exclude.
"All other outcomes" means: suspicious verdict, malicious verdict, no result
found, API timeout, API error, rate limit, ambiguous verdict, or any condition
where a clean result cannot be positively confirmed. There is no partial credit.
A URL is either verified safe or it does not appear in the report.If a URL is not verified safe (flagged, failed scan, or unknown):
flagged_urls list: {url, domain, verdict, source_name}.For scan failures, set verdict to "scan unavailable".
a link, attributed to the source name only, if the content is relevant (e.g., "CrowdStrike reported X — link omitted, domain not verified").
flagged_urls list feeds into the safety WARMUP_DATA block and issurfaced in the scan badge and the Link Safety section at the bottom of the artifact. The scan badge text updates to: "N links scanned · M not verified".
"⚠ [M] URL(s) excluded — not verified safe (flagged or scan unavailable)."
verification. It must never show a domain that failed or was not checked.
After all batches complete, output in chat: "🔒 Running link safety verification on [N] URLs..."
Safety check is a Step 2 action — not a render-time assumption. The safety.domains array in WARMUP_DATA must be built from the checks actually performed during this fetch phase. Do not copy verdicts from a previous run, do not assume all sources are clean, and do not fill in the array during synthesis or render. Every domain that appears in safety.domains must have been checked in Step 2 of this run. Verdict values: "ALLOWLISTED" (Step A match, no external call), "CLEAN" (Step B URLScan.io explicitly clean). Anything else is flagged and excluded.
If a batch returns nothing: mark those sources "no signal today." Do not invent content. A quiet source is reported honestly.
Source prioritization: Tier 1 and Tier 2 sources are fetched first and given the most depth. Tier 3 and Tier 4 are supplemental. If you run out of capacity, deprioritize Tier 3 and Tier 4 before cutting Tier 1 or 2.
Output in chat before starting synthesis: "⚡ Synthesizing [N] items across [M] sections..."
DATE FILTER — MANDATORY GATE. No item enters WARMUP_DATA without passing this check.
lookback_start = today - lookback_days
BEFORE WRITING EACH ITEM — run this check:
1. Parse item.date as YYYY-MM-DD
2. Is item.date ≥ lookback_start? → INCLUDE
3. Is item.date < lookback_start? → DISCARD immediately. Do not include it "because it's relevant."
Real violations that MUST be caught (window = 7 days, today = 2026-05-16):
lookback_start = 2026-05-09
item.date = 2026-05-08 → 8 days old → REJECT ← one day over. Still REJECT.
item.date = 2026-05-06 → 10 days old → REJECT ← "only two weeks ago" is still REJECT.
item.date = 2026-05-09 → 7 days old → ACCEPT (exactly at boundary = OK)
item.date = 2026-05-10 → 6 days old → ACCEPTNo date = discard. If a result has no parseable publication date, discard it. Do not guess or assume.
"Relevant but old" = still discard. An article can be highly relevant and still violate the date filter. Relevance does not override the date gate.
If after filtering a source has zero in-window items, mark it "status": "quiet" in sources[] and exclude it from safety.domains.
Source status must match what appears in the brief. A source is "active" only if at least one of its items is included as a card in the brief. If you found articles from a source but none make it into the brief (e.g. all outside the window), the source is "quiet". Never mark a source active when none of its articles are visible to the reader.
This gate runs before you organize items into sections. Do not route stale items into sections intending to remove them later — discard at first sight, before any further processing.
Organize fetched items into sections using the Section Structure below (CISO mode) or the user's defined interest categories (Custom mode).
Inclusion rule — the date gate is the only filter. Every item that passes the lookback window check appears in the brief as its own card. Do not cap by volume. Do not fold a distinct story into another item's body copy. Do not drop an item because a "better" item covers the same theme. Do not editorially select a subset. If the agent found it and it is within the window, the reader sees it. The brief may have more items on active news days and fewer on quiet ones — that variance is correct and honest. Within a section, order items by recency (newest first), with the most recent item as the section lead.
If special_interests is set in WARMUP.md, the Interests batch was already fetched concurrently in Step 2. Do not run a second fetch here.
Render the results from the Step 2 Interests batch as a Special Interests section in the artifact, positioned after AI Intelligence (or Industry Intel if the AI section is not present) and before Social Signal. Use general news and sports/topic sources — label all items with ○ (Tier 3 / Community/News).
Tag format: use [NBA], [SEC FOOTBALL], [F1], etc. — whatever matches the interest. Keep summaries conversational — this is the coffee reading, not an intelligence item. Two to four sentences is enough.
If special_interests is not set or is empty, omit the section entirely. Do not add a placeholder or ask about it during RUN.
ABSOLUTE RULE — NO EXCEPTIONS: The brief HTML is ALWAYS built from the warmup_get_template MCP tool. Never write the HTML from scratch or from training-data memory — the CSS, layout, typography, baked fonts, and PDF builder exist only in the tool response.
Self-contained architecture — data is injected at render time.
The brief is a fully self-contained file: you pass your assembled WARMUP_DATA to warmup_get_template, the server injects it (and stamps the generated-at time) into the __WARMUP_DATA__ placeholder, and fonts are baked into the template. There is no KV, no warmup_save_data/warmup_get_data, no font tool, and no runtime calls back to the server. Each run writes a fresh file.
The flow (the `warmup_run` tool returns the authoritative step-by-step):
WARMUP_DATA object (schema below).warmup_get_template({ intent: "...", chunk: 0, warmup_data: JSON.stringify(WARMUP_DATA) }). Read <!-- WARMUP_TOTAL_CHUNKS: N --> to learn N; the response ends with <!-- __WARMUP_SENTINEL__ --> when N > 1. warmup_data is required on every chunk call — the server re-injects it each time.[workspace-root]/warmup.html (overwrite — every run is fresh).warmup_get_template({ chunk: i, warmup_data: ... }), then Edit-replace <!-- __WARMUP_SENTINEL__ --> with the chunk.<!-- __WARMUP_SENTINEL__ --> → 0 matches; the file ends with </html>.create_artifact (first run) or update_artifact (re-run) with id: "the-warmup" and html_path. No mcp_tools needed — fonts are baked and the brief makes no MCP calls.Do not use bash for any of this. Bash runs in a Linux sandbox where macOS paths are remapped. Use the file tools with the real macOS path from html_path.User requests a correction to the existing brief (no new searches): apply the change to the relevant WARMUP_DATA field(s), re-render with warmup_get_template (steps 2–6), then update_artifact. There is no KV to write.
When an engine bug is fixed:
WARMUP_ENGINE_VERSION in constants.ts.warmup-template.html (the self-contained template the worker injects) and redeploy.`WARMUP_DATA` schema (v0.3.0 — Morning Edition):
Config field accuracy rule:mode,sector,company, andregionMUST be copied verbatim fromWARMUP.md. Do not infer, generalize, abbreviate, or replace. If the user said "Security", sector = "Security". If the user said "Global", region = "Global". These values appear as pills the user sees on every run.
{
"config": {
// Required
"name": "Mike",
"mode": "CISO",
"company": "Acme Corp",
"sector": "Cybersecurity",
"reportDate": "Thursday, 15 May 2026", // REQUIRED — full display string for the masthead date (e.g. "Friday, 15 May 2026").
// Format: "{Weekday}, {DD} {Month} {YYYY}". Use today's date in the user's timezone.
// Without this field the masthead date falls back to template placeholder text.
"updated": "15 May 2026", // Footer display string
"lastRun": "2026-05-14", // ISO date — drives issue number
"dateRange": "May 8 – May 15, 2026", // Lookback window display string
"sourcesActive": 12,
"sourcesQuiet": 4,
"showQuote": true, // REQUIRED — must be true (JSON boolean). Omitting or setting false hides the daily quote.
"scanTime": "", // Leave EMPTY ("") unless you have a reliable clock source.
// Do NOT invent or guess a time — the renderer will use the user's local
// browser clock when this is blank, which is always accurate.
// Only write a value (e.g. "06:14 ET") if a tool explicitly returned the
// current wall-clock time. Writing a fabricated time is worse than omitting.
"timezone": "ET", // REQUIRED — copy verbatim from WARMUP.md `timezone` field (e.g. "ET", "PT", "UTC").
// CRITICAL: this is the USER'S local timezone — NOT the company's headquarters timezone.
// Read it from WARMUP.md. Do not infer from the company location. Write "UTC" if not set.
// Without this field the time display in the masthead is missing timezone context.
// Optional fields — include even if blank (write "" not omit)
"region": "Global",
"vendors": "CrowdStrike, Palo Alto", // Copy verbatim from WARMUP.md vendors field. Write "" if blank — do not omit.
"interests": "",
"totalLinks": 18, // Count of verified-safe clickable URLs in the rendered brief. Must equal safety.totalUrls.
"skipScan": false, // Optional — set true if skip_scan: true in WARMUP.md. Hides scan badge, skips safety panel, shows friendly disclaimer instead.
"searchDepth": "standard" // "standard" | "deep" — copy from WARMUP.md search_depth. Drives depth indicator in sources panel and configure modal.
},
"sections": [
{
"id": "threat",
"label": "Threat Landscape",
"sub": "Active campaigns and fresh exploitation. What your stack should be watching for today.",
// sub: ALWAYS populated — the section's standing editorial deck, one sentence.
// This renders visibly in the brief as italic text under the section heading.
// NEVER put lookback computation text, agent instructions, or meta-commentary here.
// WRONG: "1-day lookback (first run). Say 'warmup, go back 7 days' for context."
// RIGHT: "Active campaigns and fresh exploitation. What your stack should be watching for today."
// Write it as editorial voice — a standing description of what this section covers.
// note: null unless there is a today-only run caveat (e.g. "Source X was down"). Never repeat sub here.
"note": null,
"items": [
{
// items[0] is the EDITORIAL LEAD — rendered full-width with a large
// headline and an oxblood drop-cap on the first letter of body.
// Choose it deliberately: most important item in the section.
"dot": "d1", "src": "CISA",
"tags": [{"cls": "t-alert", "text": "KEV ADDED"}, {"cls": "t-mitre", "text": "T1190"}],
"url": "https://...",
"hl": "Article headline.",
"deck": "Federal agencies have until June 4 to patch.",
// deck: LEAD ITEMS ONLY. One short italic sentence — the 'so what?'.
// Omit entirely on non-lead items (items[1..N]).
"body": "2–3 sentence summary in plain prose.",
"date": "YYYY-MM-DD"
// CRITICAL: date is the article's actual publication date, not today's date
// and not a recycled date from a prior run. The renderer filters out items
// older than 7 days (10 for deep mode, or window_override if set) — stale
// dates make items invisible while still inflating the ITEMS TODAY count.
// If you cannot determine the publication date, use today's date rather
// than guessing or recycling.
},
{
// items[1..N] render in a two-column grid. No deck field. Date-sorted.
"dot": "d2", "src": "Source Name",
"tags": [],
"url": "https://...",
"hl": "Article headline",
"body": "2–3 sentence summary.",
"date": "YYYY-MM-DD"
}
]
}
],
"sources": [
// status: "active" | "quiet" | "excluded" — exact strings only, no other values permitted.
// ct: "N items" for active sources (e.g. "2 items"), "—" for quiet sources, "excluded" for excluded sources.
{"nm": "CISA Alerts & Advisories", "dom": "cisa.gov", "dot": "d1", "ct": "2 items", "status": "active"},
{"nm": "NSA Advisories", "dom": "nsa.gov", "dot": "d1", "ct": "—", "status": "quiet"}
],
"safety": {
// domains: REQUIRED — one entry per active source. Populated from Step 2 checks — never fabricated.
// Empty array = safety panel does not render. This field must not be omitted or left empty.
// verdict values (exact strings):
// "ALLOWLISTED" — domain matched the Step A allowlist (no external call made)
// "CLEAN" — domain passed URLScan.io Step B check (explicitly clean verdict)
// Flagged domains do NOT appear here — they go in flagged_urls and are excluded from the brief.
// INTEGRITY RULE: domains.length MUST equal the number of active sources exactly.
"domains": [{"domain": "cisa.gov", "verdict": "ALLOWLISTED"}],
"totalUrls": 12, // REQUIRED — count of verified-safe clickable URLs in the rendered brief. Must equal config.totalLinks.
"flagged": 0,
"scannedAt": "" // Empty string — renderer uses scanTime. Fill only to override.
},
// dates: REQUIRED — one entry per item using the item's hl string (or a unique prefix) as the key.
// Used by the template to render per-item publication dates. Empty object = no dates rendered.
"dates": {"Article headline prefix": "YYYY-MM-DD"}
}Editorial lead rules:
items[0] is the lead for every section. It renders full-width with a large Oswald headline and an oxblood drop-cap on the first letter of body.deck on lead items — one italic sentence that adds the "so what?" framing.deck field on these.`scanTime` — only write it if you actually know the time. If a tool returned the current wall-clock time, write it as "HH:MM TZ" (24-hour, user's timezone, e.g. "06:14 ET"). If you don't have a reliable clock source, leave it as "" — the renderer falls back to the user's local browser clock, which is accurate. A fabricated timestamp is worse than no timestamp. Do not write separate timestamp values anywhere else.
On engine bugs:
warmup-template.html — the self-contained template the worker injects.WARMUP_ENGINE_VERSION in constants.ts.Never build the artifact HTML from scratch. Always start from the engine shell returned by warmup_get_template. Building from scratch risks re-introducing fixed bugs and diverging from the canonical engine.
After rendering, output a single summary line in the chat: "[N] items across [N] sections · [N] sources active · [N] sources quiet today · Lookback: [N] days"
If this was a catch-up run, append the reason: "… · Lookback: 12 days (catch-up from [last_run_date])"
Nothing else in chat. The brief is the artifact. Do not duplicate its content in the chat response.
When to run: After any successful RUN where (today - updated) >= 30 days. The updated field in WARMUP.md records when the source list was last configured. If it has been 30+ days since the user last touched their source config, scan for new sources that have emerged since then.
How to run:
During the fetch phase, note any domains that appeared in search results but are not in the user's active or excluded source list. After synthesis, evaluate each against the Source Trust Framework. Surface only sources that meet at least one of these bars:
fetched items, not just once) and strong editorial reputation
(new research arm, new government advisory feed, etc.)
Cap at 3 recommendations per run. Do not recommend sources already in the config (active or excluded). Do not recommend a source the user has previously excluded — they made that call deliberately.
Output format — append after the summary line in chat, separated by a blank line:
💡 New source worth adding:
[Source Name] · Tier N · domain.com
[One sentence: what it covers and why it's relevant to the user's sector/profile.]
Say "add [source name] to warmup" to include it.If more than one recommendation: list them as a short block under a single 💡 New sources worth adding: header.
If nothing new qualifies: output nothing. Do not add a "no new sources found" line — silence is the correct signal.
Frequency note: 30 days is the default check interval because a month is roughly how long it takes for a new source to establish a track record worth recommending. If the user wants tighter checks (e.g., weekly), they can add source_check_days: 7 to the Notes section of WARMUP.md and this step will use that value instead.
After a successful render, update the last_run field in WARMUP.md to today's date in YYYY-MM-DD format. This is the record the next run uses to compute its lookback window.
Do not update last_run if the run failed, produced no items, or produced fewer than 3 items total across all sections — treat these as degraded runs and preserve the window so the next run has a wider lookback to recover missing content.
Trigger: "warmup config", "update my warmup", "add source to warmup", "remove source from warmup", "show my warmup sources", "exclude [source] from warmup", "what sources is the warmup using"
Display the current source list in a compact table:
Source | Tier | Domain | Status
--------------------|------|---------------------------|--------
CISA Alerts | 1 | cisa.gov | Active
CISA KEV | 1 | cisa.gov | Active
CrowdStrike Blog | 2 | crowdstrike.com/blog | Active
...
Krebs on Security | 3 | krebsonsecurity.com | ExcludedWARMUP.md under the appropriate tier.Move from active list to Excluded Sources in WARMUP.md. The source remains in the config but is skipped at runtime and shown in the Source Transparency Panel as excluded.
If the user asks for recommendations: suggest 3–5 sources relevant to their profile that they do not already have. For CISO mode, look for gaps in sector-specific coverage or missing Tier 2 research firms.
If the user wants to switch between CISO, Product Leader, and Custom modes, run the appropriate branch of SETUP Step 2 and rebuild the source suite. Carry over any manually-added sources the user wants to keep.
After any meaningful config change (new sector, new sources, switched mode, changed company), ask: "How far back should the next brief look? Default is 1 day — or tell me a different window for this run." This catches the case where a config change means the user wants a fresh sweep to see how the new sources perform. Do not ask after minor changes (typo fixes, timezone updates).
The default source suite for CISO mode. Load all of these unless the user explicitly excludes one.
These are primary sources of truth. Treat their content as high-confidence. Never remove from the brief without user confirmation.
| Source | Search target | What it contributes |
|---|---|---|
| CISA Alerts & Advisories | site:cisa.gov advisories | Active exploits, critical advisories, joint alerts with NSA/FBI |
| CISA Known Exploited Vulnerabilities (KEV) | site:cisa.gov known-exploited-vulnerabilities | CVEs with confirmed in-the-wild exploitation |
| NVD / CVE Database | site:nvd.nist.gov OR "CVE-2026" new vulnerability | New and updated CVE records, CVSS scores |
| MITRE ATT&CK | site:attack.mitre.org | TTP context for attributed campaigns; use for tagging items from other sources |
| FBI Cyber Division | site:ic3.gov OR site:fbi.gov/investigate/cyber | Public PSAs, threat actor attributions, financial fraud patterns |
| NSA Cybersecurity Advisories | site:nsa.gov cybersecurity advisory | Nation-state TTP guidance, hardening recommendations |
High-quality, vetted research with named analysts and editorial review. Include all by default.
| Source | Search target | What it contributes |
|---|---|---|
| CrowdStrike Intelligence Blog | site:crowdstrike.com/blog | Adversary tracking (BEAR/SPIDER/KITTEN taxonomy), campaign analysis |
| Palo Alto Unit 42 | site:unit42.paloaltonetworks.com | Threat research, malware reverse engineering, IR findings |
| Red Canary | site:redcanary.com/blog | Behavioral detection research, open-source detection rules |
| Google Mandiant | "mandiant" threat intelligence blog | APT group tracking, IR case studies, zero-day attribution |
| Microsoft Threat Intelligence (MSTIC) | site:microsoft.com/security/blog | Windows/Azure/cloud threat actor TTPs, nation-state activity |
| Cisco Talos | site:blog.talosintelligence.com | Threat telemetry, malware family analysis, email threat data |
| Secureworks CTU | site:secureworks.com/blog | GOLD/IRON/BRONZE group tracking, ransomware intelligence |
| Recorded Future | site:recordedfuture.com/blog | Dark web intelligence, global threat signals, public research |
Reliable reporting with editorial standards. Label items [NEWS]. Include all by default.
| Source | Search target | What it contributes |
|---|---|---|
| Krebs on Security | site:krebsonsecurity.com | Investigative security reporting, breach coverage |
| The Hacker News | site:thehackernews.com | Breaking security news, vulnerability coverage |
| Dark Reading | site:darkreading.com | CISO-relevant analysis, industry reporting |
| SecurityWeek | site:securityweek.com | Vendor news, vulnerability roundups |
| BleepingComputer | site:bleepingcomputer.com | Ransomware tracking, active exploit news |
| Ars Technica Security | site:arstechnica.com/security | Technical security reporting, long-form analysis |
For tracking M&A, funding, product launches, regulatory moves. Label items [VENDOR] or [REGULATORY]. Read with commercial interest context.
| Source | Search target | What it contributes |
|---|---|---|
| CRN | site:crn.com security | Channel news, vendor M&A, partner moves |
| SC Magazine | site:scmagazine.com | Security product news, market coverage |
| TechCrunch Security | site:techcrunch.com/category/security | Startup funding, cybersecurity acquisitions |
| Cybersecurity Ventures | site:cybersecurityventures.com | Market reports, spending forecasts |
Default source suite for Product Leader mode. Core sources load for all users; vertical-specific sources added at SETUP.
| Source | Search target | What it contributes |
|---|---|---|
| SEC EDGAR | site:sec.gov [company] OR [competitor] | Public filings, 8-K events, earnings, exec changes |
| Crunchbase News | site:crunchbase.com [sector] funding OR acquisition | Funding rounds, M&A, investor signals |
| Company newsroom | site:[company].com/news OR /press | Official announcements, product launches, leadership moves |
| Competitor newsrooms | site:[competitor].com/news OR /press | Official competitor announcements |
| Source | Search target | What it contributes |
|---|---|---|
| a16z | site:a16z.com [sector] OR [vertical] | Market theses, sector deep-dives, portfolio signals |
| Sequoia Capital | site:sequoiacap.com [sector] | Market memos, economic outlook, founder research |
| The Information | site:theinformation.com [company] OR [sector] | Investigative tech journalism (search for public excerpts) |
| Stratechery | site:stratechery.com [company] OR [sector] | Strategic analysis of tech business models |
| Benedict Evans | site:ben-evans.com [sector] OR [topic] | Consumer tech and market structure analysis |
| CB Insights | site:cbinsights.com [sector] intelligence | Market maps, funding data, industry reports |
| Gartner | site:gartner.com [sector] magic quadrant OR report | Analyst positioning, market category definitions |
| Forrester | site:forrester.com [sector] wave OR report | Enterprise buyer-focused analyst coverage |
| Product Hunt | site:producthunt.com [category] | New product launches, early competitor signal |
Label items [NEWS] or [COMMUNITY].
| Source | Search target | What it contributes |
|---|---|---|
| TechCrunch | site:techcrunch.com [company] OR [sector] | Funding news, product launches, startup coverage |
| The Verge | site:theverge.com [company] OR [product category] | Consumer tech, platform policy, product reviews |
| Wired | site:wired.com [company] OR [sector] | Long-form technology and business reporting |
| Fast Company | site:fastcompany.com [company] OR innovation | Innovation, design, product culture |
| Reuters / Bloomberg | site:reuters.com OR site:bloomberg.com [company] OR [sector] | Breaking M&A (Tier 1); market color (Tier 3) |
| Lenny's Newsletter | site:lennysnewsletter.com [topic] | Practitioner PM and growth content |
| Reforge Blog | site:reforge.com/blog [topic] | Product growth and retention frameworks |
| Hacker News | site:news.ycombinator.com [company] OR [product] | Developer community signal; earliest mention of product issues |
[person] OR [company] site:linkedin.com | Exec commentary, people moves, product announcements |
| Source | Search target | What it contributes |
|---|---|---|
| G2 | site:g2.com [company] OR [competitor] reviews | Customer review signal, competitive grids |
| Capterra | site:capterra.com [company] OR [competitor] | B2B buyer reviews, alternative discovery |
| Trustpilot | site:trustpilot.com [company] OR [competitor] | Consumer review signal |
| Vendor blogs | site:[vendor].com/blog [product area] | AI vendor product updates, API changes |
| Source | Search target | What it contributes |
|---|---|---|
| OpenAI Blog | site:openai.com/blog | Model releases, API changes, pricing |
| Anthropic | site:anthropic.com/news OR /research | Model releases, safety research, API updates |
| Google DeepMind | site:deepmind.google OR site:blog.google/technology/ai | Research, Gemini updates, infrastructure |
| Meta AI | site:ai.meta.com/blog OR site:research.facebook.com | Open-source models (Llama), research |
| Mistral AI | site:mistral.ai/news | European frontier model moves, open-weight releases |
| Hugging Face | site:huggingface.co/blog | Open-source model ecosystem, tooling |
| arXiv cs.AI | site:arxiv.org cs.AI [topic] | Pre-print research; leading indicator of capability direction |
Additional AI vendor sources from ai_vendors: in WARMUP.md appended at runtime.
| Vertical | Add These Sources |
|---|---|
| Security product | Full CISO Tier 1–2 suite (CISA, NVD, CrowdStrike, Unit 42, MSTIC, Red Canary, etc.) |
| Fintech / payments | OCC (site:occ.gov), CFPB (site:consumerfinance.gov), FS-ISAC, Payments Dive, PYMNTS |
| Healthcare / digital health | FDA Digital Health, CMS (site:cms.gov), Rock Health, HIMSS |
| Consumer social / creator | Social Media Today, Creator Economy Report, platform dev blogs (Meta, TikTok, YouTube, Snap) |
| Enterprise SaaS | Bessemer State of Cloud, SaaStr, ChartMogul blog, Lighter Capital |
| Developer tools / platform | GitHub Blog, Stack Overflow Developer Survey, npm trends, CNCF reports, Changelog |
| E-commerce / retail | Digital Commerce 360, Shopify Engineering Blog, NRF research, Morning Brew Retail |
| Logistics / supply chain | FreightWaves, Supply Chain Dive, Flexport blog |
| Marketplace | a16z marketplace posts, NFX (site:nfx.com), a16z marketplace essays |
Append these when the user's sector matches. Add to the appropriate tier in the source suite.
| Sector | Add These Sources |
|---|---|
| Healthcare | HHS HC3 (site:hhs.gov hc3), Health-ISAC news (site:h-isac.org), AHA cybersecurity alerts |
| Financial Services | FS-ISAC public blog (site:fsisac.com), OCC alerts (site:occ.gov), FFIEC guidance |
| Energy / Utilities | E-ISAC (site:eisac.com), CISA ICS-CERT (site:cisa.gov ics-cert), NERC CIP updates |
| Government / Public Sector | FedRAMP news, FISMA updates, DoD CMMC bulletins (site:dodcio.defense.gov) |
| Technology | GitHub Security Advisories (site:github.com/advisories), Wiz Research (site:wiz.io/blog), Snyk Vulnerability DB |
| Retail / Consumer | PCI Security Council (site:pcisecuritystandards.org), NRF security news |
| Manufacturing / OT | Dragos OT Intel (site:dragos.com/blog), Claroty Research (site:claroty.com/team82), Nozomi Research |
| Critical Infrastructure | Extends Energy + Government sources; add ICS-CERT advisories explicitly |
Organize the brief into these five sections, in this order. Each section has a defined scope. Stay within it.
What belongs here: Named threat actors currently active; their targeted sectors; their primary TTPs.
(SCATTERED SPIDER, COZY BEAR, VOLT TYPHOON, etc.). Note aliases when relevant (e.g., "APT29 / COZY BEAR").
(e.g., T1566.001 — Spearphishing Attachment), and source.
sector. If no sector-specific activity exists this week, say so briefly rather than forcing items that do not fit.
or its sector has appeared in attribution reporting.
Scope boundary: Attribution and TTPs only. Do not put CVEs here — those go in Emerging Threats. Do not put vendor news here — that goes in Industry Intel.
What belongs here: New vulnerabilities and attack techniques entering circulation in the last 7 days.
catalog this week.
status (exploited in wild / POC available / no exploitation evidence).
confirmed in-the-wild exploitation ranks above a CVSS 9.8 with no POC.
Scope boundary: Technical vulnerabilities and new attack techniques only.
What belongs here: New publications from Tier 1 and Tier 2 sources in the last 7 days.
named threat data, indicators, or detection guidance qualifies.
Scope boundary: Research publications only, not breaking news. If something is both news and research (e.g., a major IR firm publishes on an ongoing incident), put it here and note the news angle.
What belongs here: Market and vendor movement a CISO cares about for budget and vendor portfolio decisions.
actions, CMMC updates, state-level privacy laws.
note that explicitly.
Scope boundary: Market and regulatory movement. Not technical threat data.
What belongs here: High-signal community discussion from the security field. This section is optional and should be omitted if nothing substantive is found.
or X/Twitter security accounts that discuss something of professional consequence (a significant debate, a disclosed incident, a tool release that is getting traction).
"Unverified community signal. Cross-reference Tier 1–2 sources before acting."
Do not pad with low-signal posts to fill the section. Absence is better than noise.
Eight sections, in this order. Section 7 (Vertical Intel) is dynamic — its name and scope adapt to the user's declared vertical. Section 8 (Special Interests) is optional and omitted if not configured.
What belongs here: Your own company's external signal — what the market, analysts, customers, and press are saying about you.
category ranking changes
(e.g., suddenly posting 20 ML roles signals an AI pivot)
Scope boundary: Only your own company. Competitor company signal goes in Section 2. Industry news goes in Section 7.
What belongs here: Strategic moves from the competitor list in WARMUP.md.
[PRICING], or [CUSTOMER]
item and put it first in the section.
Scope boundary: Named competitors only. New entrants or emerging threats go in Section 7 (Vertical Intel). Do not include your own company here.
What belongs here: Two tracks in one section.
Track A — Frontier model and AI vendor moves:
Track B — AI in product development:
Ordering: Put Track A items first (they move the floor). Track B items follow.
Scope boundary: AI capabilities, vendors, and tooling only. Do not put general tech news here. Do not duplicate competitor AI launches — those go in Section 2.
What belongs here: Capital and consolidation moves in the user's market.
late-stage. Note the lead investor — signals where smart money is pointing.
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.