The chip factory and slot vocabulary, the evergreen docs chips, the per-page slot
table and the signal chips each get their own module; registry.ts is now the
public face that re-exports them. A pure move.
dashboardAgentWatchChecks.ts keeps the dispatcher, the failure envelope and the
previous-facts reader, and re-exports the run, queue, error and health families
plus the shared reader contract. A pure move; every import path is unchanged.
The gallery pages, their fixtures and the screenshot script only exist to
look at the agent UI, so they ship separately. The fixtures two unit tests
read — the report view models and the page contexts — stay here.
Head start passed `system` as a bare string, so Anthropic neither wrote nor read
the cache: the ~18.4k-token prefix was billed in full and the agent's step 2 then
paid for a fresh write. Both breakpoints now carry a 1-hour TTL.
The two prefixes were also not identical — `get_run` sat in a different position in
the agent's tool set than in the canonical schema-only one, so they could never have
shared a cache. Reordered, and a fingerprint over system text + tool definitions is
logged per model call alongside the provider's cache-write, cache-read and uncached
input token counts, so a future drift is visible instead of silent.
Landmarks derived from the layout spec must appear in the same order in the server-rendered card
and in the markdown, over healthy, degraded, untrustworthy and empty reports.
The card no longer formats values, resolves codes or classifies footer codes of its own, and a
genuinely-unknown state now gets a neutral icon instead of a green tick.
The text surfaces gain the card's structure (headline, hero evidence, why: block, aggregated
read:, trust flag) and keep their alignment: fixed sparkline column, aligned notes.
Section order, section labels, the tone -> glyph vocabulary, the footer styles and every
string a renderer places now live in report-layout.ts. Renderers decide typography only.
/api/v1/query took its tenant scope from the request body, so a public access
token minted for one environment could read the whole organization by asking for
organization scope. The credential is now the ceiling and a wider ask is refused;
secret keys and the membership-authorized Query page are unchanged.
A turn that ends in an error was only a stream event, so reloading history showed
a turn that just stops. It is now appended to the transcript through the same
id-deduped path a wake uses, in the same wording the live stream shows, and the
panel drops its live callout once that record is the last message.
Every watch sentence (card, banner, toast, email, Slack, webhook) now comes from
app/presenters/v3/dashboardAgent. The condition is written once per kind in four
registers instead of in four switches across three files, and a plain-text block
renderer lets the non-React surfaces say what the card says.