Made to stick — work-ledger SUCCESs pass
Scope of this doc. BUILD THIN is decided (00-SYNTHESIS.md, plan 001; 01-initial-recommendation.md; the five research digests folded into this plan’s context). This doc does not re-argue build-vs-buy. Its only job: will the two humans and the agent fleet actually use what gets built, consistently, without babysitting? That is a stickiness problem (Heath & Heath’s SUCCESs frame — Simple, Unexpected, Concrete, Credible, Emotional, Stories), not a decision problem.
The market, precisely. Not a market in any commercial sense — confirmed by the competitive digest: no product category exists to sell into. Three audiences, all internal:
| Audience | Size | State | What “sticks” means for them |
|---|---|---|---|
| Robert (operator) | 1 | Already convinced — he wrote 01-initial-recommendation.md |
N/A — not a persuasion target |
| Tomas (stakeholder) | 1 | Unconvinced, decision-bound, reviews nothing by default | The A1 ask (§4) lands without becoming a negotiation |
| Agent fleet (10→64, growing) | hundreds of sessions/week | Reads a system prompt once per session, obeys or doesn’t | The CLAUDE.md paragraph (§7) is followed under load, not just understood |
The agent-fleet row is the one classic “made to stick” treatments don’t cover: the pitch isn’t remembered by a person days later, it’s re-read fresh every session and must produce correct behavior on the first pass, every time, at 64x concurrency. That reframes “sticky” as “compiles to correct behavior,” not “memorable.”
1. Simple
One-sentence essence: work-ledger is the one place a rebuild unit’s owner, state, cost, and fate are always knowable — so no unit of work is ever ambiguous.
Commander’s intent (the sentence that must survive if everything else in this plan is forgotten): Every agent, every hour: what is claimed, by whom, in what state, at what cost, headed toward what disposition — answerable from one query, always. If a future engineer strips work-ledger down to a single invariant to preserve across any redesign, it’s this one, not the schema, not the endpoint names, not Encore.
Everything else in the plan — the enum-constrained state machine, the SKIP LOCKED claim, the disposition taxonomy — is implementation detail in service of that one sentence.
2. Unexpected
Tomas’s prior, reasonably: a new internal system means a new thing to review, approve, and maintain — the shape every other Groupon-internal tool has taken. Symphony-style tools and Zaruba’s own core-plane proposal flow both train this expectation (competitive digest; repoRecon §1).
What work-ledger breaks: it asks him for nothing on an ongoing basis.
- Zero core-plane PRs in v1 — confirmed structurally by the architect addendum: work-ledger lives entirely in the internal plane, projects from the internal-plane workflow-execution stream (not Core), and reuses
tasks’ existing free-textassigneeGroupSlugfor blocking questions with zero schema change (repoRecon §2). The one earlier plan-001 draft that proposed a negotiatedTaskTypePR was demoted to optional v2 by the same addendum. - Zero meetings. Zero recurring review load. Zero dashboard he has to build or maintain.
- Evidence shows up unprompted, exactly when he needs it: at M4/M8/M12, the disposition table is already populated, already linked to parity evidence, already correct — because agents were structurally required to fill it in as a side effect of doing the work, not asked to report on it afterward.
The single genuine ask — the CODEOWNERS-partitioned lane (A1) — is a one-time boundary agreement, not a workflow he joins. That’s the surprise worth leading with: this is the rare internal tool that reduces, not adds to, what a stakeholder has to do.
3. Concrete
Abstractions (“atomic claim,” “one-way projection”) don’t survive a 30-second conversation. Two artifacts do the work instead.
Demo 1 — the race. Two terminal windows, side by side. Both run claim(orders.refund_calculation) within milliseconds of each other. One returns the full unit state and an owner. The other returns a rejection naming the current owner — not a crash, not a silent double-assignment, a named, structural refusal. This is literally TDD step 1 from 00-SYNTHESIS.md (“vitest integration test: claim-unit is atomic under 2 concurrent claimers, Docker PG, advisory lock”) run live instead of asserted in a slide. Buildable in a day per the “fastest prototype” section of 01-initial-recommendation.md — the demo and the first production artifact are the same code.
Demo 2 — the kill-gate table. One SQL query (or the equivalent Grafana panel), run in front of Tomas at M4: unit_id, disposition, evidence_url, cost_cents, disposed_at, filtered to disposition IS NOT NULL, sorted by disposed_at. Every MIGRATED/DROPPED/DEFERRED/DEAD row has a link he can click straight to the parity evidence. This is the actual artifact he reads — not a pitch deck about the artifact.
Both demos are cheap, both are literal (not simulated), and both are things Tomas can drive himself in under a minute — the strongest form of concrete a technical stakeholder gets.
4. Credible
Two mechanisms, and one honest gap in each.
Mechanism 1 — weekly reconciliation audit, published openly. Pre-mortem #3 in 00-SYNTHESIS.md names the real failure mode: ledger and execution truth disagree, first disagreement during an incident kills trust in both. The response is a standing query, not a promise: work-ledger’s disposition/cost rows compared against Zaruba’s existing workflow_executions projection table (repoRecon §3 — already built, already Postgres, already the thing Tomas’s own interceptor keeps in sync) — not against raw Temporal visibility, which self-hosted retention purges at 72h (temporalCase digest, B1). Anchoring the audit on the Postgres projection instead of the Temporal API is what makes “weekly” survivable at all; anchoring it on Temporal directly would have the audit racing a 3-day purge clock and losing.
Gap, stated plainly: this only covers units that actually run as internal-plane Temporal workflows. Per repoRecon, exactly one toy example workflow exists today — zero real fleet units run this way yet. For v1’s real unit of work (external Claude CLI sessions via the external-claim endpoint), there is no independent execution-truth source to reconcile against; the ledger is the record, self-reported. The reconciliation-audit credibility story is real but currently covers ~0% of live traffic. Flagged in §9.
Mechanism 2 — TDD-first invariant tests. Atomic claim and exactly-once transition aren’t asserted in a README, they’re proven by a failing-test-first build (00-SYNTHESIS.md §“First implementation steps”). Gap, stated plainly: repoRecon corrects the plan-001 claim that this follows an existing “house vitest+Docker-PG pattern” — no such pattern exists anywhere in the repo today; every service-layer test mocks its repository, and real DB-level testing is a manual pnpm backend:core exercise (repoRecon §5). The invariant tests are genuinely new infrastructure, not an inherited convention. Say that to Tomas directly rather than implying reuse that isn’t there — a stakeholder who later greps the repo and finds no precedent is a bigger credibility loss than admitting it up front.
Third-party corroboration worth citing verbatim in the pitch, because it’s external and dated: a June-2026 arXiv preprint (2606.19616, cited in the prior-art digest) found that lock-only claim queues reproduce the highest rate of redundant agent work of any tested condition, and that git-native file trackers silently drop concurrent field writes. That’s the argument, from outside this codebase, for why work-ledger is a durable disposition table plus a claim guard — not just a lock. Independently, beads (the claim-layer candidate research/12 §1.2 left open) had its own Postgres backend built and rolled back two days before this research pass (2026-07-16, oss digest) — evidence the “just adopt an existing claim tool” path is less settled than it looks, not evidence against building.
5. Emotional
The fear story is already sitting in this codebase, not hypothetical: two half-finished strangler migrations, rotting in code, right now [E6]. VIS3 still calls legacy VIS. The identity-service migration was abandoned in 2022 and nobody closed it out — it just stopped, silently, and stayed stopped for four years with no record of why.
That happened at ordinary, single-team, human-paced development speed. work-ledger exists because the fleet this plan is built for runs at 10→64 concurrent agents, with a queue that reaches 1000 units. At that speed, “a migration quietly stops and nobody notices for years” doesn’t take four years — it can happen inside a single sprint, across dozens of units, before any human would trip over it in production.
The line to lead the pitch with, because it’s the whole emotional case in one sentence: never again does a migration die in silence. Every unit either has a disposition with evidence, or it is visibly, queryably still open. There is no third state where it’s just quietly forgotten.
6. Stories
Before/after: one Orders unit, orders.refund_calculation.
Before work-ledger (the world VIS3 and identity-service came from): an agent starts refactoring the refund-calculation path. No record that it started. A second agent, working the same backlog, starts the identical unit an hour later — nobody notices until the two PRs collide. The first agent hits a hard edge case, opens a question in Slack, gets no answer for three weeks, and quietly moves on to something else. Six months later nobody can say whether refund-calculation was migrated, abandoned, or still pending — the only record is scattered git history and someone’s memory.
After:
- Agent A calls
claim(orders.refund_calculation)— atomic, succeeds, returns the unit’s full state (attempt #1, owner = agent A, claimed_at = now). - Agent B, working the same queue, calls
claim()on the same unit ninety seconds later — rejected, told who owns it. No collision, no wasted tokens, no merge fight. - Agent A hits an edge case it can’t resolve alone, calls
block(unit, question). The question lands in the existingtasks“agent-questions” queue — no new schema, no new PR (§2). Unit state:blocked, visible to Robert’s queue-depth panel immediately, not three weeks later. - Answer comes back, agent A (or a new claim by whichever agent picks it up next) resumes, runs the dual-run harness against legacy
VIS, reaches parity, callstransition(unit, verified, evidence=<harness diff report URL>). - Disposition set:
MIGRATED, cost total $3.20 across 2 attempts, evidence link attached, disposed_at stamped. - At the M4 kill gate, Tomas runs the one query from Demo 2 (§3).
orders.refund_calculationis already there — disposition, cost, evidence, no one asked for it, no one had to write it up.
That’s the whole pitch compressed into one unit’s lifecycle: claim prevents the collision, block prevents the silent drop, disposition prevents the six-months-later ambiguity.
7. Produced artifacts
One-sentence description. work-ledger is the durable record of what happened to every unit of Groupon’s legacy-rebuild work — who claimed it, what it cost, and how it ended — so that no unit is ever double-worked, silently dropped, or unaccounted for at a kill gate.
The CLAUDE.md paragraph for agents (the actual enforcement mechanism — see the flag in §9):
Before starting any rebuild unit, claim it via work-ledger’s
claim(unit)— never begin work on a unit you have not atomically claimed; a rejected claim means another agent owns it, stop and pick a different unit. Report every state change throughtransition(unit, state, evidence?)and every blocker throughblock(unit, question)— work-ledger’s state, not your own memory of what you did, is the source of truth for what is claimed, in progress, blocked, or closed. A unit is only finished when it carries a disposition — MIGRATED, DROPPED, DEFERRED, or DEAD — with an evidence link. Never write to a unit you do not currently hold the claim on.
The 30-second Tomas pitch (~85 words, spoken):
Right now two half-finished migrations are rotting in the codebase because nobody’s tracking what’s actually claimed, in progress, or abandoned — that gets worse, fast, once dozens of agents are working the backlog at once. work-ledger is a Postgres table my fleet writes to as a side effect of doing the work: who’s got a unit, what it cost, how it ended. It costs you nothing ongoing — zero PRs, zero meetings, it lives entirely in the internal plane. What you get: at every kill gate, one query shows exactly what’s migrated, dropped, deferred, or dead, with evidence, already there.
The A1 ask, framed precisely (per 00-SYNTHESIS.md assumption A1 and the architect addendum): a CODEOWNERS-partitioned lane inside monorepo-development’s internal plane, opened with an OWNERSHIP.md file and a directory convention — not a CODEOWNERS enforcement mechanism on day one (that comes later, on his schedule). This is a one-time boundary agreement, explicitly not a standing review commitment: work-ledger’s own endpoints, schema, and code changes never route through his review queue once the lane exists. If A1 doesn’t land within two weeks of the ask, the named fallback is A-lite (Robert-owned repo, API-only integration) — same product, different address, so the ask carries no real leverage risk for Tomas to worry about granting it.
Before/after story: §6 above.
Credibility mechanism: §4 above (weekly reconciliation vs the workflow_executions projection; TDD-first invariant tests) — including both stated gaps, which belong in the actual pitch, not just this doc.
Homepage headline/subheadline: N/A — internal; no homepage exists or should exist (Rams/Norman framing in 01-initial-recommendation.md — the API is the UX, Grafana is the read surface).
8. Flags — still abstract or unbelievable
- The reconciliation-audit credibility story covers ~0% of live traffic today. It’s sound for Temporal-workflow-modelled units, but per repoRecon exactly one toy workflow exists in the whole repo — real fleet units in v1 are external Claude sessions with no independent execution-truth source at all. Don’t let the pitch imply broader coverage than it has; revisit this line the moment real units start running as internal-plane workflows.
- “Follows the house TDD pattern” is not currently true and shouldn’t be claimed as such — repoRecon found no Docker-PG vitest precedent anywhere in the repo; work-ledger’s atomic-claim test is new infrastructure. Fine to build, not fine to market as “just following convention” if a skeptical reader can grep and find nothing.
- The CLAUDE.md paragraph (§7) is the single highest-leverage and highest-risk artifact in this entire plan. Unlike a human pitch, there’s no second chance to clarify if an agent misreads it under load — a badly worded claim/transition instruction at 64x concurrency produces the exact collision-and-silent-drop failure mode work-ledger exists to prevent. It needs to be tested against real agent behavior (does a fresh session actually call
claim()before editing, every time?), not just read for clarity. That test doesn’t exist yet — recommend it as an explicit acceptance criterion in12-prd.md, not left implicit here. - “Zero PRs” is true for work-ledger specifically but not for the sibling triage service — the temporalCase digest (B4) found no exposed endpoint exists yet for creating an
INFORMATION_REQUESTtask from outside Core, and the cross-plane signal bridge Robert’s fleet would need doesn’t exist either. Keep the A1 pitch scoped to work-ledger; don’t let “zero PRs” bleed into a promise the triage app can’t yet keep. - The demo’s two terminal windows only prove claim-atomicity, not the harder, currently-unbuilt invariant (exactly-once transition from a real projected event stream) — because, per repoRecon, there is no real event stream to project from yet. Demo 1 is honest and buildable today; a second demo for projection correctness is a v2 artifact, not a v1 one — don’t imply it’s ready.