All six merged, gate green (14 steps, backend 260/260). Records the three tickets that could not be built as written — RB-12's wrapper/public binary does not fit the route table, RB-14's command exits 0 on a High advisory, and RB-15 needed a third environment name because RB-09 makes Production fail to boot — plus RB-13's measured duplication drop (168 -> 32 lines per side). Adds a section on dispatching implementation agents. Four of six agent-runs were handed a worktree branched from a stale ancestor; batch 3 was three for three. That, the background-task parking, and the git-checkout-destroys-work trap are all cheap to prevent in the prompt and expensive to discover. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
25 KiB
Agent run status
| Agent | Status | Last module processed | Last updated | Notes |
|---|---|---|---|---|
| baseline | complete | all (18 FE + 7 BE modules) | 2026-08-26 | 0 layering violations. 11 observations BL-001..BL-011. Thresholds for Phase 1 in §9 — agent 01's [N] lines = 40 (TS fn) / 60 (C# method) / 400 (file). Read BL-001, BL-002 and BL-004 before filing complexity, duplication or coverage findings. |
| readability | skipped | n/a | 2026-08-27 | skipped — deliberate. BL-001: 23 of the 25 TS functions over CC 10 are reducers / parse* boundaries / validate*, all mandated house idioms; TS fn-length p99 is 34 with only 2 functions over 75 lines. Little left for this agent to find that is not a false positive. Revisit if the CC>10 population grows outside those three shapes. |
| testability | complete | all 24 modules | 2026-08-26 | 9 findings TE-001..TE-009; 15 modules explicit "no findings". Corrected BL-004 — libs/shared/domain and libs/beheer/contracts are pure type declarations, 0% is unimprovable (amendment note in 00-baseline.md §10). TE-009 is also a latent correctness bug (dead ActiveOn branches). Acquitted createDraftSync, httpClientFetch, Contracts/Mappers.cs in writing. |
| ddd-hexagonal | skipped | n/a | 2026-08-27 | skipped — deliberate. FE layering is clean (baseline §6: 0 violations, healthy instability gradient, kernel I=5% vs contexts I>=83%); backend Domain/ is verified EF/ASP-free. The agent may only extend existing hexagonal structure, and the one real target (Program.cs) has no Features/ folder to extend — agent 04 already filed that as out-of-mandate OOM-A. |
| cqrs-light | complete | all (16 FE + 6 BE modules) | 2026-08-26 | 7 findings CQ-001..CQ-007; 12 modules clean. Corrected BL-007 (see the amendment note in 00-baseline.md §10) and found 3 mutations the baseline missed. Program.cs → Features/+handlers filed as out-of-mandate OOM-A, not a ticket; CQ-006 is its prerequisite. bhp/behandeling named the reference implementation — do not "clean it up". |
| bdd | skipped | n/a | 2026-08-27 | skipped — deliberate. No BDD tooling present, and the prompt forbids proposing any; it self-reduces to a single structural note. gen:behaviour-spec already extracts behaviours from spec names into libs/shared/docs/behaviour-spec.mdx, which covers the intent. |
| adr-conformance | complete | all 6 ADRs | 2026-08-26 | 11 findings: 6 code, 5 ADR-fix (architect approval required). Sharpened BL-002 — Principal was never built, so ADR-0002 was untested not falsified (amendment note in 00-baseline.md §10). ADR-0005 fully conformed. Gates: ADR-C-005→ADR-C-004; ADR-C-003 gates contracts/ cleanup. 3 ADR-fixes need a matching CLAUDE.md correction in the same diff. |
| bio2-compliance | complete | all modules + 7 control areas | 2026-08-27 | 20 findings BIO-001..BIO-020 (12 defect now, 8 production gate). High: BIO-008 BSN concatenated into the authz audit Resource (Program.cs:674, verified); BIO-004 GET /uploads/{documentId}/content has no authz at all (verified). Answered agent 06's handoff as BIO-002 — a production behandelportal build resolves to the seeded zorgverlener, failing closed on backoffice caps but open on citizen-scoped ones incl. CanRevealBigNummer. Carries the mandatory "compliance review required" list: 16 rows over agents 02/04/06. Also a pre-production checklist (~25 boxes). |
| consolidation | complete (approved) | all inputs | 2026-08-27 | HALTED for human approval (per spec) — 99-backlog.md written, nothing implemented. 33 open tickets RB-01..RB-33 + 5 ADR-fixes + 5 already-shipped, from 47 findings. RB-01 (no authz on upload content) and RB-02 (BSN in the audit Resource) sort above all structural work. Gate relaxed to the 4 agents that ran; a "Coverage of this backlog" note records what the 3 skips leave unowned. Caught two orchestrator errors: CQ-002 is NOT fixed (verified — ApplicationsStore.cancel/AdminCasesStore.delete still swallow errors → RB-20), and CQ-004 shipped with half its compliance criterion unmet (no audit row on PUT /admin/flags/{key}, verified → RB-07, which blocks signing ADR-C-009). OOM-D: re-run the baseline before using it to verify any ticket — ADR-C-006 and BL-008 moved it. Approved 2026-08-27; HALT lifted. |
Phase 3 — implementation
| CD batch | Tickets | Status | Notes |
|---|---|---|---|
| 1 | RB-01, RB-02, RB-03, RB-04, RB-05, RB-06 | complete | Six commits on refactor/adr-c-006-shared-route-guards, one per ticket, each with implementation/rb-0N.md. npm run ci green. Every ticket left a test that was verified red without its fix. Carryover: RB-01's residual belongs to RB-09 (the content endpoint is reached by a plain browser navigation with no identity header — BIO-002); Pii.MaskTail now lives in Domain/People/Pii.cs, use it in RB-11 rather than hand-rolling a second masker; RB-06 additionally deleted SubmissionRules.RejectRegistratie (judgement call, recorded). |
| 2 | RB-07, RB-08, RB-09, RB-10, RB-11 | complete | All five merged; npm run ci green on the fixed gate (see below). RB-07 unblocks signing ADR-C-009 and closes CQ-004's outstanding half. RB-09 makes Production throw at startup when no real IIdentityProvider exists — note an environment that is neither Development nor Production (e.g. Staging) still fails fast, but at GetRequiredService, with a worse message. RB-10 landed parseStoredSession twice, once per app, deliberately — TE-001/BL-002 say extract-to-shared contradicts ADR-0002; RB-13 differentiates them. RB-11 corrected a factual error in BIO-012 (the proefbrief error mapping was inlined, not already a separate function) and left the step-up as a literal moved one layer up to its only caller — BIO-006(c) stays a production gate. RB-01's residual is still open and is not solved by RB-09: the upload-content link is a plain browser navigation with no credential. |
| 3 | RB-12, RB-13, RB-14, RB-15, RB-16, RB-17 | complete | All six merged; npm run ci green (14 steps — RB-14 added one — backend 260/260). RB-12 rejected the ticket's binary framing: of 47 routes only 16 use one of the five admin wrappers; of the remaining 31 only 10 are genuinely public, the other 21 are ownership-scoped inline (ctx.Zorgverlener()/ctx.Caller()) or use another mechanism. The allow-list therefore carries a reason per route, not a blanket "public" label. Known limitation: detection is .Gate("XAdmin") metadata declared at mapping time — a declaration, not a derivation, so it cannot catch a route that declares a gate it does not have. This is RB-19's safety net; read rb-12.md before starting RB-19. RB-13 measured ssp/auth ↔ bhp/auth duplication at 32 lines each side, down from 168 (backlog expected <40); each app holds only its own Principal variant, which is ADR-C-004's own proposed resolution, and ADR-0002's "Known debt" section became an amendment. RB-14 could not be built as written — dotnet list package --vulnerable exits 0 on a High advisory (verified), so a bare - run: would have been a gate that enforces nothing; scripts/dotnet-audit.sh matches the output instead and is shared by ci.yml and ci-local.sh. RB-15 used a third environment name (Staging) in its test, since RB-09 makes Production fail to boot at all. |
| 4 | RB-18..RB-23 | not started | RB-19 is the only High-risk ticket; it needs RB-12's route-table test first. |
| 5 | RB-24..RB-30 | not started | RB-25/26/27 all depend on RB-24. |
| 6 | RB-31, RB-32, RB-33 | not started |
Standing caveat for every batch: dotnet test reports one failure,
OpenZaakIntegrationTests.Admin_cases_returns_the_seeded_zaak_mapped_through_real_HTTP_and_JWT,
which needs a live OpenZaak container. It fails identically on a stashed tree — it is not
caused by any of these tickets. npm run ci does not run it.
Gate integrity — read before trusting any "ci green" in this file
scripts/ci-local.sh chained six of its steps as cmd1 && cmd2 under set -e. Bash exempts
every command of an AND-OR list except the last from errexit, so a crash in cmd1 was
swallowed: the paired check never ran and the script still printed "local CI passed". Verified
directly — bash -c 'set -e; false && true; echo hi' prints hi and exits 0.
This hid a real gen:api crash introduced by RB-09 (dotnet swagger's design-time host
defaults to Production, which RB-09 made throw). .github/workflows/ci.yml runs each step as
its own - run: and would have caught it, so the local gate was strictly weaker than the
remote one — the opposite of its purpose. The worst instance was
ng build ssp --localize && ng build behandelportal --localize: a missing English translation
in ssp could not fail the run.
Fixed in build: stop ci-local.sh swallowing the first half of every paired step. Every
"ci green" recorded for batch 1 and for RB-07/RB-10/RB-11 predates that fix and is therefore
weaker than it reads; the batch-2 completion run above is the first one made on the honest gate
(13/13 steps, exit 0). Nothing has since been found wrong with batch 1, but it has not been
re-verified under the fixed gate either.
Dispatching implementation agents — what actually goes wrong
Batches 2 and 3 ran tickets as parallel agents in git worktrees. Six of seven agent-runs hit at least one of these. Put all of it in the prompt.
- The worktree base is not reliable. Four of the six agents were handed a worktree
branched from a stale ancestor — batch 3 was three for three, all landing on
ae7781e, an unrelated lineage missing every RB ticket and this backlog directory. Make step zero:git log --oneline -8, confirm a named expected commit,git mergethe target branch if absent, and report which it was. The one agent that was not told to do this found out by luck. - Agents park on background tasks. Two agents in batch 2 ran
npm run ciin the background, then ended their turn waiting for a notification that never usefully arrived; one finished its work twice and never committed it. Banrun_in_backgroundand Monitor, and say explicitly to pass the Bash tool's owntimeout: 600000— a batch-3 agent still auto-backgrounded because "run it in the foreground" alone does not defeat the 120s default. git checkout <file>destroys the work. Agents verify a test is red by undoing the fix; restoring it withgit checkoutreverts the whole file. Tell them to undo and redo with edits.behaviour-spec.mdxconflicts on nearly every merge. It is generated and every agent regenerates it. Resolve centrally withnpm run gen:behaviour-spec && git add; tell agents to expect it and never hand-edit.- Concurrent
dotnet testruns flake — a burst ofSQLite Error 1: 'no such table: Documents'. Partly host pressure, but RB-12 found a real cause: a barenew WebApplicationFactory<Program>()races on the staticDb.ConnectionString. Use the houseTestWebApplicationFactory+IClassFixtureidiom. Do not trust a backend green while another agent is testing. - Agent worktrees live inside the repo, so
prettier --check .walks into them — fixed by ignoring.claude/worktrees/in both.prettierignoreand.gitignore.
Telling agents to report a ticket as wrong pays off. Three did: BIO-012 was factually wrong about the proefbrief error mapping (RB-11), RB-12's wrapper/public binary did not fit the code, and RB-14 as worded would have shipped a non-gate. None of the three would have been caught by a review of the diff alone.