ZION-19 — Finish the business Hub

The actual documents the agents read and work from, shown exactly as they are on disk — not a summary. See the progress view instead · All projects

Plan PLAN-ZION-19-hub-finish.md

# PLAN-ZION-19 — FINISH THE BUSINESS HUB

**Owner:** ZION-19 drive session (Fable overseer) · **Overseer:** Fable, one thread (Nick, 2026-09-04: "the new plans will deploy fable agents as overseers for build work and deisng QA") · **Design authority:** Sienna (creative-director), UI only
**Rule: no step begins until the previous step's PROOF has been produced and closed by its checker. A step with an unproven predecessor is a violation, not a shortcut — except where a step's own Enter line names a different, satisfied dependency.**

> **NORTH STAR:** The Hub is FINISHED: Nick, Chantelle, Rizza, Mae, Dean and Dindin each sign in with Google on the live site and run their real work — boards, tasks, payroll, clients, workload — with every committed fix actually deployed and proven on the screens they use, and the board-enforcement gate live behind them. (Nick, 2026-09-04: "The only thing I want to do is finish the hub and finish Skippy in the voice app. That's all I care about." · "pm noard enforcement gets wrapped in tot he hub work" · "finish voice app then we deploy the same etup in the hub and family app")
>
> **FINISH LINE — written now, the bar never rises mid-drive:**
> 1. Google sign-in is ON in the live Hub; all six identities reach their role home through it in a real browser; view-as intact; the nightly check that exercised the old password login is fixed in the same change and green.
> 2. Live production serves current HEAD: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 4` exits 0.
> 3. Every committed-but-undeployed product fix in the STEP-2 ledger is verified working on the live site through the real user path, and each one that lacked an automated test has a red-first test.
> 4. The six REOPENED ZION-3 steps (1, 4, 9, 14, 19, 25) are re-closed on their own existing harness proofs, and the no-arg suite `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs` exits 0.
> 5. ZION-17's nine round-12 findings are fixed with ONE clean check round; ZION lanes can open real board cards — **proven by actually opening one on the live board**, not by reading the code (the vocabulary was measured present on disk and accepted in production on 2026-09-04, so this item is a verification, not a code change); this plan's §5 carries a real card id.
> 6. The voice setup proven in the Skippy voice app is deployed in the Hub from that lane's handed-off pattern — consumed, never re-designed.
> 7. The agent-facing Hub infrastructure guide exists, carries the measured card-creation recipe with its three traps, and says plainly which parts of the board machinery are Monday-derived and will change (Nick, 2026-09-04: "we should have an agent write a how to guide for other agents as a part of the hub work- FAQs and SOPs for the hub infra").
> 8. The postmortem is written into this file.
>
> When these eight pass, this plan is DONE and everyone stops. Anything found after that goes on one line in the **NEXT list** at the bottom and is NOT worked (§G: done means GREAT, not perfect).

### STEP 0 — ARM THE LOOP, BEFORE ANYTHING ELSE.
Set a 5-minute loop. Every time it fires, answer these four in order and CORRECT any failure before doing anything else:
1. **NORTH STAR** — is what I am doing this minute moving this plan's North Star? If not, drop it and take the highest-value unblocked step that does.
2. **FAN-OUT** — is my queue full up to the concurrency cap (§T)? Full capacity means the cap is reached and a queue of ready work sits behind it — NEVER "launch everything at once". Below the cap with ready work → dispatch now. At the cap → queue, don't launch.
3. **CHEAP** — are cheap models doing the building? If anything expensive is building, move that work down now.
4. **BLOCKED** — for anything I have called blocked: name the three concrete things I tried. If I cannot, it is not blocked — drive through it now.
Then keep building. The loop never stops until the FINISH LINE is proven.

## Already true (the distilled past — facts, not story)

- The Hub app lives at `projects/business/business-app/` and is its OWN git repository — evidence: `git -C "projects/business/business-app" rev-parse --show-toplevel` printed that path, measured 2026-09-04. 🔴 Every commit instruction in this plan says which repo it lands in; a session in the wrong directory commits into the wrong repo (§W).
- The Hub repo's `main` is ahead 4 / behind 11 against `origin/main` — evidence: `git -C projects/business/business-app branch -vv`, measured 2026-09-04. The 4 unpushed local commits: `69a0b9c0`, `51388a51`, `4f7da632`, `c2318c32`. The 11 remote-only commits are the HSDB Phase-3 PRs (#153–159).
- Live production has drifted at least 29 commits behind local HEAD with no redeploy — evidence: ZION-3 STEP 4 REOPENED record, two independent regroup verifiers, `LIVE_SOURCE_REVISION_STALE`; re-measured fresh by STEP 1 of this plan before anything acts on it.
- Google sign-in is BUILT and browser-tested in the Hub but not switched on — evidence: `projects/business/business-app/app/functions/api/auth/google/start.js` and `callback.js` on disk, and `projects/ops/google-sso/STATE.md` (corrected 2026-09-04). The old password login is removed in the built code; switching on requires fixing one nightly check that still exercises the old password login, in the same change.
- Rizza's `finance@heroesandsidekicks.io` mapping is settled — evidence: Nick, 2026-09-04, "finance email is rizza" (it is hers alone), recorded in `projects/ops/google-sso/STATE.md`.
- Six ZION-3 steps are REOPENED (1, 4, 9, 14, 19, 25) with dated per-step reasons — evidence: `projects/ops/zion/PLAN-ZION-3-kanban-hub-work.md` landing note 2026-09-03/04; steps 9 and 25 (and the sign-in-dependent checks in 13/20/21) are NOT_MEASURABLE because the SSO migration removed the password sign-in path their harnesses use (real 410, confirmed by curl in that record).
- ZION-17's gate is live and survived eleven adversarial rounds; round 12 left NINE unfixed findings — evidence: `projects/ops/zion/evidence/step12-round12-findings-2026-09-03.txt` and `projects/ops/zion/STATE-ZION-17.md`.
- No ZION lane can open a real board card today: `projects/business/business-app/app/functions/api/tasks.js` (`LANES_WITH_AGENT_STAGE_VOCAB`, ~line 216 — re-find by name) lacks `"zion"` while `board-report.mjs` lists zion as writable — evidence: real failed `--open` run recorded in `projects/ops/zion/STATE-ZION-17.md` STEP 14, 2026-09-01.
- Card creation against the live Hub works TODAY by API and is undocumented — measured first-hand 2026-09-04 against the live site: POST to `/api/tasks` with the bearer token from the vault entry `deck-business-skippy-token` returns HTTP 201; `group` and `priority` take exact fixed vocabularies; the read-back rows live at `data.tasks`, not `tasks`; the created card came back `created_by: "monday-dual-write"`. STEP 13 turns this into the guide.
- No competing voice mechanism exists in the Hub — checked two ways per §Z: `command grep -ril "voice" projects/business/business-app/app/js/` and a Glob for `*voice*` under `projects/business/business-app/app/` (both empty of any voice feature, 2026-09-04). The Skippy voice-app lane owns the pattern; this plan consumes it (STEP 11).
- No agent-facing Hub how-to exists among the repo's 51 loose markdown files — checked 2026-09-04: `KANBAN-AND-AGENT-BOARDS-SPEC.md` is a build spec (kanban view + agent layer, parts 1–3 built), `SOP-DERIVED-WORKFLOWS.md` is a human-role SOP survey; neither is an agent-operations guide, and a second sweep (`command grep -ril "how to\|FAQ" projects/business/business-app/*.md`) surfaced no third candidate.

## 0 · Gate Zero receipts (the plan may not exist without these)
- Failure Mode Registry loaded: 2026-09-04, 167 data rows counted across all tables of `.claude/skills/plan/references/failure-registry.md` (the same row set `check_plan.py`'s own counter uses).
- Canonical specs loaded: the plan skill (incl. §W/§Z added 2026-09-04), `projects/ops/agents/CODE-STANDARD.md`, `projects/ops/agents/CREATIVE-QA-STANDARD.md`, `projects/ops/PROMPT-SPEC.md`, `projects/ops/MACHINE-RULES.md`, `projects/ops/REGROUP-SOURCE-2026-09-04.md`, and the Hub repo's own CLAUDE.md (deploy traps, sign-in flow, gate discipline).
- Ownership check: `projects/business/business-app` is an existing owned boundary (ownership projection row cited by PLAN-SMP-5 §0); this plan EXTENDS that boundary's live work and SUPERSEDES the competing governing files (ZION-3, ZION-17; SMP-5's Hub scope) rather than adding a second system — supersession markers land in the same commit as this file.
- Expected inputs confirmed to exist: `harness-zion3-proof-suite.mjs`, `check-handback.mjs`, `board-report.mjs`, `task-run.mjs`, `tasks.js`, the round-12 findings file, `check_plan.py`, `render_sheet.py` — each Glob-confirmed on disk 2026-09-04.
- PLAN AUTHOR: Boris 2 of 3 (senior-engineer, Fable), 2026-09-04, dispatched on Nick's words "boris x 3 on fable 5.1 do the planning".
- COLD READER: none — SINGLE-AUTHOR, UNREVIEWED (a cold read by a different session is queued as the first act of the drive; the plan is honest about shipping unreviewed rather than claiming a review that did not happen).
- PROMPT-SPEC scan (P1–P7): P1 "finish" is pinned by the FINISH LINE's eight checkable items; P3 negatives in the brief ("six fixes never deployed") are re-derived by STEP 2 rather than trusted; P4 "the hub" is bounded by the anti-scope below; P7 Nick's 2026-09-04 multi-part message was split against `projects/ops/REGROUP-SOURCE-2026-09-04.md` A12's verbatim quotes; no unresolved variable remains — the settled ones are in §1a with his words.

## 1 · Goal and definition of done
- **What we're building, one paragraph.** The business Hub, finished: the live app all six people already use, with sign-in moved to Google, every committed fix actually shipped and proven on screen, the reopened Kanban/board work re-closed on its own proofs, board-PM enforcement folded in and closed, an agent-facing guide to the Hub's own infrastructure, and the voice-app pattern deployed on top — then we stop.
- **HOW IT'S USED:** each of the six signs in with Google on the live Hub and works their boards, tasks, payroll, clients and workload; agents post board updates through the enforced gate and learn the Hub's API from the guide instead of rediscovering it. · HOW WE KNOW: STEP 6's per-identity live browser drives and STEP 14's blind finish-line sweep.
- **WHAT IT LOOKS LIKE:** the existing live Hub screens, unchanged except where a §2 row names a fix; new Google sign-in screen; the voice control surface ported from the voice app. · HOW WE KNOW: Sienna's design QA receipt on every changed screen (STEP 12), each claim naming width and theme.
- **WHERE IT LIVES:** the deployed Hub at hub.heroesandsidekicks.io (the domain people use — never the aggressive-caching pages.dev mirror), built from `projects/business/business-app` (its own repo; deploys land via the Mac-mini runner on push with `timeoutSec: 2400`, or `node projects/ops/deploy.mjs deck-business` deliberately) — opened daily by Nick, Chantelle, Rizza, Mae, Dean, Dindin. · HOW WE KNOW: `--step 4` live-parity proof binds served bytes to HEAD.
- **WHAT IT MUST DO:** (1) sign all six in via Google, view-as intact; (2) serve current HEAD live; (3) show every STEP-2 ledger fix working through the real user path; (4) hold the six reopened ZION-3 behaviors green on the existing harness; (5) enforce board updates via the ZION-17 gate with zero open round-12 findings; (6) run the inherited voice setup; (7) let ZION lanes open real board cards; (8) teach the next agent the Hub's infrastructure without rediscovery. · HOW WE KNOW: §6 evals, one row each.
- **NOT in scope:** SECURITY WORK of any kind — audits, credential chasing, hardening nobody asked for — is click-gated through the ZION-8 approval mechanism and lives on the NEXT list until Nick's click (§S; Nick: "we do not do security audits until the end period nobody aiuthorized that"). · The family app's voice/SSO rollout — same pattern, different product, its own lane. · Alexa, shopping lists, weekly success reports, Gracie/Neeko, and every retired ancillary item (Nick, 2026-09-04, A12). · Redesigning the voice mechanism — this plan CONSUMES the voice lane's pattern; inventing a second one is the duplication the house rule bans. · The Monday MIGRATION itself — STEP 13 MAPS the coupling and documents it; ripping Monday out is its own future decision of Nick's. · ZION-3's UNPROVEN-but-not-reopened rows (15/17/18/24 findings) beyond what the no-arg suite itself enforces — each existing finding gets one NEXT-list line, not a workstream.
- **Trip-over protocol:** a lane that finds something outside the fence writes ONE dated handover line to its named owner in `STATE-ZION-19.md` §HANDOFFS, then back to building — never investigates, never fixes.

## 1a · Critical variables — the confirmation sheet is GENERATED from this table

| # | The variable, in plain words | Value chosen | Alternatives rejected | Class | HOW WE KNOW | Cost if wrong | CONFIRMED |
|---|---|---|---|---|---|---|---|
| 1 | **SURFACE — which screen this lands on, and who opens it** | the live business Hub, opened by Nick, Chantelle, Rizza, Mae, Dean, Dindin | a staging copy; a rebuilt app | V1 | Nick's standing V1 for this exact surface and consumer set | wrong audience, wrong app | Nick, 2026-08-30, "SMP-5 Business Hub Nick, Chantelle, and H&S team with specific permissions for each, with Nick and Chantelle full authorization over everything"; re-affirmed 2026-09-04, "finish the hub" |
| 2 | Google sign-in gets switched ON as part of finishing (not left built-and-off) | switch-on is a step of this plan (STEP 6), with the nightly password-login check fixed in the same change | leave it off and hand Nick a switch | V1 | his instruction folding SSO into the Hub work | six people locked out, or a nightly check red every night | Nick, 2026-09-04, fold the SSO work into the Hub programme (recorded in `projects/ops/google-sso/STATE.md`) |
| 3 | Rizza's sign-in maps to finance@heroesandsidekicks.io | keep the mapping as built | remap to a personal address | V1 | he was asked exactly this, with the shared-inbox risk stated | wrong person able to read money numbers | Nick, 2026-09-04, "finance email is rizza" — it is hers alone |
| 4 | Production deploys proceed inside this plan without a per-deploy ask | deploy as the steps require; report after | the 2026-09-01 post-outage rule "a production deploy needs Nick's explicit yes" (that hold was that drive's own binding rule, quoted here so it is not silently stepped over — his 2026-09-04 word to finish supersedes it) | V1 | his newest dated instruction wins over the older drive-local rule | shipping something he wanted held | Nick, 2026-09-04, "The only thing I want to do is finish the hub…" — finishing includes shipping; flagged on the sheet so he can restore the per-deploy hold with one word |
| 5 | The Hub's voice setup is the voice-app lane's pattern, consumed as handed off | wait for that lane's named artifact, then port (STEP 11) | design a Hub-specific voice mechanism now | V1 | his sequencing words | two diverging voice stacks to maintain | Nick, 2026-09-04, "finish voice app then we deploy the same etup in the hub and family app" |
| 6 | The agent guide is part of the Hub work, written for agents (not people) | one guide file in the Hub repo, pointed to from the repo's CLAUDE.md (STEP 13) | a human-styled SOP; a note in Monday | V1 | his own words creating the deliverable | every future agent repeats tonight's failed attempts | Nick, 2026-09-04, "we should have an agent write a how to guide for other agents as a part of the hub work- FAQs and SOPs for the hub infra" |

**Considered and ruled NOT critical** *(the denominator — never demote a variable silently)*:
- Which machine runs the deploy (mini runner vs deliberate `deploy.mjs`) — V2, both are measured paths; STEP 4 proves the result either way.
- The exact undeployed-fix list — V2, derived by STEP 2 from the live revision, never asked.
- The old test-mode/password question (`ZION-3-URGENT-restore-test-mode.md`) — mooted by variable 2: Google becomes the only door, password test-mode ceases to exist as a surface.
- Where the guide lives — V2, settled by opening the two candidate files (see Already true): neither owns agent operations, so one new file with a CLAUDE.md pointer, reason stated.

## 1b · Subproject decomposition — could a piece of this ship on its own?

- **SINGLE SUBPROJECT:** every step lands in the one live Hub app and its enforcement gate; nothing here ships, signs off, or gets used on its own before the Hub does. (The voice APP is a peer lane's product, not a piece of this one — this plan only consumes its pattern.)

## 2 · The complete UX map (this becomes the test manifest verbatim)

| Id | Screen / entry point | State (default·empty·error·loading) | Element / interaction | Expected behavior | Navigation from → to |
|---|---|---|---|---|---|
| U1 | Sign-in | default · loading · error | Google sign-in button | reaches Google, returns signed in as the right identity; no password field exists | / → role home |
| U2 | Sign-in | error | wrong-account return | plain refusal naming no internal detail; retry available | Google → sign-in |
| U3 | Sign-in tab (app.js) | loading | tab before session resolves | inert until session resolved (fix `77acba62`) | — |
| U4 | Role home | default · loading | each identity's landing | correct role home and nav for all six identities | sign-in → home |
| U5 | My Boards | default · empty · error | stats tiles | genuine zero distinguished from failed fetch (fix `2280ff7d`) | home → My Boards |
| U6 | Board / Tasks | default | collapsed card | assignee visible on collapsed cards (ZION-3 STEP 19) | My Boards → board |
| U7 | Task detail | default · error | open from list and board | one shared detail screen, same data both routes | board → detail |
| U8 | Payroll approve | error | transport failure | failure rendered as failure, never as access-denial (fix `516be5ce`) | home → payroll |
| U9 | Clients | default | #clients?filter=risk deep link | filter applies, both former bugs stay dead (fix `c2318c32`) | link → clients |
| U10 | Clients — Archive tab | default | archived Heroes rows | labeled Archived, never Active (fix `fcfe43a8`) | clients → archive |
| U11 | Workload | empty · error | failed vs empty fetch | distinct renders (fix `eb596391`); Dindin denied per scope | home → workload |
| U12 | Workflows / CRM | empty · error | failed loads | never render as genuinely empty (fix `0be9c140`) | home → workflows |
| U13 | Active roster | default | duplicate button | generation-token fix holds (fix `49fcce3b`) | home → roster |
| U14 | View-as | default | Nick/Chantelle switch identity | full round trip intact post-SSO | home → view-as |
| U15 | Voice surface | default · error · denied-mic | the ported voice control | behaves per the voice lane's handed-off pattern | home → voice |
| U16 | Board API (headless) | default · error | agent posts via gate | ZION-17 gate blocks unposted turns, allows confirmed posts; zion lanes can open cards | — |
| U17 | Card-create API (headless) | default · error | POST /api/tasks per the guide's recipe | 201 on the exact vocabularies; 400s on anything else; read-back found at `data.tasks` | — |

## 3 · Lanes and frozen contracts

| Lane | Scope (in / out) | Owner | Definition of done | Model (explicit) |
|---|---|---|---|---|
| A — Ship & verify (STEPS 1–5) | in: Hub repo git state, deploy, live parity, fix ledger, new tests under `_selfchecks/` · out: auth files, gate files | ZION-19 drive | FINISH LINE items 2–3 | builder glm (via `projects/ops/cheap-task.mjs`; haiku through the same router while outside vendors are down); checker sonnet; live-drive checking fable (overseer) |
| B — SSO & reopened steps (STEPS 6–8) | in: auth wiring, the nightly password-login check, harness sign-in path, `task-run.mjs` seam · out: deploy scripts, gate internals | ZION-19 drive | FINISH LINE items 1 and 4 | builder glm (same routing); checker sonnet; live drives sonnet (biz-app-qa) |
| C — Enforcement, board & guide (STEPS 9–10, 13) | in: `check-handback.mjs` + its libs, the single `tasks.js` vocabulary line, this plan's §5 card id, the agent guide + CLAUDE.md pointer · out: everything in lanes A/B | ZION-19 drive | FINISH LINE items 5 and 7 | builder glm (same routing); checker sonnet |
| D — Voice + QA + close (STEPS 11–12, 14) | in: voice port per handed-off pattern, design QA, postmortem · out: the voice app itself (peer lane's) | ZION-19 drive | FINISH LINE items 6 and 8 | builder glm; checker sonnet; design QA creative-director with sonnet, checked by fable; blind sweep sonnet (se-blind-checker), relay fable |

**Contracts between lanes (FROZEN at plan time — change = dated delta in `PLAN-CHANGES-ZION-19.md`):** Lane A alone touches deploy machinery and new `_selfchecks/harness-zion19-*` test files; lane B alone touches `app/functions/api/auth/**`, the nightly check it identifies, the proof suite's sign-in helper, and `projects/ops/skippy-jobs/lib/task-run.mjs`; lane C alone touches `projects/ops/skippy-jobs/lib/check-handback.mjs`+`handback-contract.mjs`, the single `tasks.js` vocabulary line, the guide, and the Hub CLAUDE.md pointer lines; lane D alone touches the new voice files. No two lanes need the same file in the same hour (§W). Commits: ALWAYS scoped `git commit -m "..." -- <paths>`, never bare, never `git stash`; Hub-app paths commit inside `projects/business/business-app` (its own repo — prove with `git rev-parse --show-toplevel` first), plan/state/gate-lib paths commit in the workspace repo — every step below says which. Any edit under `app/`, `engine/`, `_selfchecks/` triggers the full ~25-minute build on push; docs-only pushes are free (`paths-ignore` covers `*.md`).

## 3b · Execution map — the Step map, then one STEP block per row

A task is DONE only when its review-ledger row is CLOSED by a reviewer that is not the builder.

**Step map (read this first):**

| Stage | # | Task (step name) | Gate to enter | EXECUTOR (model, from the matrix) | CHECKER (different model — never the builder) | DONE-PROOF (runnable command) | Ends when |
|---|---|---|---|---|---|---|---|
| Framing | 1 | Re-measure ground truth; reconcile the diverged Hub repo | none — start now | glm (cheap-task router; haiku fallback) | sonnet | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs` | no-arg suite exit code recorded; repo neither ahead nor behind origin/main |
| Framing | 2 | Derive the undeployed-fix ledger from the live revision | STEP 1 proven | glm | sonnet | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 4` | ledger written into STATE-ZION-19.md with live rev + HEAD cited |
| Tests | 3 | Red-first tests for every ledger fix lacking one | STEP 2 proven | glm | sonnet | `node projects/business/business-app/_selfchecks/harness-zion19-fixcoverage.mjs (CREATED BY STEP 3)` | every ledger fix has a test proven RED against pre-fix code |
| Output | 4 | Push, deploy, prove live parity | STEP 3 proven | glm | sonnet | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 4` | exit 0, live token matches HEAD |
| Proof | 5 | Verify every ledger fix on the live surface through the real user path | STEP 4 proven | sonnet (biz-app-qa, browser) | fable — the overseer re-drives two ledger rows in a fresh session | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 19` | each ledger fix seen working live; --step 19 exit 0 |
| Elements | 6 | Switch Google sign-in ON; fix the nightly password-login check in the same change | STEP 4 proven | glm | sonnet (biz-app-qa live drives, different session) | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 9` | all six identities in via Google live; nightly check green |
| Fixes | 7 | Re-close the SSO-broken ZION-3 checks (9, 25; sweep 13/20/21) | STEP 6 proven | glm | sonnet | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 25` | steps 9 and 25 exit 0 |
| Fixes | 8 | Seal `task-run.mjs postCardUpdate` (ZION-3 STEP 14's third-checker find) | STEP 1 proven | glm | sonnet | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 14` | 4 consecutive green runs |
| Fixes | 9 | Fix ZION-17 round-12's nine findings; ONE clean check round | STEP 1 proven | glm | sonnet — one round, per §G | `node projects/ops/skippy-jobs/lib/check-handback.mjs --selftest` | all nine fixed; the single check round returns no dodge |
| Elements | 10 | Open the board to ZION lanes; register this plan's card | STEP 9 proven | glm | sonnet | `node projects/ops/skippy-jobs/lib/board-report.mjs --read` | a real live card carries this plan's §5 id |
| Elements | 11 | Deploy the voice-app pattern in the Hub | voice lane's handoff artifact (see block) | glm | sonnet | `node projects/business/business-app/_selfchecks/harness-hubvoice.mjs (CREATED BY STEP 11)` | voice surface works live per the pattern |
| Details | 12 | Sienna's design QA on every changed screen | STEPS 6, 11 proven (or 11 honestly queued) | creative-director (sonnet) | fable — receipt audited against fresh screenshots by the overseer | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 24` | six-gate receipt on U1–U3, U15 |
| Details | 13 | Write the agent-facing Hub infrastructure guide; map the Monday coupling | STEP 10 proven | glm | sonnet — follows the guide cold, literally | `test -f projects/business/business-app/HUB-AGENT-GUIDE.md (CREATED BY STEP 13)` | a cold agent creates and reads back a card using ONLY the guide |
| Proof | 14 | Blind finish-line sweep + postmortem + close | STEPS 1–10, 12–13 proven; 11 proven or honestly queued | sonnet (se-blind-checker, cold) | fable overseer relays the verdict UNCHANGED | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs` | all eight FINISH LINE items graded; postmortem written here |

**Then one block per step:**

### STEP 1 — Re-measure ground truth; reconcile the diverged Hub repo
**Enter this step when:** nothing. This is the first step.
**Builder:** glm via `projects/ops/cheap-task.mjs` (haiku through the same router while both outside vendors are down) · **Checker:** sonnet, different session
**Files you may touch:** the Hub repo's git state (`projects/business/business-app`, ITS OWN repo — merge only, no source edits) and `projects/ops/zion/STATE-ZION-19.md` (workspace repo). **Never** `app/functions/api/auth/**` (lane B) or gate libs (lane C).

**Do exactly this:**
1. `cd "/Users/nickdeck/Documents/Claude 2.0/projects/business/business-app" && git rev-parse --show-toplevel` — confirm it prints the business-app path, not the workspace (§W: wrong-repo commits are this lane's sharpest trap; it has already cost a session an hour and ~50 misplaced commits).
2. `git fetch origin && git merge origin/main` — bring in the 11 HSDB Phase-3 remote commits under the 4 local ones. If conflicts: read both sides, keep both behaviors, record each resolved file in STATE-ZION-19.md.
3. `node _selfchecks/harness-zion3-proof-suite.mjs` — run the no-arg suite. Record the exact exit code and every red step id in STATE-ZION-19.md. (ZION-3 STEP 1's reopening cause — an untracked fixture — was already committed as `51388a51`; this run is the live re-measure, per the rule that a record of a defect is not a defect.)
4. Any red whose cause is a stray untracked file or environment residue: fix the cause, re-run. Any red owned by a later step of THIS plan (4, 9, 14, 19, 25): record it and move on — it is that step's work, not this one's.

**PROOF — all must be true, pasted into STEPS verbatim:**
- `git -C projects/business/business-app branch -vv` shows main neither ahead nor behind `origin/main`, OR ahead only by commits this plan's own steps made.
- The no-arg suite's exit code and per-step red list are recorded in STATE-ZION-19.md with a timestamp.

**If it fails:** merge genuinely wedged → one line to the overseer naming the conflicted files, then STEP 8/9 (independent of repo state). Dependents need this step SUCCEEDED.
**Checker's job:** re-run the proof yourself. Do not accept the builder's pasted output.

### STEP 2 — Derive the undeployed-fix ledger from the live revision
**Enter this step when:** STEP 1 proven.
**Builder:** glm (same routing) · **Checker:** sonnet
**Files you may touch:** `projects/ops/zion/STATE-ZION-19.md` (workspace repo). **Never** Hub app source.

**Do exactly this:**
1. `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 4` — expect RED with `LIVE_SOURCE_REVISION_STALE`; its output names the live source revision. Paste it.
2. `git -C projects/business/business-app log --oneline <live_revision>..HEAD` — the full undeployed range.
3. Classify each commit: PRODUCT FIX (changes what a person sees or a behavior they hit) vs infra/test/docs. The known candidates from the 2026-09-04 log read — `c2318c32` (clients risk deep link), `0be9c140` (workflows/CRM failed loads), `fcfe43a8` (archive tab labels), `516be5ce` (payroll false access-denial), `77acba62` (inert sign-in tab), `eb596391` (workload failed vs empty), `2280ff7d` (my-boards zero vs failed), `49fcce3b` (roster duplicate button) — are HYPOTHESES to confirm against the real range, not the answer.
4. For each PRODUCT FIX: `command grep -rl "<its key symbol>" projects/business/business-app/_selfchecks/` AND a second differently-shaped search (Glob by date-stamped harness name) to establish whether an automated test exists (§Z: one empty search proves nothing). Record fix → test path or NONE.
5. Write the ledger into STATE-ZION-19.md: one row per product fix — commit, screen, what a person sees, test path or NONE, live-verified? (all "not yet").

**PROOF:** the ledger exists in STATE-ZION-19.md citing the live revision and HEAD by hash; every row's test claim carries both search shapes.
**If it fails:** `--step 4` unexpectedly GREEN means live already matches HEAD — record that, ledger the fixes as deployed-unverified, skip to STEP 5. Dependents need this step ANSWERED, not a particular answer.
**Checker's job:** re-run both commands; spot-check two rows' test-existence claims with your own searches.

### STEP 3 — Red-first tests for every ledger fix lacking one
**Enter this step when:** STEP 2 proven.
**Builder:** glm (same routing) · **Checker:** sonnet
**Files you may touch:** one new file `projects/business/business-app/_selfchecks/harness-zion19-fixcoverage.mjs` (CREATED BY STEP 3) and its registration in `projects/business/business-app/app/gates.js` (Hub repo). **Never** the fixed product files themselves.

**Do exactly this:**
1. For each ledger row marked NONE: add one exported case to the umbrella harness (one file for the whole ledger — extend, never a file per fix).
2. Red-first, per case: `git stash` in ANY form is BANNED (§W) — instead check out the fix's parent commit into a scratch worktree (`git -C projects/business/business-app worktree add /tmp/z19-red <commit>^`), run the case against it, record the RED, remove the worktree.
3. Register the harness in `app/gates.js` in the tier the existing empty-fail harnesses use.
4. Commit scoped, IN THE HUB REPO (prove toplevel first): `git commit -m "ZION-19 STEP 3: fix-coverage harness (red-first proven)" -- _selfchecks/harness-zion19-fixcoverage.mjs app/gates.js`.

**PROOF:** the umbrella harness exits 0 on HEAD; the recorded RED output per case against the pre-fix worktree is pasted in STEPS.
**If it fails:** a case that cannot be made to fail against pre-fix code is not a test — one line to the overseer, mark that fix's coverage UNPROVEN, continue with the rest.
**Checker's job:** re-run green on HEAD, and re-run ONE case against its pre-fix worktree to confirm the red reproduces.

### STEP 4 — Push, deploy, prove live parity
**Enter this step when:** STEP 3 proven.
**Builder:** glm (same routing) · **Checker:** sonnet
**Files you may touch:** none in source — git push and deploy machinery only. **Never** edit files to make a gate pass (MACHINE-RULES Rule 12), and never chain build and deploy through a pipe (the pipeline's exit code hides a BLOCKED build).

**Do exactly this:**
1. `git -C projects/business/business-app push origin main` — this queues the Mac-mini runner's deploy, which may land unattended and hours later; a runner job must declare `"timeoutSec": 2400` or the ~25-minute build is killed at ten minutes and looks like a broken deploy.
2. Poll: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 4` every 30 minutes, three times, doing other unblocked steps meanwhile (a queued deploy is neither progress nor a blocker).
3. If still stale after three polls: `node projects/ops/deploy.mjs deck-business` (the deliberate path — it refuses a behind-remote publish and runs the full gate set; never any other publish route).
4. Verify on hub.heroesandsidekicks.io, never the pages.dev mirror, and only after the ~2.5-minute edge rollout window — one failed probe immediately after "deployment complete" proves nothing.

**PROOF:** `--step 4` exit 0 — the staged manifest and live runtime endpoint identify every shipped byte.
**If it fails:** deploy lands but parity fails → the bundle-parts trap is live; diff the served manifest against dist (the Hub CLAUDE.md's PARTS check for shelf artifacts), name the missing part, one line to the overseer. Dependents need SUCCEEDED.
**Checker's job:** re-run `--step 4` yourself, plus one direct fetch of the live cache token.

### STEP 5 — Verify every ledger fix on the live surface through the real user path
**Enter this step when:** STEP 4 proven.
**Builder:** sonnet (biz-app-qa — real browser, real logged-in identities; a live drive is judgment QA, not mechanical build work) · **Checker:** fable — the overseer re-drives two ledger rows in a fresh session (a different model from the builder, per the review-ledger rule)
**Files you may touch:** `projects/ops/zion/STATE-ZION-19.md` (workspace repo) and evidence files under `projects/business/business-app/HUB-UIUX-AUDIT/evidence/zion-19/` (Hub repo). **Never** app source.

**Do exactly this:**
1. For each ledger row: drive the EXACT user path in §2 (U5, U8–U13) on the live custom domain, at 390px and 1280px, both themes where the screen has them. A fix present in the bundle but not seen working on screen is NOT verified (the measured Hub trap: green build + successful deploy ≠ shipped).
2. Save one screenshot per row into the evidence folder; write the verdict into the ledger row.
3. Re-run ZION-3's own live checks now deploy-dependent: `--step 19` (assignee on collapsed cards) and `--step 13` if red in STEP 1's sweep.

**PROOF:** every ledger row reads live-verified with an evidence path; `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 19` exit 0.
**If it fails:** a fix absent live despite parity → reopen as a real product defect with its own one-round fix via lane A, or NEXT-list it if outside the FINISH LINE. Dependents need ANSWERED.
**Checker's job:** re-drive two ledger rows yourself, fresh browser, before closing.

### STEP 6 — Switch Google sign-in ON; fix the nightly password-login check in the same change
**Enter this step when:** STEP 4 proven (never before live parity — flipping auth on a stale deploy tests the wrong app).
**Builder:** glm (same routing) for the config/check edits · **Checker:** sonnet (biz-app-qa live drives, a different session)
**Files you may touch:** the Hub's auth switch-on config (`app/functions/api/auth/google/*`, `_middleware.js`, `login.js` wiring — Hub repo), and the ONE nightly check identified in action 1 (whichever repo holds it — say which in the commit). **Never** rotate, mint, or edit any credential value — the OAuth secret exists (provisioned by Nick, `projects/ops/google-sso/STATE.md` lane C: done); if a secret is genuinely absent that is a Rule-13 flag, not something to create.

**Do exactly this:**
1. Find the nightly check that exercises the old password login, TWO ways (§Z): `command grep -rln "api/session" projects/business/business-app/jobs/ projects/ops/skippy-jobs/` and a second sweep for the per-identity vault password entries by name. The Hub CLAUDE.md cites its sign-in health job as the reference implementation of the password flow — that job is the leading candidate; NAME the confirmed file in STATE-ZION-19.md before touching anything.
2. Update that check to authenticate through the new path (or a sanctioned test session), in the SAME commit as switch-on — never before, never after.
3. Flip the switch-on exactly as `projects/ops/google-sso/STATE.md` describes for the Hub; commit scoped in the owning repo(s), then ship via STEP 4's route and re-prove `--step 4` exit 0.
4. Live-drive sign-in for ALL SIX identities via Google on the custom domain (agents drive the identity gate as standing policy); confirm view-as round-trips for Nick and Chantelle; confirm Rizza lands with finance scope and no view-as.
5. Run the updated nightly check once, for real, spawned the way its scheduler runs it.

**PROOF:** six live sign-ins evidenced (screenshots in the STEP-5 evidence folder); the updated nightly check exits 0 through its real path; `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 9` no longer returns NOT_MEASURABLE/410 on the sign-in path it needs.
**If it fails:** any identity cannot get in → REVERT the switch-on commit (scoped), redeploy, record the exact failure — the app must never sit half-on overnight. Dependents need SUCCEEDED.
**Checker's job:** re-drive two identities yourself, including one non-owner.

### STEP 7 — Re-close the SSO-broken ZION-3 checks
**Enter this step when:** STEP 6 proven.
**Builder:** glm (same routing) · **Checker:** sonnet
**Files you may touch:** the proof suite's sign-in helper ONLY (port the selector, never the assertion — MACHINE-RULES Rule 12 clause 5), and ZION-3's Status/ledger lines (workspace repo). **Never** the behaviors those steps assert.

**Do exactly this:**
1. Update the harness's authentication path to the post-SSO door (whatever STEP 6 proved live).
2. `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 9` then `--step 25`, then re-run the full no-arg suite to sweep 13/20/21's sign-in-dependent checks.
3. Correct ZION-3's REVIEW LEDGER rows 9 and 25 (and their Status lines) to CLOSED with today's date and this plan named — in `projects/ops/zion/PLAN-ZION-3-kanban-hub-work.md`, workspace repo, scoped commit.

**PROOF:** `--step 9` exit 0 · `--step 25` exit 0 · no-arg suite shows no NOT_MEASURABLE caused by sign-in.
**If it fails:** a check red for a REAL behavioral reason (not auth) → that is a genuine defect: one round through lane A, else NEXT list with the exact reason code. Dependents (STEP 14) need ANSWERED.
**Checker's job:** re-run both steps and one of 13/20/21 yourself.

### STEP 8 — Seal `task-run.mjs postCardUpdate`
**Enter this step when:** STEP 1 proven (independent of deploy — this is workspace-side).
**Builder:** glm (same routing) · **Checker:** sonnet
**Files you may touch:** `projects/ops/skippy-jobs/lib/task-run.mjs` (workspace repo). **Never** `comments.js`/`_kv.js` (already sealed and verified).

**Do exactly this:**
1. Read the sealed sibling pattern in `projects/ops/skippy-jobs/lib/board-report.mjs`'s comment path (the exact seam two prior checkers verified) and apply the identical unsealed-clock fix to `postCardUpdate()` in `task-run.mjs`.
2. Commit scoped in the WORKSPACE repo: `git commit -m "ZION-19 STEP 8: seal task-run postCardUpdate clock (ZION-3 step 14 third-checker find)" -- projects/ops/skippy-jobs/lib/task-run.mjs`.
3. `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 14` four consecutive times — the reopening symptom was an intermittent RED (`RETRY_CHANGED_UPDATE_ID`) on run 3 of 4.
4. Correct ZION-3's step 14 Status line and ledger row to CLOSED, dated, this plan named (workspace repo, scoped commit).

**PROOF:** four consecutive `--step 14` exit 0 runs, pasted with timestamps.
**If it fails:** the intermittent RED reproduces → the seam differs from the sibling's; paste the differing lines, one line to the overseer, do not widen the retry window to go green (Rule 12 clause 1). Dependents need SUCCEEDED.
**Checker's job:** re-run `--step 14` twice yourself and read the seam against the sibling.

### STEP 9 — Fix ZION-17 round-12's nine findings; ONE clean check round
**Enter this step when:** STEP 1 proven (independent lane).
**Builder:** glm (same routing) · **Checker:** sonnet — ONE round (§G: one check round per step; eleven prior rounds are enough adversarial history; the fix for checker-stalls is calling the checker and moving on, never a thirteenth sweep)
**Files you may touch:** `projects/ops/skippy-jobs/lib/check-handback.mjs`, `projects/ops/skippy-jobs/lib/handback-contract.mjs`, their test suites, `projects/ops/zion/PLAN-ZION-17-board-pm-enforcement.md` + `STATE-ZION-17.md` status lines (all workspace repo). **Never** ZION-3's board posting tool (`board-report.mjs`) — its printed outcome strings are a load-bearing dependency of this gate; a change there is a handover, not a fix.

**Do exactly this:**
1. Read `projects/ops/zion/evidence/step12-round12-findings-2026-09-03.txt` in full — nine findings, each naming its owning code.
2. Fix all nine; extend the existing suites with one permanent check per finding (red-first each).
3. Run both suites the record names (the 164-case and 38-case sets) plus `node projects/ops/skippy-jobs/lib/check-handback.mjs --selftest`.
4. Dispatch the ONE checker round. Its verdict lands: PASS closes ZION-17's STEP 12 and this step; a FAIL goes back once, and the re-check covers the named failure only.
5. Update ZION-17's plan/state: STEP 12 closed, this plan named as where the lane's remainder lives.

**PROOF:** all suites green (exact counts pasted); the single checker round's verdict pasted; the round-12 findings file's nine items each mapped to its fix commit.
**If it fails:** the checker finds a real dodge → fix that named item once, re-check that item only, close. Dependents (STEP 10) need SUCCEEDED.
**Checker's job:** attack the gate fresh against the nine findings' shapes — one round, findings named with evidence, no verdict-free "concerns".

### STEP 10 — Open the board to ZION lanes; register this plan's card
**Enter this step when:** STEP 9 proven.
**Builder:** glm (same routing) · **Checker:** sonnet
**Files you may touch:** this plan's §5 card line (workspace repo) — and `projects/business/business-app/app/functions/api/tasks.js` ONLY IF action 1 below shows the vocabulary genuinely missing. **Never** board data itself beyond the one card open.

🔴 **THIS STEP WAS WRITTEN TO ADD SOMETHING THAT ALREADY EXISTS — DO NOT EDIT THE CODE BLIND.** It rested on a failed run from 2026-09-01, and the cold review of 2026-09-04 measured otherwise: `tasks.js:221` already reads `new Set([...AGENT_IDENTITIES, "ai-builds", "zion"])`, and a live probe against production the same day showed a create with `group: "zion"` passing group validation on the deployed Hub (it fails only on the separate required-date rule, a different check). So the vocabulary is live, not merely local. A builder following the original wording would have edited a line that needed no editing — the exact "work already done" trap this drive exists to stop. VERIFY FIRST; edit only if the verification actually comes back missing.

**Do exactly this:**
1. Re-measure before touching anything. `command grep -n "LANES_WITH_AGENT_STAGE_VOCAB" projects/business/business-app/app/functions/api/tasks.js` — read the line. If `"zion"` is present, there is NO code change in this step; record that and go to action 2. If it is genuinely absent, add it, commit scoped in the Hub repo, ship via STEP 4's deploy route, re-prove `--step 4`, then continue.
2. `node projects/ops/skippy-jobs/lib/board-report.mjs --open --lane zion --title "ZION-19 · Finish the Hub" --stage "In Progress" --due 2026-09-11 --assignee nick` — the exact call that failed on 2026-09-01.
3. `node projects/ops/skippy-jobs/lib/board-report.mjs --read` and confirm the live card; write its id into §5 of THIS file (bare-slug convention — the documented ambiguity in STATE-ZION-17.md's workspace-wide finding; STEP 13's guide documents the convention).

**PROOF:** action 1's grep output pasted, showing what the set actually contains; the `--open` call succeeds (paste output); `--read` shows the real live card; §5 below no longer reads `none yet`.
**If it fails:** vocabulary genuinely refused at the live surface → paste the exact refusal, check the `boards_meta` ingest as the alternate route named in the original error, one line to the overseer. A refusal about the DATE is not this step's failure — supply a real `YYYY-MM-DD` and retry, since agent-created cards require one. Dependents (STEPS 13, 14) need ANSWERED.
**Checker's job:** run `--read` yourself and match the card id against §5.

### STEP 11 — Deploy the voice-app pattern in the Hub
**Enter this step when:** RUNNABLE WHEN: a dated handoff line exists in `STATE-ZION-19.md` §HANDOFFS-IN from the Skippy voice-app lane naming its reusable voice-pattern artifact paths (that lane owes this plan that line at its own close — the named artifact, never "wait for the other plan"). Until that line exists this step is QUEUED, never blocked, and every other step proceeds.
**Builder:** glm (same routing) · **Checker:** sonnet; design half goes to STEP 12
**Files you may touch:** new voice files under `projects/business/business-app/app/` per the pattern, `app/gates.js` registration, and the new harness this step creates (all Hub repo). **Never** redesign the pattern — deviations are a handover line to the voice lane, not a fork.

**Do exactly this:**
1. Read the handed-off pattern files end to end; port them into the Hub with only the identity/scope wiring the Hub needs.
2. Write the voice harness mirroring the voice lane's own test shape; red-first (break the wiring in a scratch copy, confirm red).
3. Commit scoped (Hub repo), ship via STEP 4's route, re-prove `--step 4`, then drive U15 live in a real browser including the denied-mic state.

**PROOF:** the voice harness exits 0 (its file is named in this step's step-map row, CREATED BY STEP 11); live browser drive of U15 evidenced (default · error · denied-mic).
**If it fails:** the pattern doesn't fit the Hub's auth/session shape → one dated handover line to the voice lane naming the exact mismatch; this step stays open, STEP 14 grades FINISH LINE item 6 honestly against it. Dependents need ANSWERED.
**Checker's job:** re-run the harness and re-drive U15 default state yourself.

### STEP 12 — Sienna's design QA on every changed screen
**Enter this step when:** STEP 6 proven; U15 included only if STEP 11 has landed (else graded on what exists, gap named).
**Builder:** creative-director (Sienna) with sonnet · **Checker:** fable — the overseer audits the receipt against fresh screenshots; one round, no second adversary (§G)
**Files you may touch:** evidence under `projects/business/business-app/HUB-UIUX-AUDIT/evidence/zion-19/` (Hub repo). **Never** app source — findings route to lane owners.

**Do exactly this:**
1. Grade U1–U3 (sign-in) and U15 (voice, if landed) against the six creative gates, per claim naming width (390/768/1280) and theme.
2. Behavioral defects reopen the owning step for its one fix round; cosmetic ones take one NEXT-list line each.

**PROOF:** Sienna's receipt in the evidence folder, every verdict bound to a fresh screenshot; `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 24` exit 0.
**If it fails:** a behavioral defect → one round via the owning lane, re-grade that screen only. Dependents need ANSWERED.
**Checker's job:** confirm each verdict's screenshot is fresh (taken this step, not reused).

### STEP 13 — Write the agent-facing Hub infrastructure guide; map the Monday coupling
**Enter this step when:** STEP 10 proven (so the guide documents the board as it now works, zion vocabulary included).
**Builder:** glm (same routing) · **Checker:** sonnet — a COLD agent that follows the guide literally, using nothing else
**Files you may touch:** the new guide file (named in this step's step-map row, CREATED BY STEP 13 — Hub repo), plus a two-line pointer added to the Hub repo's CLAUDE.md and one to `KANBAN-AND-AGENT-BOARDS-SPEC.md` (Hub repo). **Never** a 52nd loose file beyond the guide itself — the home decision is made (see §1a denominator): the two candidates were read and neither owns agent operations; the guide gets ONE home and CLAUDE.md points at it.

**Do exactly this:**
1. Write the guide FOR AGENTS (Nick, 2026-09-04: "we need to docment it because its not obvious how to add cards to list on hub but were migrating ther sono and we cant depdn on monday" · "a how to guide for other agents… FAQs and SOPs for the hub infra"). Seed it with the recipe measured live 2026-09-04 — verify each item against the deployed app while writing, never copy blind:
   - Card creation: POST `/api/tasks`, `Authorization: Bearer` + the vault entry `deck-business-skippy-token` (retrieved via the family vault tool; the value is extracted from its VALUE line and never logged or committed). Body `{"action":"create","name":"…","assignee":"nick","group":"general","priority":"normal","due_date":"YYYY-MM-DD"}` → HTTP 201.
   - Trap 1: `group` takes EXACTLY topics · assets · payment-staging · order-requests · recurring · general · gracie · neeko · ai-builds · zion; anything else 400s.
   - Trap 2: `priority` takes EXACTLY `normal` or `someday` — High/Medium/Low all 400.
   - **Trap 3, in bold: the read-back rows live at `data.tasks`, NOT `tasks`** — reading the wrong level returns zero rows for a card sitting first in a list of 171 and makes a successful create look failed.
   - The sign-in flows (password today, Google after STEP 6), the board-card slug convention, how the ZION-17 gate judges a handback, and how to run the proof suite.
2. Map the Monday coupling: trace the `tasks.js` write path to establish why a native create returns `created_by: "monday-dual-write"`, and which vocabularies (groups, priorities, stages) are Monday-derived. ONE observation is a hint, not a map — read the code, list every Monday touchpoint in the write and read paths, and mark each item of the guide MONDAY-DERIVED (will change at migration) or NATIVE. The Updates-panel trap (app-native cards read "No Monday updates on record" forever) goes in this section.
3. Add the pointer lines; commit everything scoped in the Hub repo (docs-only push — free, no build).

**PROOF:** the checker — a cold agent given ONLY the guide — creates a card, reads it back at the right JSON level, and deletes-or-archives it, without one question; the Monday-coupling section lists the touchpoints with file citations.
**If it fails:** the cold agent stalls anywhere → that exact stall point is the guide's defect; fix that section once, re-test that section. Dependents (STEP 14) need SUCCEEDED for FINISH LINE item 7.
**Checker's job:** follow the guide literally, log every place you needed knowledge the guide didn't give you.

### STEP 14 — Blind finish-line sweep, postmortem, close
**Enter this step when:** STEPS 1–10, 12–13 proven; 11 proven or honestly QUEUED with its entry condition still unmet.
**Builder:** sonnet (se-blind-checker — cold, handed ONLY the FINISH LINE and the artifact, never this drive's history) · **Checker:** the fable overseer relays the verdict UNCHANGED — a relay that edits the verdict is the grading it is forbidden to do
**Files you may touch:** this file's STEPS/postmortem/NEXT sections and STATE-ZION-19.md (workspace repo).

**Do exactly this:**
1. Dispatch the blind checker against the eight FINISH LINE items; it re-runs every named command first-hand and drives the live surface for items 1, 3 and 6.
2. Paste the verdict verbatim into STEPS, including any FAIL.
3. Write the postmortem below §6; append any new failure pattern to `.claude/skills/plan/references/failure-registry.md` in the four-column format, same turn.
4. Final scoped commits in both repos, each naming only its own paths.

**PROOF:** the blind verdict pasted unedited; `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs` (no-arg) exit 0; postmortem present.
**If it fails:** any FAIL → one fix round via the owning step, one re-check of the named item only, then close at GREAT (the NEXT list holds everything else).
**Checker's job:** the blind checker IS the check; nobody re-grades the grader.

## 4 · Regret Check (every registry entry, or the plan is not done)

| Failure mode (registry entry) | The measure in THIS plan that prevents it | Where it lives (section / artifact / gate) |
|---|---|---|
|  A second system was built because the first was invisible  | Gate Zero cites the ownership row; this plan supersedes ZION-3/ZION-17 in the same edit rather than adding a competing governing file | §0 |
|  A capability was declared impossible from a stale or unverified claim  | STEP 0's five-minute loop re-checks north star, fan-out cap (8/session, ~40 machine-wide), cheap routing and blocked-claims; blocked requires three named attempts | STEP 0 · §5 |
|  An absence was asserted without opening the store that would hold it  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A known constraint's reason was lost, and it silently capped the product  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  An instruction assumed capacity the executor doesn't have  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Expectations/manifest rows carried no grounding  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  Work was written to a queue no reader ever visits  | STEP 0's five-minute loop re-checks north star, fan-out cap (8/session, ~40 machine-wide), cheap routing and blocked-claims; blocked requires three named attempts | STEP 0 · §5 |
|  A detector's death was invisible because only its target read it  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  A decision settled once re-opened elsewhere, or two copies of a rule disagreed  | Gate Zero cites the ownership row; this plan supersedes ZION-3/ZION-17 in the same edit rather than adding a competing governing file | §0 |
|  A rule constraining the user turned out to be an agent's invention  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  Remediation was ordered with diagnosis last  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A document, label, or comment was believed over the live system  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A proposal was sold on a capability never opened and read  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A cause was named and acted on without eliminating alternatives  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  The human was asked a question the record already answers  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A spec and its guard were authored by the same hand and ratified the same defect  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Session rules never reached the subagents doing the work  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  One rule was blanket-applied across items needing per-item answers  | Gate Zero cites the ownership row; this plan supersedes ZION-3/ZION-17 in the same edit rather than adding a competing governing file | §0 |
|  Pattern-matching scoped too loosely produced false connections  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Rules existed but were psychologically dormant at answer-time  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A run exceeded its cost/time ceiling or hung unbounded  | STEP 0's five-minute loop re-checks north star, fan-out cap (8/session, ~40 machine-wide), cheap routing and blocked-claims; blocked requires three named attempts | STEP 0 · §5 |
|  A helper was dispatched on a brief with a wrong or missing constraint  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  A claim about the user/system was made without its source  | STEP 1 re-measures ground truth (repo state, live revision, suite result) before any step acts; every inherited claim is re-run, never trusted | §3b STEP 1 |
|  A conclusion was drawn from a partial read  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A fact was quoted as current without its date  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A computed value never reached the persistent record  | STEP 1 re-measures ground truth (repo state, live revision, suite result) before any step acts; every inherited claim is re-run, never trusted | §3b STEP 1 |
|  A missing lookup key fell back silently to a wrong default  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A hardcoded identifier broke when the referent was recreated  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A placeholder or wrong-level path shipped as a literal instruction  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A UI reported success while the backend silently failed  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  Mid-session state was assumed unchanged  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Uncertainty was silently absorbed instead of marked  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  A serial multi-step operation blew its time budget  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  An external action went unlogged and became unrecoverable  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  A tool's own description contradicted house reality and won  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Personal/identifying data exposed, or a record written to the wrong subject  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  One instance of a defect class was fixed while its siblings stayed broken  | Gate Zero cites the ownership row; this plan supersedes ZION-3/ZION-17 in the same edit rather than adding a competing governing file | §0 |
|  A read operation mutated state  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  The three biggest absence-claims variants: empty result, broken probe, discarded stderr  | STEP 1 re-measures ground truth (repo state, live revision, suite result) before any step acts; every inherited claim is re-run, never trusted | §3b STEP 1 |
|  A generated mirror was hand-edited, or its generator never re-ran  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Deployed config silently diverged from source config  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A delivery path was reordered and its notification behavior changed  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A critical boundary was config-editable and could be silently widened  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A "growing" archive had actually frozen  | STEP 1 re-measures ground truth (repo state, live revision, suite result) before any step acts; every inherited claim is re-run, never trusted | §3b STEP 1 |
|  Files were archived but their citations kept pointing at them  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  A pipeline broke silently and looked identical to a working one  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  Output was delivered somewhere the intended reader never looks  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Concurrent sessions clobbered each other's work in a shared file  | STEP 0's five-minute loop re-checks north star, fan-out cap (8/session, ~40 machine-wide), cheap routing and blocked-claims; blocked requires three named attempts | STEP 0 · §5 |
|  An enforcement gate covered fewer paths than its rule, or failed open  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Identity or authority was read from a value the caller supplies  | Security work is click-gated and in the anti-scope; credentials are never rotated or raised; findings cost one NEXT-list line | §1 NOT in scope |
|  A new failure state was detected but reached no human  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  The builder graded its own work and passed it  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A check existed that could not fail  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  The review didn't cover the shipped artifact  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  A narrowing/refactoring change broke the cases that were already correct  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A check's verdict depended on wall-clock, machine load, or a concurrent writer  | STEP 0's five-minute loop re-checks north star, fan-out cap (8/session, ~40 machine-wide), cheap routing and blocked-claims; blocked requires three named attempts | STEP 0 · §5 |
|  A test existed but nothing ran it  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  An interactive element or view shipped untested / unseen  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Coverage was reported optimistically  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A staleness/freshness check used the wrong proxy  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A quantitative claim shipped without its method  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Done was declared before the live surface was checked  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A biometric/metric overrode the human's stated reality  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A correlation was asserted as a cause  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  A nuanced reality was collapsed into a clean binary  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  A recommendation repeated something already tried, uncited  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A wrong record was disclaimed instead of corrected  | STEP 1 re-measures ground truth (repo state, live revision, suite result) before any step acts; every inherited claim is re-run, never trusted | §3b STEP 1 |
|  Open items were re-typed from memory and drifted  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A deliverable was referenced instead of delivered  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A report used names/shorthand only the writer understood  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  Commands were sent to a surface that can't run them  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  A number was published without the population it was counted over  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  A finding existed only in the session's output and died with it  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  The plan named a target with total precision, and the target was wrong  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  The human approved a summary, and the summary was silent on the deciding variable  | STEP 1 re-measures ground truth (repo state, live revision, suite result) before any step acts; every inherited claim is re-run, never trusted | §3b STEP 1 |
|  A project stated its scope and never its anti-scope, and lanes leaked into adjacent work  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A new rule was written as prose inside its own fix, with nothing enforcing it  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  A confirmation was satisfied by checking the wrong kind of fact  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A blocker common to every lane was carved out of all of them and given to nobody  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Lanes were built to stop: one pass, land, idle — while fixed ceremony ate the context  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  A caveat nobody measured travelled as fact through multiple independent lanes  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  The environment destroyed work silently, and the lane wrote a wrong lesson from it  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A specification described ONE lifecycle in several places, and the copies drifted independently — four consecutive cold reviews each found ~5-8 blocking ambiguities, because every patch added another partial description of the same state machine  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A task brief on an existing project was treated as the plan, and a generated status checklist was treated as the task list  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  A regression test's "red-proof" failed for a reason unrelated to the thing it claimed to prove, twice in one session, two different mechanisms  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A standing instruction to route work to an outside/cheap engine eroded over a long session into doing the work directly  | One overseer thread tracks every step against the FINISH LINE; failures land in STATE-ZION-19.md the same turn and STEP 14's postmortem appends new entries to the registry | §5 · STEP 14 |
|  A plan's own second line named a different document as the authority, and the reader proceeded without opening it  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A live bug got three consecutive confident wrong-or-unproven diagnoses, two claiming live verification  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Fourteen guards stayed green all day while the live screen showed the wrong thing  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  An agent was accused of fabricating its report because a narrow search failed to find the file it cited  | STEP 1 re-measures ground truth (repo state, live revision, suite result) before any step acts; every inherited claim is re-run, never trusted | §3b STEP 1 |
|  A tool's failure verdict was believed without checking the disk — and separately, a success verdict shipped a syntax error  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  A build with several independently-shippable pieces was planned and run as one monolithic project, too large for one agent to hold  | STEP 0's five-minute loop re-checks north star, fan-out cap (8/session, ~40 machine-wide), cheap routing and blocked-claims; blocked requires three named attempts | STEP 0 · §5 |
|  A rule written only in prose, with no template slot and no machine gate, behaved as if it didn't exist  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A row-quality check counted TOTAL filled cells instead of checking the specific columns it claimed to require  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Three independent readers reported wildly different "% complete" for the exact same objective state — twice, on two different subprojects  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A V2 "opened it, here's what I saw" confirmation was wrong three separate times because it opened the WRONG PATH — the plan's own stated location, never independently rediscovered  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A shared coordination file used by several subprojects at once had no per-subproject write fence, and one subproject's list silently filled with rows belonging to the others  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  The single cheapest, most decisive test of a build's core hypothesis was defined at planning time (correctly) but not RUN until after most of the build effort was already spent  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A dispatched build agent reported an interim status ("build is in progress, will resume once a Monitor delivers the completion notification") as its FINAL answer and returned, instead of waiting for the real result  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A sandbox restriction produced the EXACT error text this same repo's own CLAUDE.md already documents as a sign of a genuinely broken machine ("chrome exited early, code null" / Chrome preflight failure), and it was initially read as that known problem rather than investigated as a new one  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A paid external tool (Codex CLI) ran out of its own usage quota mid-build, and the agent that hit the limit chose to switch to running the command directly via its own Bash tool instead of the mandated Codex path — correctly, but this is a real, recurring risk that needs a standing rule, not a one-off judgment call  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  A card-creation script reported success ("card opened... read back and confirmed") and its own internal counter incremented, but the card did not actually exist on live re-query — twice, for two different cards, requiring full manual re-creation  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Three separate, independently-fatal wiring gaps each made the same feature (the ai-builds board) non-functional in a different way, and NONE of them were caught by a passing `build-dist.js` run, any TIER-1 or TIER-2 gate, or any API-level check  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A real, deployed code fix (the three fixes directly above) did not reach a real user's already-open browser tab, even after that user hard-refreshed multiple times  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A correct, intentional, previously-ruled-on design decision (the task screen's default view narrows to "my own tasks" even for leadership identities) was mistaken for a bug because it was checked from only ONE identity's login  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  The Updates panel — the actual surface a person opens to read what an agent posted about a card — is wired to Monday.com sync data ONLY, and an app-native card (this entire board) has no Monday board behind it, so it will read "No Monday updates on record for this item" FOREVER, regardless of how many real, correctly-formatted updates were posted server-side  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped; STEP 13's guide documents this exact trap for every future agent | §3b STEPS 4-5 · STEP 13 |
|  A pure oversight/QA dispatch (re-run four questions, grade the answers, write nothing) was refused twice in a row by the WORK-TYPE gate as "unclear," burning two full agent-spawn round-trips before the actual task began  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  The same brief, past the work-type gate, was then refused by a SEPARATE gate for missing the ~6,000-word MACHINE-RULES travel block — a requirement with no automatic injection and no template a brief author can copy from without hitting the refusal first  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command | §5 topology |
|  A fix (new SYSTEM-prompt grounding rules) was drafted, partially applied to disk, and left in a syntactically-valid but COMPLETELY UNVERIFIED state when the tool writing it (Codex CLI) hit its own account-wide usage cap mid-task  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  The above fix's failure was found ONLY because a second, genuinely fresh-context pass re-ran the real test live — the first pass's own self-check (syntax valid, code present) had already been satisfied and would have been reported "done" without it  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A confirmed, applied data fix was verified as working because it had only been applied to ONE of two live copies of the same data (production) — the copy actually being tested against (staging) still held the old, wrong text  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A 16-question regression suite meant to catch exactly this bug class had been silently crashing on question 1 and reporting nothing useful for a full day, because a dependency it called gained a new required argument and nobody re-ran the suite after that change landed  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Two entire bodies of real, load-bearing work — a 34-file answer pipeline and this drive's own PLAN.md/STATE.md tracking pair — had never been committed to git, on any machine, the whole time they were being built, found only by accident while fixing something else  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A request to deepen an existing artifact was answered by re-polishing the context already in hand, while named, existing sources were never opened  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A gate protecting one specific, highly sensitive file covered some tool surfaces (Write/Edit/MultiEdit) but not others (Bash), and the gap sat honestly documented in the file's own header for a day before being closed  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A function parameter's DEFAULT value silently made an entire decision branch unreachable, under a fully green test suite, since the day the branch was written  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  A write-then-rename ("atomic write") pattern was used to update one row in a file that has a SECOND, independent writer appending new rows — the pattern is genuinely atomic against a torn read, and genuinely loses any row the other writer appended during the read-modify-write window  | STEP 0's five-minute loop re-checks north star, fan-out cap (8/session, ~40 machine-wide), cheap routing and blocked-claims; blocked requires three named attempts | STEP 0 · §5 |
|  A test suite's own "red-proof" claimed a safety property held ("removing the fix would fail the test") without ever actually removing the fix and running the suite  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Test files that exercised a shared module's logging path wrote real output into the REAL production log file, even though every other piece of test state (queue, tickets, journal) was correctly scoped to scratch directories  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  An identity verified once, in memory, from a live authenticated source, was designed to be re-derived later from a file any process could write — which would have made the file, not the live authentication, the actual source of trust  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A background daemon process registered a global crash-and-exit handler for unhandled promise rejections; a later feature fired a promise without a `.catch()` in that same process, meaning any transient failure in that one feature (a network timeout) would have crashed the ENTIRE daemon, including everything unrelated it was doing  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A build's supersession of one design ("a standalone daemon" → "extend the existing listener") correctly re-scoped every task around the new mechanism's natural shape, and in doing so quietly dropped a piece of functionality that had no obvious home in the new shape  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  `fs.watch()` on a shared state directory was assumed to be a sufficient delivery trigger, and was not — under real concurrent load from ~235 other sessions writing to sibling files in the same directory, two real queued requests sat with zero fs.watch event ever firing  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A plan asserted facts about the repo it never checked — one step named a symbol that travels under a different name; another's file fence named a file that does not exist (merges log items A3, A4, D2)  | Every dispatch carries the §T header with MACHINE RULES substance pasted, an exact file fence, and an exact proof command; every proof path in this plan was Glob-confirmed on disk at planning time | §5 topology · §0 |
|  The program fixed what was BROKEN instead of building what was ASKED FOR — a day's good work landed on a component its own plan retires (log item J1)  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; the NORTH STAR outranks every step and the loop re-aims at it every five minutes | §3b STEPS 4-5 · STEP 0 |
|  A plan passed every gate — well-formed steps, real proofs — and still could not deliver what the user asked for (log item J2)  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; the FINISH LINE is written in Nick's own scope words and graded blind | §3b STEPS 4-5 · STEP 14 |
|  An assistant's first-person account of its own failure was taken as the root cause by every reader, and it was false (log item J3)  | STEP 1 re-measures ground truth (repo state, live revision, suite result) before any step acts; every inherited claim is re-run, never trusted | §3b STEP 1 |
|  Three verifications were real and all three had the wrong SCOPE: verifying a quote is not verifying the claim; verifying a file once is not verifying it now; verifying the code path is not verifying the thing (merges H1, H2, H3 — one defect, three extents)  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  An orchestrator's confident relay propagated a wrong conclusion to five sessions faster than any plan could — a real acceptance criterion was deleted on it — and the builder that refused the relay with evidence was right (merges F1, J4)  | Every new test is proven RED against reverted code before it counts (STEP 3); the builder's standing to refuse a step that contradicts the code is written into §A and honored here | §3b STEP 3 · §3b |
|  One writer in three read the same handoff as a gate and serialized nine of fourteen steps behind another chunk's tenth step (log item F3)  | Every step's Enter line names its SPECIFIC dependency; STEPS 8, 9, 11 run independent of the deploy chain by design | §3b |
|  Every failure mode of the file-approval machinery was silent: an approved-once path became permanently un-requestable; a legitimate handoff into a shared governed file consumed another chunk's pending approval; approval never notified the requester; one approval unlocked exactly one edit operation, losing a two-part edit's second half; and a plan tracker named STATE.md missed the PLAN-shaped free-edit carve-out, costing ~10 approval taps in one evening (merges B1, B2, B3, B4, I2)  | STEP 0's five-minute loop re-checks north star, fan-out cap (8/session, ~40 machine-wide), cheap routing and blocked-claims; blocked requires three named attempts | STEP 0 · §5 |
|  A governance CLI silently dropped unrecognized flags (exit 0), let a two-token flag value overwrite the file path, let --reason swallow the next flag as its value, and its own written spec documented the broken form in two copies (merges C1, C2, C3, C4)  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Plan shape existed as convention, not enforcement: plans degenerated into 1,000-line session logs; the plan template itself failed the machine gate; the checker validates a plan's parts, never its shape (merges A1, A2, D1)  | This plan passed `check_plan.py` at creation and the write gate ratchets every future edit; history goes to STATE, never into the step blocks | §0 · §3b |
|  A punchlist item condensed to six words pointed its reader at exactly the wrong action — implementing it literally would have silently rerouted every assistant reply into manual approval (log item I3)  | STEP 0's five-minute loop re-checks north star, fan-out cap (8/session, ~40 machine-wide), cheap routing and blocked-claims; blocked requires three named attempts | STEP 0 · §5 |
|  A production secret read as SET when its value was EMPTY, and every check agreed with the wrong answer for 90 minutes across three sessions  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  The SAME claim, on the SAME evidence, was CONFIRMED by a checker asked to verify it and REFUTED by a checker asked to break it — and the refuting one was right  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Reasoning ABOUT a system instead of ASKING it — the single most repeated failure of the 2026-08-27/28 night, four times across three different sessions, every time producing a confident and wrong claim from real evidence  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A hard prerequisite discovered AFTER a decision, with no owner assigned, silently converts a made decision into an unimplementable one  | Every new test is proven RED against reverted code before it counts (STEP 3); the tasks.js vocabulary prerequisite for board cards has an owner and a step (STEP 10) | §3b STEP 3 · STEP 10 |
|  A relayed instruction is acted on, or held, by whether the RELAY ITSELF could be the attack — and sessions had no test for that, so they either obeyed every relay or refused every relay  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Two independent programs audited themselves on the same night and found the same disease — every instrument reported a state that was not the system's state — while both had been reading the reports as ground truth  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A PROOF block read as complete while still containing its own template placeholders — four times in one plan, and the shape is mechanically detectable  | Every new test is proven RED against reverted code before it counts (STEP 3); the no-arg proof suite must exit 0 at the finish line and each step's checker re-runs the proof first-hand | §3b STEP 3 · FINISH LINE |
|  Real evidence, deliberately destroyed for a good reason, is indistinguishable from evidence that never existed  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; every live-drive verdict saves its screenshot to the evidence folder | §3b STEPS 4-5 |
|  A capability was ruled impossible on the strength of a query that structurally could not see the answer — the same shape as an earlier logged incident, on a different tool, and it was not recognised  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; §Z's two-shaped-search rule binds every absence claim in this plan | §3b STEPS 4-5 · §Z |
|  The instruments used to verify a UI lie in four distinct ways, and a "drive the real surface" standard that does not name them produces confident false results  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; drives run on the custom domain, after the edge window, at named widths and themes | §3b STEPS 4-5 |
|  A step's entry gate was satisfied and the step still could not run, and the format had nowhere to say so  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; every step carries an If-it-fails branch that names where the failure lands | §3b |
|  An automated proof's own internal check detected failure and the surrounding pipeline logged success anyway — the checking logic and the reporting logic disagreed, and reporting won  | Every new test is proven RED against reverted code before it counts (STEP 3); never chain build and deploy through a pipe (STEP 4) | §3b STEPS 3–4 |
|  A dispatch gate blocked the exact defensive pattern its own preceding line prescribed, for the exact reason that pattern exists  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A fallback held in place to make a cutover safe was itself the reason the cutover could never succeed — every retry failed, and each failure made the fallback look more necessary  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; STEP 6's fail branch reverts rather than half-holding | §3b STEPS 4-6 |
|  An approved instruction was correct when it was approved and harmful by the time it could be delivered — and every existing rule for handling relayed instructions asked only whether it was AUTHENTIC, never whether it was still TRUE  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; §1a row 4 quotes BOTH of Nick's dated rulings so the newer one supersedes in the open | §3b STEPS 4-5 · §1a |
|  "I fixed the file" · "I deployed it" · "that is what the user sees" are THREE different claims, and a chunk can be right about the first two and wrong about the third — the gap is a client cache that no repo read, no deploy log and no server-side fetch can see  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  In a multi-session build, code read from the working tree is not the state of the system — it may be another session's half-finished fix, and reading it as established behaviour produces a confident diagnosis of a bug that does not exist  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; §W's re-read-before-write and scoped-commit rules bind every step | §3b STEPS 4-5 · §W |
|  Three successive rounds of fixes each produced an honest, passing proof, and the user's original complaint was untouched by all three — because every proof measured the mechanism the fixer had chosen to fix, never the sentence the user actually said  | The FINISH LINE is written in Nick's own scope words and graded by a blind checker against the live surface, not against the fixes' own mechanisms | FINISH LINE · STEP 14 |
|  A correct local caution was escalated into a fleet-wide halt across eight sessions on a crisis that did not exist — and the escalation priced only one side of the decision  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; a finding gets ONE owner or a NEXT-list line, never a swarm (§T overseer rule) | §3b STEPS 4-5 · §5 |
|  An overseer reported two pieces of work as missing because no message about them had reached its inbox — both had landed, were logged with dates and real terms, and one had already passed a full triad  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; state lives in STATE-ZION-19.md, read at every step start, never in an inbox | §3b STEPS 4-5 · §5 |
|  An acknowledgement from the system under test was read as evidence of the outcome — the same word, `queued`, covered a genuine pass and a silent 40-minute failure on the same endpoint the same night  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; STEP 4 polls the live revision rather than trusting the push's acknowledgement | §3b STEPS 4-5 |
|  An overseer authorized an action by bridging a DIFFERENT ruling of the user's onto the question — reasoning correctly from a real quote that was about something else, three relay hops from where it was said  | STEP 0's five-minute loop re-checks north star; every §1a confirmation quotes Nick's words about THIS exact variable, dated | STEP 0 · §1a |
|  An agent, blocked by a safety guard mid-test, offered the user a choice between loosening the guard and accepting weaker proof — presenting a load-bearing protection as one of two equal options  | Security work is click-gated and in the anti-scope; credentials are never rotated or raised; findings cost one NEXT-list line | §1 NOT in scope |
|  A fault that repairs itself faster than anyone reports it is invisible to every alarm in the system — two family-facing surfaces cut out roughly twice a day for a MONTH and nobody escalated once  | Every new test is proven RED against reverted code before it counts (STEP 3); STEP 8 runs its proof four consecutive times because the defect it seals is intermittent | §3b STEPS 3, 8 |
|  A relayed approval was acted on as if the work were still outstanding — and the same file had already been written, by the session doing the relaying  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; STEP 1 re-measures before any step acts on any inherited record | §3b STEPS 1, 4-5 |
|  An investigator noticed that a metric could not possibly detect what it was being asked to detect, WROTE THAT DOWN, and then built a headline claim on it anyway — because the number it produced agreed with the conclusion  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  An investigation's own searches and relays contaminated the evidence it was searching for — 80 of 84 occurrences of the string were manufactured by the act of investigating it  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  Three unrelated lanes in one night each ran an honest check against an intermittent fault and each got a clean answer, because a point-in-time probe is mathematically almost certain to miss a fault that heals itself  | STEP 8 runs its proof four consecutive times against a known-intermittent defect; single clean probes are never accepted for it | §3b STEP 8 |
|  An overseer holding the user's GENUINE first-hand instructions relayed them as authority to four sessions — and one correctly refused, because accuracy and standing are different things and only one of them travels  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; the builder's standing to refuse a contradicted step is honored (§A) | §3b STEPS 4-5 · §3b |
|  A file that documents its own version history in prose ABOVE its code turns every unanchored search into a lie — three sessions in one hour read the changelog and believed it was the declaration  | STEP 1 re-measures ground truth; ZION-3's dated Status lines are corrected in place by STEPS 7-8 so no stale claim outlives its fix | §3b STEPS 1, 7-8 |
|  A commit hash cited as closing evidence resolved to nothing later — sometimes minutes later — because the citation was checked when it was written and never at the moment it was relied on  | STEP 0's five-minute loop re-checks state; every closing citation in STEPS is re-run by the step's checker at close time, not trusted from the builder | STEP 0 · §3b |
|  A step's own PROOF COMMAND, not just a claim someone else wrote, over-matched — pointed at the right file this time, it still returned a plausible, close, wrong count  | STEPS 4-5 verify every shipped fix on the live site through the real user path after deploy; bundle presence or a green build is never accepted as shipped | §3b STEPS 4-5 |
|  A deliberate, reviewed, gate-passing commit was pre-empted by an automatic snapshot that bundled the change with unrelated files, destroyed its commit message, and meant the commit-time gate never executed at all  | Every commit in this plan is scoped `-- <paths>` with its repo named; §W's rules bind every step; the two-repo split is proven with rev-parse before any commit | §3 contracts · §W |

Novel risks specific to this build, same format:

| Failure mode | The measure in THIS plan that prevents it | Where it lives |
|---|---|---|
| A green build and successful deploy shipped a bundle missing the fix's own part | STEP 5 verifies each fix on the live rendered screen through the real user path, never by build output; STEP 4's fail branch runs the PARTS diff | §3b STEPS 4-5 |
| The nested Hub repo received a workspace commit, or vice versa | every commit instruction names its repo and paths; STEP 1 action 1 proves the toplevel before anything commits | §3 contracts · STEP 1 |
| Auth switch-on stranded an identity overnight | STEP 6's fail branch is an immediate scoped revert + redeploy, never a half-on wait | §3b STEP 6 |
| The plan's own supersessions left two governing files competing | ZION-3/ZION-17 carry SUPERSEDED-BY markers in the same commit that lands this file | §0 ownership receipt |
| The guide documents the Monday-shaped vocabulary as if it were permanent | STEP 13 marks every guide item MONDAY-DERIVED or NATIVE from a traced write path, not one response field | §3b STEP 13 |

## 5 · Topology and roles
- **OVERSEER-AUTHORITY:** none named — `projects/ops/OVERSEER-AUTHORITY.md`'s holder table is dormant (ZION-17's live audit, 2026-09-01); this plan's lanes work as if the file did not exist. The four approval classes (money leaving · credential rotation · irreversible destruction · a message sent as Nick) and the data floor (logins/keys/secrets/financial detail) never move on any overseer's word.
- Thread layout: ONE Fable overseer thread for the whole drive (Nick, 2026-09-04: Fable oversees build work and design QA); lanes A–D run as dispatched workers under it, staggered waves.
- Overseer: fable · Lane execution: glm via `projects/ops/cheap-task.mjs` (haiku through the same router while both outside vendors are down — one over its weekly limit, one at zero balance, measured 2026-09-04) · Checkers: sonnet, always a different session from the builder; where the builder is itself sonnet, the checker is fable · Design QA: creative-director (Sienna) with sonnet · Blind close: sonnet (se-blind-checker).
- Concurrency: hard ceiling 8 simultaneously-running agents in this session AND ~40 machine-wide — count live sessions (`ls /tmp/cc-socks/`) and divide before every wave; a wave that has not returned is load, not progress. Raising either number is Nick's call alone.
- State files location: `projects/ops/zion/STATE-ZION-19.md` · `projects/ops/zion/PLAN-CHANGES-ZION-19.md` · questions/assumptions live as sections inside STATE-ZION-19.md, not new files.
- **Board card id:** none yet — opening it IS STEP 10 of this plan (blocked today by the tasks.js vocabulary gap; a fabricated id here would be the exact dishonesty ZION-17 exists to catch).
- **Artefact consumers:** the fix ledger → STEP 5's driver and STEP 14's blind checker; evidence folder → Sienna and the blind checker; the agent guide → every future agent working the Hub (reached via the Hub CLAUDE.md pointer); ZION-3/ZION-17 status corrections → any future session resuming those lanes; the postmortem → the failure registry and the next plan's Gate Zero.
- **Write-contention:** lanes A–D own disjoint path sets (§3 contracts); the two repos are named per step; checkout proven writable at STEP 1 (real merge + real commit) and re-proven by each step's own scoped commit landing.

**Per-stage topology — counts DECLARED at plan time:**

| Stage | Overseer | Sub-overseers | Workers |
|---|---|---|---|
| Framing (1–2) | 1 | 0 | 1 |
| Tests (3) | 1 | 0 | 2 |
| Output/Proof (4–5) | 1 | 0 | 2 |
| Elements/Fixes (6–10) | 1 | 0 | 3 |
| Voice/QA/Guide (11–13) | 1 | 0 | 2 |
| Close (14) | 1 | 0 | 1 |

**The walk-away contract — a stranger resumes the drive from files alone:**
- **STATE FILE:** `projects/ops/zion/STATE-ZION-19.md`
- **HEARTBEAT ROW:** `zion19-hub-finish` in `projects/personal/skippy-app/ala-state/work-threads.json` (registered at lane-open by the overseer; beaten each pass)
- **MORNING-REPORT LINE:** "Hub finish (ZION-19): <n>/14 steps proven, finish line <m>/8" in `projects/ops/walkaway/REPORT.md`

## 6 · Evals — what "working" means, decided now

| Capability | Check (exact command or procedure) | Pass looks like |
|---|---|---|
| All six sign in via Google, live | STEP 6's six real browser drives + `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 9` | six evidenced sign-ins; exit 0 |
| Live serves current HEAD | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 4` | exit 0 |
| Every ledger fix works live | STEP 5 drives per §2 rows U5, U8–U13 + evidence paths | every ledger row live-verified |
| Ledger fixes have real tests | `node projects/business/business-app/_selfchecks/harness-zion19-fixcoverage.mjs (CREATED BY STEP 3)` | exit 0, with recorded pre-fix REDs |
| Reopened ZION-3 behaviors hold | `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs` (no-arg) | exit 0 |
| Board gate enforced, nine findings dead | `node projects/ops/skippy-jobs/lib/check-handback.mjs --selftest` + the one checker round | suites green; round returns no dodge |
| ZION lanes can open cards | `node projects/ops/skippy-jobs/lib/board-report.mjs --read` | this plan's real card visible |
| Voice works in the Hub | `node projects/business/business-app/_selfchecks/harness-hubvoice.mjs (CREATED BY STEP 11)` + U15 drive | exit 0; three states evidenced |
| The guide actually teaches | STEP 13's cold-agent walkthrough (create → read back → archive, guide only) | zero questions needed; U17 behaviors confirmed |

## If you get stuck (all steps)

Before writing "blocked": (1) try a concrete workaround, (2) re-read the step's proof requirements — most "stuck" is a misread gate, (3) write one line to the overseer AND the owner of the blocker. Only then log `STEP <N> BLOCKED — tried: <a>,<b>,<c>. Need: <one sentence>.` Then keep working every other unblocked step. Never idle on a blocker; never end a turn waiting on a background result.

## Your loop

Every pass: find the lowest-numbered step whose enter gate is proven and which is not yet proven → do it → produce its proof → paste the proof under the matching item in STEPS below → repeat.

## SUMMARY — a few plain-English lines, read by the status generator

The business Hub is one of only two things Nick wants finished. Everything needed is either built and waiting to ship, built and waiting to be switched on, or reopened with a known cause. This plan ships the waiting fixes and proves them on the real screens, turns Google sign-in on for all six people, re-closes the reopened board work on its own tests, folds the board-enforcement gate in and closes it, writes the how-to guide so no future agent has to rediscover the Hub's own machinery, and then deploys the voice setup the voice-app team hands over. Nothing here is speculative; every step re-runs a proof that already exists or creates one that can fail.

## STEPS

1. Re-measure ground truth; reconcile the diverged Hub repo — 0%
   DEFINITION OF DONE: repo neither ahead nor behind origin/main; no-arg suite exit + red list recorded in STATE-ZION-19.md
   PROOF: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs`
2. Derive the undeployed-fix ledger from the live revision — 0%
   DEFINITION OF DONE: ledger in STATE-ZION-19.md citing live revision and HEAD by hash, test-existence per fix checked two ways
   PROOF: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 4`
3. Red-first tests for every ledger fix lacking one — 0%
   DEFINITION OF DONE: umbrella harness green on HEAD, each case proven RED against its pre-fix worktree
   PROOF: `node projects/business/business-app/_selfchecks/harness-zion19-fixcoverage.mjs (CREATED BY STEP 3)`
4. Push, deploy, prove live parity — 0%
   DEFINITION OF DONE: live token matches HEAD byte-for-byte, on the custom domain, after the edge window
   PROOF: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 4`
5. [UI] Verify every ledger fix on the live surface through the real user path — 0%
   DEFINITION OF DONE: every ledger row live-verified in a real browser with evidence path; --step 19 exit 0
   PROOF: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 19`
6. [UI] Switch Google sign-in ON; fix the nightly password-login check in the same change — 0%
   DEFINITION OF DONE: six identities in via Google live in a browser; nightly check green through its real path; view-as intact
   PROOF: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 9`
7. Re-close the SSO-broken ZION-3 checks (9, 25; sweep 13/20/21) — 0%
   DEFINITION OF DONE: steps 9 and 25 exit 0; no sign-in-caused NOT_MEASURABLE anywhere in the suite
   PROOF: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 25`
8. Seal task-run.mjs postCardUpdate — 0%
   DEFINITION OF DONE: the sibling seal pattern applied; four consecutive green runs
   PROOF: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 14`
9. Fix ZION-17 round-12's nine findings; one clean check round — 0%
   DEFINITION OF DONE: nine findings each mapped to a fix commit and a permanent red-first check; the single checker round returns no dodge
   PROOF: `node projects/ops/skippy-jobs/lib/check-handback.mjs --selftest`
10. Open the board to ZION lanes; register this plan's card — 0%
    DEFINITION OF DONE: the 2026-09-01 failed --open call now succeeds; §5 carries the real card id
    PROOF: `node projects/ops/skippy-jobs/lib/board-report.mjs --read`
11. [UI] Deploy the voice-app pattern in the Hub — 0%
    DEFINITION OF DONE: pattern ported unmodified but for identity wiring; U15 driven live in three states
    PROOF: `node projects/business/business-app/_selfchecks/harness-hubvoice.mjs (CREATED BY STEP 11)`
12. [UI] Sienna's design QA on every changed screen — 0%
    DEFINITION OF DONE: six-gate receipt bound to fresh screenshots for U1–U3 and U15
    PROOF: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs --step 24`
13. Write the agent-facing Hub infrastructure guide; map the Monday coupling — 0%
    DEFINITION OF DONE: a cold agent creates and reads back a card using only the guide; every guide item marked MONDAY-DERIVED or NATIVE from a traced write path
    PROOF: `test -f projects/business/business-app/HUB-AGENT-GUIDE.md (CREATED BY STEP 13)`
14. Blind finish-line sweep, postmortem, close — 0%
    DEFINITION OF DONE: cold checker's verdict on all eight finish-line items pasted unedited; postmortem written; registry appended
    PROOF: `node projects/business/business-app/_selfchecks/harness-zion3-proof-suite.mjs`

## NEXT list (found after the finish line was set — recorded, not worked)

- (empty at lane-open)

Current state STATE-ZION-19.md

# STATE — ZION-19 · Finish the business Hub · created 2026-09-04 by the planning session (Boris 2)

## Current state (rewritten in place — this section only, never appended)

**Plan written, lane not yet open.** No step has run. The first act of the drive is a cold read
of the plan by a session that did not write it (the plan's §0 declares SINGLE-AUTHOR honestly),
then STEP 1. The overseer registers the heartbeat row `zion19-hub-finish` at lane-open.

**Ground truth measured at planning time (2026-09-04, re-measure at STEP 1 before acting):**
- Hub repo (`projects/business/business-app`, ITS OWN git repository): main ahead 4 / behind 11
  vs origin/main. Local unpushed: `69a0b9c0`, `51388a51`, `4f7da632`, `c2318c32`. Remote-only:
  the HSDB Phase-3 PR merges (#153–159).
- Live production drift: ZION-3 STEP 4's two regroup verifiers measured
  `LIVE_SOURCE_REVISION_STALE`, 29 commits behind local HEAD at that measurement.
- Both outside cheap vendors down (one weekly limit, one zero balance) — cheap routing falls
  back to haiku through the same router until they recover.

## The undeployed-fix ledger (written by STEP 2 — placeholder until then)

| Commit | Screen | What a person sees | Test path or NONE | Live-verified? |
|---|---|---|---|---|
| (STEP 2 derives this from `git log <live_revision>..HEAD` — candidates hypothesised in the plan, not assumed) | | | | |

## Who is driving this
- **Overseer session:** the ZION-19 Fable overseer thread (topology in PLAN §5).
- **Lanes re-read this file:** at the start of every step.
- **Unowned-blocker owner:** the overseer.

## Questions (open → answered, in place)
- none yet

## Assumptions (each carries who assumed it and the check that would break it)
- none yet

## HANDOFFS (outgoing, one dated line each)
- none yet

## HANDOFFS-IN
- (awaiting the Skippy voice-app lane's dated line naming its reusable voice-pattern artifact
  paths — PLAN STEP 11's entry condition. That lane owes this line at its own close.)