The WATCH face — a read-only compounding-return ledger over the board snapshot + the tenant git trail
0069-watch-activity-compounding-ledger
- Reversibility
- two-way door
DEC-0069 — The WATCH face: a read-only compounding-return ledger
Reversibility: two-way door. The ledger derives entirely from existing real state (board atoms + the tenant's own git history); the read function, the route, and the digest shape can all change without migration. Nothing about the loop, the disposition seam, or the system of record depends on this surface.
The operator dashboard (Build DEC-0064 Option D into running code — the v0 agency governance dashboard is a non-prerendered `(operator)` route group that reuses dispose.ts, gated behind DOSSIER_OPERATOR) built approve / ship — the review queue a human disposes. DEC-0052's triad is approve / ship / watch, and the v0 spec (Spec the v0 agency dashboard surface (Phase 0 dogfood — Dossier's own .claude/agents team on Dossier's own OKF; daily-standup / approve-ship loop) line 49) carried the watch / daily-report digest forward as the next slice: "what it did, and what it wants to do next" + the compounding return "made visible … a git diff in the org's own history" (The compounding merge — the per-tenant learning loop accumulates by id + confidence instead of overwriting (okf reconcile() + opt-in reconcile in extraction/runtime)). This is that surface, built v0.
Decision
Ship a new read-only operator-scoped surface at (operator)/activity (/activity) — the watch face — that narrates the loop's compounding return over time for a tenant. It has no mutation: disposition stays on the dashboard (Invariant 3 / Governed disposition lives with the operator control plane (CLI now, local dashboard optional, deployed siloed service deferred) — the public `/board` deploy stays read-only and holds no mutation authority).
The signal comes from two real sources, joined and counted by one new runtime read — readActivityLedger in @dossier/runtime (the SSOT for board/runtime reads; the app consumes it, never re-derives it):
- The board snapshot — every
taskatom's currentstatusplus the disposition/claim provenance the loop + the human stamp: theapproved-by:/approved-on:tags from the disposition (Governed disposition lives with the operator control plane (CLI now, local dashboard optional, deployed siloed service deferred) — the public `/board` deploy stays read-only and holds no mutation authority /dispose.ts), andclaimed_by/assignee. Read through the same confinedloadTasksthe board and the disposition use. - The tenant git trail — the commits the loop and the human disposition wrote into the tenant's own repo (Adopt OKF as Dossier's canonical knowledge format system of record):
dossier(board): approve … → done — compounded by …,reject … → backlog, transitions, claims. Parsed via a read-onlygit logmatching only the stabledossier(board):prefix the runtime itself writes — a hand commit is ignored, so the narrative can never drift from what the runtime actually did.
The digest counts are derived purely from those two sources (compounded / awaiting-review / in-flight / backlog / blocked; approve & reject events; first/last activity). No number is invented — a non-derivable figure (e.g. firstActivity on a git-less or empty-history tenant) is null/absent, never fabricated.
Rationale
- SSOT, reuse-don't-fork. The watch surface needed a read, not a new mechanism. Putting it in
@dossier/runtime(next tolistReviewQueue/dispose) keeps board/runtime reads in one place; the app's$lib/server/operator.loadActivityLedgeris a thin bridge, so the browser and the CLI/runtime can never drift. The disposition provenance it reads (approved-by:tags, thedossier(board):commit prose) is the SAME provenance the disposition writes — parsing those exact formats binds the narrative to the truth. - Provenance / Invariant 3 made visible. The ledger distinguishes human disposition (a named
compounded by <by>approve/reject) from agent acts (claims/transitions), so the human-in-the-loop governance is legible — you can see that only a human reacheddone. - Compounding return = git. The "made visible" the spec asks for is literally the tenant's own git history (The compounding merge — the per-tenant learning loop accumulates by id + confidence instead of overwriting (okf reconcile() + opt-in reconcile in extraction/runtime) / Adopt OKF as Dossier's canonical knowledge format); reading it is the honest way to show the return — git-owned, portable, and the same record the disposition compounds into.
- Read-only by construction. Watch holds no mutation authority; it renders even when the mutating dashboard is gated off (
DOSSIER_OPERATORunset). The (operator) group'sprerender = false+ nothing-prerendered-links-here keeps it off the public read-only/boarddeploy (Governed disposition lives with the operator control plane (CLI now, local dashboard optional, deployed siloed service deferred) — the public `/board` deploy stays read-only and holds no mutation authority / Build DEC-0064 Option D into running code — the v0 agency governance dashboard is a non-prerendered `(operator)` route group that reuses dispose.ts, gated behind DOSSIER_OPERATOR).
Consequences
- New runtime read
readActivityLedger(+parseCommit,deriveDigest, types) exported from@dossier/runtime; offline integration-tested against a real sandbox git repo (packages/runtime/test/activity.test.ts). - New route
(operator)/activity(+page.server.tsload ++page.svelte), bridged byloadActivityLedgerin$lib/server/operator.ts; offline route test (packages/app/test/operator-activity.test.ts). The dashboard ↔ activity cross-link both ways (one surface family). - NOT in scope (carried forward): the per-team/per-action autonomy dial (DEC-0052; explicitly a LATER slice). The watch surface is the readout, not the control.
Review
Verified at build: the runtime read + the route load are proven offline (a disposed task appears in the ledger as both a done task with approved-by provenance and an approve git event; digest counts derive from real state), and the surface was demonstrated live against the RBA dogfood tenant (clients/rba/tenants, rba-consulting) — see the session report + screenshot. The verified confidence scopes the watch READ + surface only; it does not promote any carried-forward DEC-0052 face. If the surface ever shows a number it can't derive, that is a defect against this DEC's non-fabrication rule.