Delivery operating model¶
1. Purpose and status¶
Temporary planning document; planning only. Nothing here authorises code, a flag change, a
deployment, a merge, a GitHub write or a message. It sets out how the
integrated plan is actually delivered: by one accountable approver, Chris,
and a large workforce of agent sessions (Claude Code and Codex), one writer per wt worktree
under /home/chris/workspace/syrf/pr/.
It resolves every finding of round-2 review DS (delivery strategy), the delivery parts of review AC (AC-03, AC-09, AC-25 and its §3.2), PH-11, UX-13 and MS-01 (for the critical path), and the gate and join findings of reviews RT and NS. The resolution record has one row per finding. Companion pages: programme integration (joins and other programmes), acceptance criteria (merge and activation criteria, tiers per release), UX strategy (design QA content and the U-validation schedule).
Labels. As in the decision register. Everything here
is PROPOSAL unless it cites an owner decision or a measured fact. All nine Batch D1 questions
are decided. D1-01 (Chris, 3 October): keep #3964, port #3969's active-member check and tests,
close #3969. It has been carried out: #3964 merged on 3 October 2026 (85e6facf7) and #3969 is
closed. D1-02 to D1-09 (Chris, 3 October, evening): approved as recommended
(decision register §1.13),
with parts still open: the tester names (D1-06) and the date for #3987's activation (D1-03) are
needed for G0, F1a confirms D1-08's start thresholds from M0 evidence, and the #3965 restack (D1-09) depends on the stack owner. Every D2, D3 and D4 ID cited
here is open. "R0's admission service" is the
per-project enrolment service (CanonicalEnrolment) in the domain model's naming.
Evidence baseline. main at de3e98c59 (3 October 2026, 14:47 BST). PR, issue, run and host
state read between 15:14 and 15:25 BST the same day; the state of #3964 and #3969 re-read at
20:35 BST.
What changes in the plan:
| Today in the plan | Under this model |
|---|---|
| Independent lane owners; "sequencing assumes parallel teams can be staffed" (A-10) | One approver; five delivery streams with briefs and stream-lead sessions; implementer and fresh-verifier sessions per slice (§2) |
| Programme owners sign contract changes | A fresh-context agent runs the programme's checklist against its rules file; Chris rules on exceptions (§2.5) |
| G0 exit evidence: "lane owners named" | Operating model, stream briefs, decision calendar and Batch D1 answers approved (§3.2) |
| One F1 mega-gate | F1a engine contracts; F1b catalogue and export disclosure; F1c IA, copy and AF2 seams merged as code (§3.3) |
| M0 in a scratch worktree | S0 scaffolding (eight PRs), then M0 as a merged walking skeleton with go/no-go thresholds (§4) |
| Windows W0–W8 schedule the work | A dependency-driven ready queue with WIP limits; windows kept as an illustration (§5) |
| A GA chain without R2d, R3c, R3d or the production chains | The GA path is the latest of six chains; approver throughput is the binding constraint (§6) |
| One nine-item gate for every release | Tiers T1, T2 and T3 (§7); merge criteria on every PR, activation criteria on a recorded release candidate (§8) |
| "A passing Claude review" | Supervised and delegated review tiers, stack depth at most two, a ship-gate verifier (§9) |
| No CI, host or Bramble budget | Budget rules, an e2e strategy, a Bramble calendar and a Juniper session cap (§10) |
| A conflict model for the AF2 shell only | Hot-file register, generated-file protocol, claim step, PR size, ADR block, merge trains (§11) |
| No unit smaller than a release; no DoR or DoD | Definitions of ready and done (§12); release briefs in the async-fold format and agent briefs (§13); STATUS ledger and weekly digest (§14) |
| The architecture review (#3961) missing | Joint sequencing and precedence (§15) |
2. Operating model¶
2.1 One accountable approver¶
Chris is the single accountable approver for this plan and for the programmes it joins. DS found
that all 400 PRs since 8 September were authored through his account; main recorded at least
412 PR merges on 24 of the 31 days from 3 September to 3 October (mean 17 on a merge day, peak
53; git log --first-parent --merges). Agent engineering capacity is not the constraint (A-36).
His decisions, gate passages and acceptances are (A-35, §6.4).
Consequences:
- A lane owner is a stream brief plus a stream-lead session (§2.2 to §2.4). Lanes stay as the scope map in plan §4.
- A programme-owner sign-off is a fresh-context agent checklist against that programme's rules file; Chris reviews exceptions only (§2.5).
- G0's exit evidence becomes "operating model, stream briefs and decision calendar approved", not "lane owners named" (§3.2).
- Implementation is authorised per freeze gate through one dossier per gate (D1-04, approved on 3 October; §2.7, §3.6), as plan §12 now records. Nothing is built under the plan before G0.
- The authority agents follow (ledger, package, research inputs) is merged to
mainfirst (step 0, D1-05), because every agent session starts frommain(DS-17).
2.2 Five delivery streams¶
| Stream | Lanes | Leads | Contracts it provides | Notes |
|---|---|---|---|---|
| A Engine and definitions | L0 (compatibility floor, admission service), L1, L2, L13 | S0-1, S0-3, S0-4, S0-6; M0; R0; R1a; R2a backend; R2c; R2d; R3d | C1 to C5, C16, C18, C19 | Owns the canonical engine and definition folders |
| B Workflow, profiles and operations | L3, L4, L7 | R2b; R3a; R3b; R3c; AL1 | C6, C7, C8 | Joins FEAT-024, eligibility, allocation, presence and batches |
| C Reviewer workspace and admin UX | L5, L16 | F1c seams; R1b; the reviewer UI slices of every release; admin, overview and coexistence screens | C17 | Sole writer of the AF2 and stage-review shell files (§11.3) |
| D Reconciliation, history and notifications | L6, L11, L14 | R4a; R4p; R4b; R4c; R5a; R5c | C9, C11, C15 (consumer side) | Owns StudyConversation from R4a (NS-19) |
| E PRISMA, classification and outcomes | L9, L10, L12 | P1; P2; R5b; C1; C2; O1; O2 | C12, C13, C14 | Works under the FEAT-011 change policy |
Cross-cutting roles are staffed by sessions the programme lead starts when needed: L8 permissions (C10; R1c and R1d with the authorization programme #3335), L15 adoption (R6, R7) and L17 acceptance (fixtures, harnesses, e2e; S0-2, S0-7, S0-8). L0's governance work (contract registry, gates, dossiers, STATUS, the ADR block, PR dispositions) belongs to the programme lead session.
Each release has one lead stream. Its release brief assigns slices to supporting streams: for example, R2c puts publication in A, usage evidence in B with the FEAT-024 programme, and the impact dialog in C.
2.3 Sessions and roles¶
Model routing follows Chris's standing rules for Fable-tier orchestration.
| Session | How many | Model | Does | Never does |
|---|---|---|---|---|
| Programme lead | 1 | Fable | Ready queue, WIP limits, STATUS, gate dossiers, decision calendar, weekly digest, cross-stream conflicts, ADR block | Write product code |
| Stream lead | 5 | Opus | Stream brief; release briefs (slice tables); slice briefs; claims; sequencing inside the stream; review triage; reads implementers' diffs and runs the verifying commands | Merge without the tier's evidence; edit another stream's leased files |
| Implementer | 1 per slice | Opus for supervised-tier slices; Sonnet for delegated-tier slices; Codex where the mixed pool routes a slice | One slice in one wt worktree; red-first tests; a PR with the programme section filled in |
Edit outside its allowed files; hand-merge generated files; use git stash |
| Fresh verifier | Per supervised PR, per gate checklist, per ship gate | Opus in a fresh context; cross-review for high-stakes changes |
Reads the brief, the diff and the rules files; runs the verifying commands; reports PASS or FAIL with file:line evidence | Fix the code it verifies |
| Scanner | As needed | Haiku | Mechanical scans: inventories, labels, digest data | Judgements |
A slice moves from the stream lead's brief to an implementer, who claims it (§11.5), builds it in its own worktree and opens a PR; the PR is reviewed by tier (§9) and merged; the worktree is then removed (§11.6). A stream lead corrects an implementer's shortfall by message rather than rewriting its work, and never has two implementers active on one branch.
2.4 Stream briefs¶
Each stream has one brief of at most 200 lines, approved at G0 and revised at each freeze gate:
- Mission and boundary; the lanes it covers.
- Releases it leads and supports, with their state in the ready queue.
- Contracts it provides and consumes, with versions and fake locations.
- Folders it owns and hot files it may lease (§11.1).
- Programmes it joins and the rules files their checklists use (§2.5).
- Decisions it depends on (Batch IDs) and the "until answered" behaviour for each.
- The path globs that put a PR in the supervised review tier (§9.3).
- WIP limits and default model routing.
- Stop-and-ask triggers specific to the stream, beyond §2.9.
2.5 Programme-owner sign-off¶
Every "owner signs" in the plan becomes a fresh-context agent checklist against the programme's rules file. The verifier answers each checklist item PASS, FAIL or N/A with file:line evidence. Each FAIL becomes an exception in the gate dossier with a recommendation; Chris rules on exceptions only. A passed checklist counts as the programme's signature. Where the rules file is stale or missing, the programme lead commissions a docs PR first; a checklist cannot pass against a stale baseline (this applies to tracking now, RT-27).
| Programme | Checklist source | Used at |
|---|---|---|
| FEAT-024 statistics | .claude/rules/materialized-stats.md; gates in docs/features/materialized-project-statistics/STATUS.md |
F1a, F2, F3, F5; any PR touching statistics seams or pinned command budgets |
| Bulk update and study locks | .claude/rules/bulk-study-locks.md |
F1a, R0 |
| Persistence and cache | .claude/rules/repository-cache.md |
F1a; every canonical repository PR |
| AF2 | AF2 binding rules in src/services/web/CLAUDE.md; docs/features/annotation-form-v2/remaining-delivery.md |
F1a (adapter design), F1c, F4, F5 |
| Stage-review layouts (Dockview) | .claude/rules/stage-review-layouts.md; docs/planning/stage-review-layouts/contract.md |
F1c |
| Feature flags | .claude/rules/feature-flags.md; docs/how-to/manage-feature-flags.md |
S0-6; every flag PR |
| CI routing | .claude/rules/ci-workflows.md; docs/how-to/juniper-runner-routing.md |
Any workflow change |
| Identity | .claude/rules/identity-auth.md |
R1b to R1d where identity is touched |
| Authorization (#3335) | handover/2026-09-08-authorization-3335/PLAN.md (outside the repository) |
F1b; R1b to R1d |
| Presence and tracking | docs/features/signalr-active-reviewer-tracking.md, after the presence owner's refresh (RT-27) |
F1a, F4, X-CLAIMS |
| Eligibility | docs/planning/review-eligibility-policy.md |
F3 |
| Allocation | docs/features/proportional-study-allocation/STATUS.md and editor-save-workflow.md |
F-A |
| Material 3 (FEAT-023) | docs/features/material-3-migration/technical-plan.md; the Material 3 boundary section of src/services/web/CLAUDE.md |
F1c; tier-1 design QA on every UI PR |
| Notifications | The stack's docs/features/notification-inbox/technical-plan.md and the C15 v2 ADR |
F1b, G-NOTIF |
| PRISMA | The FEAT-011 change policy (docs/features/prisma-specification/) |
F3, F-P, F6b |
2.6 What Chris decides and what is delegated¶
| Chris decides (never delegated) | Delegated under a gate's authorisation |
|---|---|
| Owner and product decisions (Batch B, C and D) | Release and slice briefs inside an authorised scope |
| Passing every gate: G0, the M0 go/no-go, freeze gates, G-NOTIF, G-GA, G-ADOPT per wave, G-RETIRE | Ready-queue order inside the WIP limits; claims; sequencing inside a stream |
| Implementation authorisation per gate (D1-04) | Implementation, tests, PRs, /claude-review requests and one fix round |
PROPOSAL thresholds, confirmed at each freeze gate |
Preparing delegated-tier PRs for merge; the merge itself keeps Chris's /approve, batched daily (D1-04) |
| Rulings on checklist exceptions | Rebases; regenerating generated files; harvest-and-close of PRs whose disposition he already decided (QM v2, #2224) |
| ADR approval (he reads the summary of each docs-only ADR PR) | STATUS, slice issues, the weekly digest |
| Release acceptance (walkthrough by tier) and go/no-go | Fresh-verifier runs; e2e runs; benchmark runs inside booked Bramble windows |
| Production enablement per release; production admission of pilot projects | Staging and preview smoke checks on recorded release candidates |
| Production data operations: adoption waves, outcome migration, production index builds, production configuration | Closing duplicate or superseded slice PRs inside the programme |
| Staging promotion pause windows; Bramble windows (it is his workstation) | |
| The tester panel and the design acceptance cadence (D1-06, D3-02) |
2.7 One dossier per gate¶
The programme lead prepares one dossier per gate: a markdown file under the STATUS home, at most two pages plus generated appendices. A fresh verifier checks that every evidence link resolves before Chris sees it.
- Ask. Pass the gate, and authorise the listed slices (IDs, stream, review tier, size estimate).
- Decisions needed now. Batch IDs with the recommendation and the "until answered" behaviour,
answered in one
batch-grillsitting where Chris replies only with deviations. - Evidence matrix. Exit-evidence and criterion rows with links, generated from the traceability file.
- Exceptions. Every FAIL from fresh-context checklists, each with a recommendation: fix before passing, or accept with a follow-up issue.
- Joins, risks and capacity. External chains with RAG status, WIP, CI queue time, Bramble windows.
- If not passed. The re-plan options.
2.8 Decision calendar tied to gates¶
Batch B is split by gate, as DS asked. The "Needed by" cell in the open questions is the deadline: each question, or each part of a split question, sits in the sitting held before that gate, and a split question is named with its part in both sittings. A question is late when its gate's dossier is ready and it is still open; the digest shows its age, and the re-plan trigger fires at 10 days (§5.6).
| Sitting | Held before | Questions | Notes |
|---|---|---|---|
| 1 | G0 | The Q-03 catalogue subset (moved from F1); D4-18 (mapping part); D3-14 and D3-15 if S0-4 and S0-7 are to be enabled early. D1-02 to D1-09 were answered on 3 October, as recommended (decision register §1.13) | D1-01 to D1-09 decided (D1-01 carried out). Still needed for G0 from the D1 answers: the tester names (D1-06) and the date for #3987's activation (D1-03) |
| 2 | F1a | D2-01 to D2-16; Q-27 (R2a's Save effects); D1-08 (start thresholds, approved on 3 October, confirmed from M0 evidence); D3-14 (unless answered at sitting 1); D3-16 (contract part: the claim contract fields and route seam); D3-17; D4-06 (R1a catalogue part); D4-12 (markers in C3) | The F1a parts of split questions; C7 and C3 freeze only with these answers |
| 3 | F1b and F1c | D3-01 to D3-04, D3-06, D3-08, D3-15 (unless answered at sitting 1), D3-20 | Copy deck, UI1 approach, legacy restyle, browsers, presence disclosure |
| 4 | F2 | Q-34; Q-20 (narrowed by NS-14); the Q-03 Publish subset; D3-10 (a, b, d) | Batch B "F2 set" |
| 5 | F3 | Q-15, Q-24, Q-28, Q-12, Q-30, Q-01, Q-02; the Q-03 stage-lifecycle and Monitor subset; D3-05, D3-07, D3-09, D3-12 (first part), D3-13, D3-16 (production route), D3-18, D3-19, D3-23 (R3c's notices); D4-04, D4-19 | Batch B "F3 set" |
| 6 | F4 and F5 | Q-29, Q-35, Q-36, Q-04, Q-32, Q-11, Q-26; the Q-03 reconciliation subset; D3-10 ©; D3-11; D3-25; D4-01 to D4-03, D4-05 (amendment rule), D4-12 (F4 part), D4-13, D4-17, D4-20 | Batch B "F5 set" and the first half of Batch C |
| 7 | F6a, F6b and the lane freezes | Q-33, Q-37, Q-06b, Q-22, Q-23, Q-17, Q-18, Q-19, Q-16, Q-21, Q-05; D3-12 (identification part); D4-05 (search fields), D4-06 (F-O part), D4-07 to D4-11, D4-14 to D4-16, D4-18 (audit part), D4-21 | Lanes and reporting |
| G-NOTIF | Each environment and kind family | D3-21, D3-22, D3-24 | Notifications (D3-23 moved to sitting 5, for R3c; D3-25 to sitting 6, for F4) |
2.9 When agents stop and ask¶
An agent stops, records the question in STATUS and passes it to the programme lead, who batches it for Chris, when:
- an owner decision is missing and the brief states no "until answered" behaviour;
- a frozen contract (its ADR, DTOs, fake or conformance suite) would need to change;
- an invariant in plan §2 conflicts with the brief or with the code;
- a production or data action is needed: production configuration or admission, an index build, a migration, a deletion, GitOps production values;
- a major security problem is found;
- a hot-file lease or a competing claim blocks the slice and "first ready lands, the later one rebases" cannot resolve it;
- the slice cannot stay near the PR-size limit and needs an exception (§11.7);
- a check the DoD requires cannot run (missing tooling, no Bramble window).
Review and audit findings that are not correctness, regression or major security problems never stop work: they become follow-up issues.
2.10 Tools reused¶
wt newin the foreground for every worktree;start-work;/ship-pr <n> --no-cleanupto merge, then removal of only that worktree;to-issuesfor slice issues;handoverbetween sessions;batch-grillfor decision sittings;pr-deep-analysisorcross-reviewfor fresh verification;phased-rolloutfor each release's planning phase, with progressive dark merges instead of holding every PR until the end.~/.claude/scripts/pr-review-settled.shand the review bot's summary comment before any claim that a PR is ready.- FEAT-024's
BenchmarkEnvironmentpattern; theIAggregateWriteGuardplusStudyWriteLockArchitectureTestspattern; the catalogue-coverage test (#3882). - Codex sessions may not have the Claude Code skills (DS coverage gap, unverified), so briefs and the DoD spell out every command instead of naming a skill.
3. Gate structure¶
3.1 Gate types¶
- Freeze gates fix a contract (ADR, DTOs, fake, conformance suite) so dependent slices can build against it. They change nothing users see.
- The M0 go/no-go sits between S0 and F1a (§4.4).
- Ship gates decide whether a release may be activated for pilots. Their weight depends on the release tier (§7).
- Activation steps are production enablement per release (§8.6) and G-NOTIF per environment and notification kind family (§3.5).
- Programme gates are G-GA, G-ADOPT per adoption wave and G-RETIRE (§3.7).
Every gate has one dossier (§2.7) and is a re-plan point (§5.6).
3.2 G0 plan approval and operating model¶
| Item | Content |
|---|---|
| Freezes | The package as amended in round 2; this operating model; the five stream briefs; the decision calendar |
| Entry | Step 0 merged: the owner ledger, the package and the research inputs on main as one docs-only PR (D1-05; met: PR #3617 merged on 3 October 2026, f5318074d) |
| Exit evidence | Chris's approval (not yet given); D1-02 to D1-09 answered (met on 3 October, with D1-01 decided earlier; decision register §1.13); the Q-03 catalogue subset and D4-18's mapping part answered; tester panel named (D1-06 approved its shape; the names are still needed); joint sequencing with #3961 agreed (met: D1-02, §15); a direction for #3987 (met: activate, D1-03) and the date for its activation (still to be set); PR dispositions recorded (QM v2 and #2224 harvest-and-close, already decided; the dormant schema and profile PRs; #2469; the notification merge train, ordered by D1-09, with the #3965 restack subject to the stack owner); the G0 dossier |
| Authorises (D1-04) | S0 (eight slices, §4.2); the M0 skeleton (§4.3); R1b (#3964 merged); R1a's audit, browse and preview slices; prototypes for U1, U13 to U15, U19 and U26, and the other W0 validations in UX strategy §11; the F1a, F1b, F1c and C15 v2 ADR drafts (docs only); the presence owner's baseline docs PR (RT-27) |
| Signs | Chris |
3.3 F1 split into F1a, F1b and F1c¶
R0 needs only the engine contracts, the inventory and the storage basics (plan §5.2, R0's critical path), yet the single F1 held it behind the catalogue, IA, copy, AF2 seams, the Dockview amendment and five owner sign-offs (DS-06). F1 splits into three gates that can pass in any order after M0. R0 and R2a's backend wait only for F1a.
| Gate | Freezes | Entry | Exit evidence | Gates which work |
|---|---|---|---|---|
| F1a Engine contracts | C1, C2, C3, C5, C16; C18 (transactions, concurrency, idempotency) and C19 (durable effects and events), see consistency model; the storage ADR (E15) with the Study canonical summary; E20 as a form-keyed projection with per-reviewer markers (RT-06); drafts with the tab lease held by a stable tab ID (E21, RT-10); E25 settled on M0 evidence, with no per-project document in interactive transactions; E27; the canonical command ledger replacing E35; C4's definitions part (identity, content versions, composition, system-question snapshots E24, the applicability specification E23); the StageSettingsVersion envelope (DS-21); C7 identity and the claim contract v2 with hub, DTO and command versioning (RT-11); the writer and reader inventory, including tracking's writers and readers (RT-08) and the #3945 and #3947 Study writers (NS-08); from the domain model: the context map and fitness tests, the evidence aggregate boundary and collection map, the command catalogue and hosting rule, the glossary and naming ADR, the CanonicalScopes marker, the context-key and EntityTypeId identities, and the ScreeningOutcome facet shape |
M0 go; the sitting-2 decisions answered (§2.8): D2-01 to D2-16, D1-08's F1a part (start thresholds confirmed from M0 evidence), the F1a parts of D3-16, D4-06 and D4-12, and D3-17; X-ARCH-a met (#3973 merged, and #3985 merged or canonical repositories using isolated reads and non-upsert saves enforced by an architecture test, D1-02); #3987 decided (met on 3 October: activate, D1-03); the presence owner's baseline docs PR merged (RT-27) | ADRs approved in docs-only PRs; C# and TypeScript fakes and the conformance suites merged and green against fake and real providers; checklists run against materialized-stats.md, bulk-study-locks.md, repository-cache.md, the refreshed tracking contract and the AF2 binding rules; the presence and FEAT-024 checklists cover the claim contract, the form-keyed projection, the draft lease and the versioning (RT §5.1); exceptions ruled on |
R0; R2a backend; R2b backend against fakes; the AF2 per-project admission input; C1 and O1 design |
| F1b Catalogue and export disclosure | C10 catalogue and export disclosure, including the disclosure matrix and realtime presence as a disclosure channel (RT-14); C11 versions (previous-version exports); the C15 v2 capture contract and channel-aware disclosure hook (NS-01, NS-03, NS-12) | The Q-03 catalogue subset (answered at G0); D3-20 (sitting 3) | ADRs approved; the catalogue coverage test extended; the disclosure probe-suite skeleton merged (AC-ALL-19); checklists against the authorization plan and the notification stack's technical plan | R2a export slices; the C15 v2 implementation by the notification programme, after #3932 merges |
| F1c IA, copy and AF2 seams | C17 IA and the copy deck (typed message constants and guard spec); the AF2 extension points merged as code (step host, history panel slot, outdated and provenance markers, population context slot, outcome-schema entry, the versioned data-source port); the Dockview layout-contract amendment for the history panel; the shell per-project admission seam (DS-04) | The sitting-3 decisions answered (§2.8): D3-01 to D3-04, D3-06 and D3-08 (D3-15 before S0-7's browser projects count as evidence); every validation UX strategy §11 lists for F1c passed (among them U13 to U15 and U26 to U28) | Seam PRs merged by stream C with flags-off behaviour identical (AF2 and stage-review specs green); checklists against stage-review-layouts.md, the AF2 binding rules and the Material 3 technical plan |
R2a UI slices; R1a's default-entry slice |
3.4 Later freeze gates and lane freezes¶
Plan §6.1 stays the base. Each gate's entry also needs its sitting's decisions answered (§2.8); plan §6.1 names the ones each gate's freezes depend on. Round 2 adds:
| Gate | Added in round 2 |
|---|---|
| F2 Publication | Two-phase publication in which publication writes no evidence (D2-01, D2-10, D2-11); usage families as new FEAT-024 families by a technical-plan amendment, with FEAT-024's new-family onboarding contract landed before F2 (MS-02, MS-14); C15 recorded fan-out available before R2c's notices (NS-01) |
| F3 Workflow | The Stage aggregate and settings placement; R3c's readiness source decided (the completion definition extracted from #3939, DS-03, unless #3939 has merged under programme integration's X-BATCH criteria); the remaining eligibility slices absorbed into R3a's slice list (D3-09); allocation choices (D3-13); the production claims route (D3-16); shared-form tracking rules (D3-18, D3-19); X-ARCH-d (#3979, #3980) scheduled before R3a's build; X-STATS-c (target-aware classification) scheduled |
| F4 Reconciliation | X-RECLAIM: the reconciliation-task editor claim, frozen in C9 and C7 and working with tracking off (RT-01); shared gold (D2-09); conversations rebound to the task only if #3944 and #3965 have merged (DS-22, NS §4.3) |
| F5 Profiles | Profile-grain screening statistics: new FEAT-024 families at F5 or served live for R3b pilots (D3-10c, MS-08) |
| F6a, F6b | No change beyond the tier rules |
| F-P, F-C, F-O, F-A | F-P adds X-IMPORT and the P1 and P2 hooks for the #3945 and #3947 writers (NS-08); F-A adds X-AUTH-RESOLVER for allocation reviewer validity |
3.5 G-NOTIF notification enablement¶
G-NOTIF is a new activation gate (NS-04; D3-21). Notifications stay off outside the e2e stack and Mailpit until Chris passes it for an environment and a kind family. Evidence:
- X-NOTIF met: #3932 to #3943 merged with flags off, after the merge train in §11.9.
- Per-project notification admission (an R0 admission scope, or an interim registry before R0 exists), checked at capture for every kind.
- An operator delivery halt that pauses dispatch without cancelling it.
- Inbox reads available whenever saved items exist, whatever the capture flag.
- The declared
notificationEmailtonotificationInboxdependency. - Disclosure fixtures per kind, channel and role (AC-ALL-22); the enablement criteria (AC-ALL-29).
- For the publication notices family, the flood controls in NS-13, in place before R2c's notices are enabled.
- Staging and preview overrides only with Chris's approval, recorded in the flag audit comment; email kept in Mailpit. Evidence never relies on runtime overrides while #3975 resets them (X-ARCH-c).
Notifications are never a release dependency: feature-owned queues carry the confirmed obligations with every notification flag off (A-07).
3.6 Implementation authorisation per gate¶
Chris agreed on 3 October (D1-04): passing a gate authorises the slices its dossier lists. Authorisation covers building and merging dark behind flags. It never covers production enablement, production data operations, adoption waves or GitOps production values, which keep their own approvals.
| Gate passed | Slices authorised |
|---|---|
| G0 | S0-1 to S0-8; M0-1 to M0-5; R1b; R1a's audit, browse and preview; the W0 prototypes; the F1a–F1c and C15 v2 ADR drafts; the RT-27 docs PR |
| M0 go | F1a ADRs may be finalised (docs only) |
| F1a | R0 slices; R2a backend slices; R2b backend against fakes; the AF2 per-project admission input |
| F1b | R2a export slices |
| F1c | R2a UI slices; the shell per-project admission slice; R1a's default-entry slice behind its flag |
| F2 | R2c slices, including the staged publication flow |
| F3 | R3a slices, including the absorbed eligibility slices (D3-09) and the eligibility per-project admission slice; R3c design |
| F4 | R4a slices, including the task editor claim |
| F5 | R3b slices; R4p design |
| F6a, F6b | R5a; R5b |
| F-P, F-C, F-O, F-A | P1 and P2; C1 and C2; O1 and O2's build (O2 execution separately); AL1 |
3.7 Programme gates¶
G-GA keeps AC-GA-01 to AC-GA-05 and adds: an opt-in production pilot per release family before GA (D1-07, approved on 3 October); and the production chains in §6.3 met: the statistics chain (D1-03 chose activation, so the freeze path is not taken), X-ELIG, AF2 and the redesigned shell on for every new project, and X-CLAIMS or D3-16 option ©. G-ADOPT and G-RETIRE are unchanged.
4. S0 scaffolding release and M0 walking skeleton¶
4.1 Why enabling work comes first¶
The plan's parallel lanes depend on enabling work it never scheduled: a walking skeleton; a
cross-language fixture harness; a home for fakes, including TypeScript fakes behind AF2's
persistence port; a benchmark harness with a recorded baseline (round 1's AC-R2a-19 cited a
"today's session-submit p95" that exists nowhere, and the existing write benchmarks cover screening
only; AC-R2a-19 is now the canonical write gate, AC-ALL-26); and seed scaffolding (DS-08). The riskiest assumption, the cost of a canonical commit, was not
tested first, though FEAT-024's transactional path already fails its write gate by 46% to 1,283%
on an idle host and its fold path is a provisional fail
(docs/features/materialized-project-statistics/STATUS.md, "Performance and rollout gates"). M0
was also to run "in a scratch worktree" while F1 needed its conformance suite and fakes merged.
This section corrects that contradiction.
4.2 S0 slices¶
S0 is a T3 release with no user value: eight PRs, merged dark. Its criteria are AC-S0-01 to AC-S0-07 in the acceptance criteria.
| # | Slice | Main files (indicative) | Red-first tests | Criteria and items | Needed by | Review tier |
|---|---|---|---|---|---|---|
| S0-1 | Canonical module skeleton: an explicit DI module registered in the API and PM hosts (no convention scan, following #3961's direction); placeholder controllers answering the typed "feature unavailable" result behind stream A's kill switch; a startup test asserting key singleton identities; an architecture-test skeleton (new canonical code in new files; canonical repositories never read through RepositoryCache); new projects added to today's dependency maps |
New canonical folders; host registration only; docs/architecture/dependency-map.yaml |
Host starts with the module; flag off gives the typed refusal; singleton identity test | AC-S0-01 | M0 | Supervised |
| S0-2 | Fixture corpus: versioned JSON with a schema check, loaders for xUnit theories and Vitest describe.each, a differential runner (.NET against AF2 evaluators); FX-PRISMA-01 to 08 inputs and per-release assertion files |
src/libs/testing/SyRF.Testing.Common/; web test utilities |
One corpus file loads identically in both runners | AC-S0-02; E99 | M0, R2a | Delegated |
| S0-3 | Baseline benchmark arm on FEAT-024's environment-gated pattern: today's session submit and screening save on the RV-DS tiers (D1-08: 50, 340 and 2,023 questions); cells of 1, 2, 5 and 10 reviewers, same and different study; 20 warm-up and 200 recorded iterations; idle host; report with commit, dataset and host | src/libs/project-management/SyRF.ProjectManagement.Mongo.Data.Tests/ProjectStatistics/BenchmarkEnvironment.cs pattern |
Skips without its environment variable; a counting run asserts the cells | AC-S0-03; E98 | M0 thresholds | Delegated; Chris reads the report |
| S0-4 | Seed-if-absent job: additive, idempotent, keyed by fixed GUIDs, ready to create canonical seed projects through canonical commands once R0 and R2a exist | PM seeding | A second run creates nothing; legacy seeding unchanged | AC-S0-06; E97; D3-14 | R2a's seed project | Delegated |
| S0-5 | STATUS ledger (§14.1); release-brief, slice-brief, gate-dossier and acceptance-record templates; the traceability file and its docs-CI check; the PR template's programme section (§13.4); the ADR block (§11.8) | docs/features/integrated-review/ (home settled at step 0); .github/pull_request_template.md |
docs/scripts/validate-docs.sh --skip-indexes passes; the traceability check fails on an unknown criterion ID |
AC-S0-04, AC-S0-07; E76, E94 | Every later slice | Delegated |
| S0-6 | Flags and kill switches registered once: five stream kill switches and R0's admission flag, default off, with regenerated outputs, catalogue counts and consumer-manifest entries | src/charts/syrf-common/env-mapping.yaml and its generated files; the runtime flag catalogue; docs/planning/feature-flag-overhaul/consumer-manifest.json |
Flag count tests; flags-off behaviour identical | AC-S0-01; E77 | S0-1, M0, R0 | Supervised |
| S0-7 | Acceptance tooling, part 1: the e2e persona set; axe and screenshot helpers inside journey specs; the excluded-spec check script; Firefox and WebKit smoke projects; the native-drag guard spec | e2e/setup/auth.setup.ts, e2e/helpers/constants.ts, e2e/playwright.config.ts |
Each persona logs in; a seeded axe violation fails | AC-S0-05; E85, E95, E96; D3-15 | R1b (personas, axe, screenshots); R2a (Firefox, WebKit) | Delegated |
| S0-8 | Deterministic concurrency barrier harness on MongoDbReplicaSetTestFixture (named points such as "after read, before commit") and the mixed-version harness skeleton |
src/libs/testing/SyRF.Testing.Common/Fixtures/ |
A forced race gives the loser its typed conflict; the harness starts two image versions on one database | AC-S0-05; E95, E96 | M0 (barriers), R0 (mixed versions) | Supervised |
Dependencies: S0-5 and S0-6 first; S0-1 after S0-6; S0-4 after S0-1; S0-2, S0-3, S0-7 and S0-8 in parallel from the start. S0-3 runs in the second Bramble window (§10.5).
4.3 M0 walking skeleton¶
One synthetic 200-question form on one stage travels the whole path:
- a canonical command with compare-and-set on the head and the canonical command ledger;
- the Study canonical summary, written through FEAT-024's source-write seam in its projection-only shape, which emits nothing, a classified delta or an invalidation intent as the active statistics path requires (MS-06; until fold protocol 5, canonical commits carry intents only, MS-15);
- a draft with lease, etag and per-holder write sequence, consumed atomically by Save;
- the dark AF2 adapter, behind stream C's kill switch;
- an export of current and previous versions.
If FEAT-024's seam refactor has not merged, M0 uses a test double that reproduces both statistics paths' command lists, and the M0 report says so.
| # | Slice | Stream | Review tier |
|---|---|---|---|
| M0-1 | Engine spike: OrdinaryAnswer and ScreeningDecision through one command handler, head CAS and the command ledger; conformance suite and C# fake | A | Supervised |
| M0-2 | Study projection through the seam in transactional and fold modes; a command-budget test pinning the commit shape | A, with the FEAT-024 checklist | Supervised |
| M0-3 | Draft record with lease and etag, consumed by Save; the TypeScript fake behind AF2's persistence port | A and C | Supervised |
| M0-4 | Dark AF2 adapter renders the form and saves through the API | C | Supervised |
| M0-5 | Export of current and previous versions; the benchmark arm run in a Bramble window; the M0 report and the storage ADR (docs-only PR) | A and L17 | Delegated; the ADR supervised |
What merges: the conformance suite, both fakes, the barrier-harness use, the benchmark arm, the storage ADR and the M0 report. Spike handler code may be discarded; if kept, it stays behind stream A's kill switch and must meet F1a's contract before any release relies on it. Its criteria are AC-M0-01 to AC-M0-08.
4.4 Go and no-go thresholds¶
Set at G0 from the S0 baseline (D1-08); the acceptance criteria rows AC-M0-02 and AC-ALL-26 are authoritative and these values mirror them. D1-08's start thresholds (the exhausted-submission cells and the Save and Complete start values) were approved on 3 October and apply now; F1a confirms them from M0 evidence.
| Measure | Go threshold (PROPOSAL) |
Method |
|---|---|---|
| Engine-caused exhausted submissions | Zero at 1, 2, 5 and 10 reviewers, same-study and different-study cells, with the fold worker (where enabled), claims and one background sweep running (the ADR-019 gate (b) shape) | M0 benchmark arm |
| Statistics-caused conflicts | Zero | The same arm, with FEAT-024's attribution rules |
| Save and Complete p95 on a 200-question form | Start values Save at most 150 ms and Complete at most 300 ms, confirmed after M0; also reported against the S0 legacy baseline per RV-DS tier | The same arm on an idle host (load per CPU at most 0.5) |
| Transaction duration | p99 at most 2 s, maximum at most 10 s (MongoDB's default transaction lifetime is 60 s) | The same arm |
| Document size | The Study document at most 50% of 16 MiB at the maximum tier; the maximum tier also sets the E28 ceiling (D2-16) | Size probe in the arm |
| Commit shape | The command list per Save and Complete pinned by CanonicalCommitCommandBudgetTests |
Test |
| Correctness | AC-M0-01, AC-M0-05 and AC-M0-06 green on fake and real providers; the walking-skeleton journey green in the local e2e stack | C, I, E |
4.5 Outcomes¶
- Go: every threshold met. The F1a ADRs freeze.
- Conditional: latency missed while exhaustion is zero and size is within limits. Chris chooses between a lower E28 ceiling (D2-16) and rework, re-measured in the next Bramble window.
- No-go: exhaustion or a size failure. Storage is re-planned before F1a (the canonical-summary default against legacy-shaped stub sessions, brief §1.3), and E25 is revisited.
4.6 Walking-skeleton rule for every release¶
QM v2 completed its milestones against fakes and never wired its UI to its API, leaving a dormant
738-file stack (PH-11; docs/planning/qm-v2-context/README.md). So:
- Each release's first code slice is a thin end-to-end path behind its flag, through the real provider wherever one exists.
- No release merges more than three slices, or spends more than ten working days, against fakes
alone before an integration slice merges against the real provider (
PROPOSAL). - Conformance suites run against both the fake and the real provider; a divergence fails the build.
- A risk row records this in plan §10.
5. Ready queue and WIP limits¶
5.1 Item states¶
- Slices: Blocked (a predecessor, freeze or decision is missing) → Ready (DoR met, §12.1) → Claimed (§11.5) → Building → In review → Merged dark.
- Releases: Building → Release candidate recorded (§8.3) → In acceptance → Shipped (ship gate passed) → Enabled in production (§8.6).
5.2 Start and ship rules¶
- A slice is build-ready when its release's freeze gate has passed, the contracts it consumes are frozen with their fakes merged, and its DoR holds.
- A release is ship-ready when its graph predecessors have shipped, its joins hold and its ship gate passes.
- Production enablement is separate: it needs the release's production chain (§6.3) and Chris's approval.
- Windows no longer gate anything (DS-05). They survive only as the illustration in §5.7.
5.3 Conditions per release¶
Brackets the windows hid are now explicit. Join names follow programme integration §12.
| Release | Build may start | Ship gate may pass | Production enablement also needs |
|---|---|---|---|
| S0 | G0 | Slices merged | Nothing (no user value) |
| M0 | S0-1, S0-2, S0-3, S0-8 | Go/no-go (§4.4) | Not applicable |
| R0 | F1a; the PM consumer-guard slice also needs X-ARCH-b (#3986 decided) | Staging rehearsal (T1) with the mixed-version harness | One production promotion cycle and seven days without deserialisation errors before any production canonical write (§6.6) |
| R1a | G0 for audit, browse and preview; canonical apply moves to R2a (DS-20) | Staging acceptance | The new editor becomes the default entry point once C17's two modes exist (F1c) |
| R1b | G0 (#3964 merged) | Staging acceptance | Explanations only when X-AUTH-WP9 lands |
| R1c | X-AUTH-SCHEMA design; #3941 merged (X-NOTIF step 3) | X-AUTH-SCHEMA; X-AUTH-ENFORCE or parity tests; X-AUTH-WP9 | Per environment after the authorization joins |
| R1d | R1c; Q-03 | R1c shipped | As R1c |
| R2a | Backend at F1a; exports at F1b; UI at F1c; FEAT-024's seam refactor before the Study-coupling slice | R0's staging rehearsal passed | R0's production soak; X-AF2 and X-SHELL admission slices; D1-07 |
| R2b | R2a backend; claim contract v2 (F1a) | R2a shipped; R2b's floor-step rehearsal | X-CLAIMS (D3-16); X-STATS-c before any materialised consumer serves a canonical project (MS-07) |
| R2c | F2; R2a | R2a shipped; X-STATS-a for the staging pilot | Q-31(b) for named pilots; X-STATS-b1 to b7 beyond them (D1-03 chose activation, not freeze) |
| R2d | R2a; R2c fakes | R2c shipped | As R2a |
| R3a | F3; R2a; X-ARCH-d (#3979, #3980); the absorbed eligibility slices (D3-09) | R2a shipped; R0's screening floor step | X-ELIG or the eligibility per-project admission slice; X-CLAIMS for reservation admission |
| R3b | F5; R3a fakes | R3a and R2c shipped | Profile-grain statistics served live until FEAT-024's families exist (D3-10c) |
| R3c | R3a | R3a shipped; readiness source decided at F3 (§3.4) | As R3a |
| R3d | R3b fakes; R1a | R3b, R2c and R1a shipped | As R3a |
| R4a | F4; R2b fakes | R2b shipped (not R3a) | X-RECLAIM is internal and frozen at F4; conversation work only after #3944 and #3965 merge |
| R4p | F4 and F5 | R3b and R4a shipped | As R4a |
| R4b | R4a fakes | R4a shipped | Notices only after X-NOTIF and G-NOTIF |
| R4c | O1, R4a | X-AF2-PR9; X-PDFTOOLS | As R4a |
| R5a | F6a; R4a fakes | R4a shipped | Per admitted project |
| R5c | R4a; Q-04, Q-16; E9; U29 | R4a shipped | Per admitted project |
| R5b | F6b | P1, P2, R3b and R4p shipped | Per admitted project |
| P1 | F-P; X-DEL design; X-IMPORT | R0's Study floor step | Per admitted project |
| P2 | P1 | P1 shipped; the reviewed-record part after R3b | Per admitted project |
| C1 | F-C; R2a | R2a shipped; a floor step if C1 adds embedded fields | Per admitted project |
| C2 | C1; Q-18 | C1 shipped | Per admitted project |
| O1 | F-O; R2a; X-PDFTOOLS (or O1's scope states the gap) | R2a shipped; a floor step if O1 adds embedded fields | Per admitted project |
| O2 | O1; Q-05 | O1 shipped; P1 identity gate | Separate execution approval |
| AL1 | F-A; R2b fakes; X-AUTH-RESOLVER | R2b shipped | Per admitted project |
| GA | Not applicable | G-GA (§3.7) | Not applicable |
5.4 WIP limits¶
| Scope | Limit (PROPOSAL) |
|---|---|
| Per stream | At most two releases building and one in acceptance; at most four open non-draft PRs |
| Programme-wide | At most three releases in acceptance; at most eight items waiting on Chris (decisions, supervised-PR summaries, dossiers) |
| Bramble | At most one exclusive window a week for this programme |
Rules:
- Finish before starting. A stream may not claim a new release while one of its releases in acceptance waits only on the stream's own work.
- Weekly rebase or close. At the weekly review, conflicting PRs older than seven days are rebased or closed with a harvest note. Without this, about 20 in-scope PRs are already conflicting or stale (inventory §4); on 3 October, 18 of 132 open repository PRs were conflicting.
5.5 Queue order¶
- Items on the GA path (§6.1) and items that unblock a gate.
- Early-value items (§6.7).
- Items that unblock the most other items.
- Tails: P1 → P2 → R5b; O1 → R4c; R4a → R5a and R5c; C1 → C2; R2b → AL1; R1c → R1d.
Ties go to the oldest ready item. Items waiting on Chris appear in the digest with their age.
5.6 Re-plan triggers¶
Re-plan at every freeze gate, and whenever:
- an external chain step slips by more than two weeks against its forecast;
-
3987's activation (D1-03, decided 3 October) is reversed to "freeze", so GA statistics would¶
follow D1-03's alternative; - WIP exceeds a limit in two consecutive weekly digests;
- a decision waits on Chris for more than 10 days after its gate's dossier is ready;
- M0 is conditional or no-go;
- PR Tests queue time p90 exceeds 30 minutes for a week;
- a booked Bramble window is lost twice.
5.7 Illustrative timeline¶
The windows below show a plausible order and overlap if every item became ready as early as its conditions allow. They are not a schedule, carry no dates and gate nothing.
| Window | Typically opens when | Work |
|---|---|---|
| Before G0 | Package submitted | Batch D1 answered (all nine by 3 October; decision register §1.13); step 0 merged the package to main (D1-05; PR #3617 merged on 3 October 2026, f5318074d); #3964 has already merged (D1-01, 3 October); the tester names (D1-06) and the date for #3987's activation (D1-03) still to be set; Chris approves G0. Nothing is built under this plan before G0. |
| W0 | G0 | S0; the M0 skeleton; R1b; R1a's audit, browse and preview; #3985 and #3973 (architecture review); F1a, F1b, F1c and C15 v2 ADR drafts; the presence owner's docs PR; W0 validations; the notification merge train; Bramble: gate (b) rerun, then the S0 baseline |
| W1 | M0 go and F1a | R0 build and staging rehearsal; R2a and R2b backends against fakes; F1b and F1c; C1 and O1 design; F2 work with FEAT-024; F3 work; R1a and R1b ship |
| W2 | R0's staging rehearsal, F1b and F1c | R2a UI on merged seams; R2a acceptance and staging pilot; R0's production promotion and soak; the X-AF2 and X-SHELL admission slices; R2c [F2]; R3a [F3, X-ARCH-d]; P1 [F-P, X-IMPORT]; F4 and F5 work |
| W3 | R2a shipped | R2b ships; R2c ships (staging pilot under X-STATS-a; production pilots under Q-31(b)); R2a opt-in production pilot [D1-07]; C1 and O1 ship; R4a [F4] and R3b [F5] build; R3a acceptance |
| W4 | R2b shipped and F4 passed | R4a ships, not waiting for R3a; R2d [R2c]; AL1 [F-A]; R3a ships; R3c builds; R4b builds |
| W5 | R3a and R2c shipped | R3b and R3c ship; R4b, R5a [F6a] and R5c [Q-04, Q-16] ship; P2 and C2 build |
| W6 | R3b and R4a shipped | R4p and R3d ship; P2 ships; R4c [O1, X-AF2-PR9]; R5b builds [F6b] |
| W7 | R4p shipped; GA criteria | R5b ships; GA readiness review; production pilots per family (D1-07) |
| W8 | GA | R6 adoption waves, each through G-ADOPT; R7 after the waves (G-RETIRE) |
| Floating | External gates clear | R1c; R1d; O2 execution only with separate approval |
6. Revised critical path and binding constraints¶
6.1 The GA path¶
GA (the canonical path by default for new projects) cannot pass before the latest of six chains. The plan's chain left out R2d, R3c and R3d and every production chain (DS-03).
flowchart LR
G0[G0] --> S0[S0 scaffolding]
G0 --> M0[M0 walking skeleton]
S0 --> M0
XA[["X-ARCH-a: #3985 and #3973"]] -.-> F1a
M0 --> F1a{F1a engine contracts}
F1a --> R0[R0 staging rehearsal]
F1b{F1b catalogue and disclosure} --> R2a
F1c{F1c IA, copy, AF2 seams} --> R2a
R0 --> R2a[R2a]
R2a --> R2b[R2b]
R2b --> R4a[R4a]
F4{F4} --> R4a
R2a --> R2c[R2c]
F2{F2} --> R2c
R2c --> R2d[R2d]
R2a --> R3a[R3a]
F3{F3} --> R3a
R3a --> R3b[R3b]
R2c --> R3b
F5{F5} --> R3b
R3a --> R3c[R3c]
R3b --> R3d[R3d]
R1a[R1a] --> R3d
R3b --> R4p[R4p]
R4a --> R4p
R2d --> GA((GA))
R3c --> GA
R3d --> GA
R4p --> GA
XS[["X-STATS-b1 to b7 (D1-03: activate)"]] -.-> GA
XE[[X-ELIG]] -.-> GA
XF[["X-AF2 and X-SHELL for every new project"]] -.-> GA
XC[["X-CLAIMS, or D3-16 option c"]] -.-> GA
XP[["R0 production soak and pilots per family"]] -.-> GA
- Internal chain. G0 → S0 and M0 → F1a → R0 (staging rehearsal) → R2a (backend at F1a, exports at F1b, UI at F1c) → three branches: R2b → R4a [F4] → R4p; R2c [F2] → R2d; R3a [F3] → R3b [F5, R2c] → R3c, R3d [R1a] and R4p [R4a] → GA readiness (coexistence UI, guided-setup parity, help pages and the "what changed" page).
- Statistics chain (§6.2).
- Eligibility chain: X-ELIG (§6.3).
- Admission chain: X-AF2 and X-SHELL, now plan-owned slices (§6.3).
- Claims chain: X-CLAIMS (§6.3). E6, the dedicated reconciliation task claim, now applies always (RT-01): it becomes X-RECLAIM, internal to R4a and frozen at F4, and leaves the external list.
- Approver throughput (§6.4).
6.2 Statistics chain¶
FEAT-024 production readiness is a chain of seven steps, not one gate (MS-01). Programme integration §7.2 holds the authoritative wording and owners.
| Step | What | State on 3 October | Depends on |
|---|---|---|---|
| X-STATS-b1 | Gate (b) passes on an idle host | Provisional fail on a loaded host; Bramble rerun pending | The first Bramble window (§10.5) |
| X-STATS-b2 | 7-day soak (#3510, driver #3952) | Not started; runs in the isolated e2e stack on Bramble | b1; Bramble |
| X-STATS-b3 | Production pending index built in an approved window | Not built in any environment | b1 |
| X-STATS-b4 | Production rollout approved, lifting the in-code refusal | Refused in code | b1 to b3; Chris |
| X-STATS-b5 | Production per-project eligibility (#3524, built after C16 freezes) | Planned, not built | F1a |
| X-STATS-b6 | The usage family built (new families and scope kinds by a FEAT-024 technical-plan amendment) | Does not exist | F2 |
| X-STATS-b7 | The usage family proven on staging under X-STATS-a | Not started | b6 |
Consequences:
- Two steps (b5, b6) depend on this plan's own gates, so the chain cannot finish before F2.
- Under Q-31 (decided), named production pilots may count authoritatively at the protected boundary when gate (b) has not passed. Given the chain's length, R2c's first production pilots are expected to run that way: the Q-31(b) path is the designed first pilot path, and the materialised family is a swap-in behind the same interface (MS-01).
- GA needs the full chain: Chris chose to activate #3987's families (D1-03, 3 October), so Q-31(b) is not extended to GA.
- Preview pilots use the Q-31(b) path, and seed project 0102, FEAT-024's staging pilot, stays out of R2a to R3a pilots until the seam fixture passes (D3-10b, D3-10d).
6.3 Other production chains and joins¶
Q-25's per-flag routes stand. Its tracking line rested on a false premise and is corrected (brief §2.1); the production claims route goes to Chris as D3-16.
| Join | Needed for | Owner | Evidence | What changed in round 2 |
|---|---|---|---|---|
| X-ELIG | R3a production admission; GA | Eligibility programme (paused 25 September) | The items in programme integration §5.2; an authorised count-only reservation check per environment (RT-23) | Remaining slices absorbed into R3a's slice list if Chris agrees (D3-09); the eligibility per-project admission slice is plan-owned (DS-04) |
| X-AF2 and X-SHELL | Every production pilot of reviewer UI; GA | Plan-owned slices reading R0's admission service (stream C), checked against the AF2 rules | AF2 per-project admission with R0 or R2a (the AF2 gate is a pure-function input, annotation-form-v2-eligibility.ts); shell per-project admission with R2a |
Were external joins with no slice (DS-04). GA needs both on for every new project, environment-wide or by an admission rule that admits all new projects |
| X-CLAIMS | R2b claim behaviour, R3a reservation admission and any capacity promise, in production; GA | Presence owner with the FEAT-024 owner | The route chosen in D3-16 built; API and PM switched together; load and failover runs on Bramble (AC-T-03 to AC-T-07); the orphan-claim backstop (AC-T-06, RT-24); E2E in both tracking modes | New (RT-02, RT-03): claims and capacity guards exist only with tracking on, which is off in every deployed environment |
| X-RECLAIM | R4a in every environment | Stream D with the presence checklist; frozen in C9 and C7 at F4 | AC-R4a-36 to 39 | Replaces X-TRACK; internal, so no longer an external join (RT-01) |
| X-NOTIF | Notices only; R1c also needs #3941; R4a's conversation work needs #3944 and #3965 | Notification programme | Met when #3932 to #3943 are merged with flags off (NS §4.3) | Definition added (NS-17); dashed edges to R1c, R2c, R3c, R4a and R4b (NS-09) |
| G-NOTIF | Any notification enablement outside e2e and Mailpit | Chris | §3.5 | New (NS-04) |
| X-STATS-c | R2b pilots on allowlisted projects; R3a | FEAT-024 (with #3979) | Target-aware classification merged with its reconciliation plan executed (MS-07) | New |
| X-ARCH-a to d | F1a (a); R0 (b, c); R3a (d) | Architecture-review programme | §15.2 | New (DS-02) |
| X-BATCH | R3c readiness reuse; any batch enablement | Batches programme | Programme integration §4.2 | R3c needs only the completion definition, decided at F3 (DS-03) |
| X-AUTH-*, X-AF2-PR9, X-PDFTOOLS, X-DEL, X-IMPORT | R1c and AL1; R4c; O1 and R4c; P1; P1 and P2 | Their programmes | Programme integration §12 | Tails, off the GA path |
6.4 Approver throughput¶
Items that need Chris: about 91 open decisions (Batch B 14, Batch C 15, Batch D 62: 71 questions less the nine decided D1 questions, so no D1 question is open), 14 freeze gates plus the M0 go/no-go, 27 ship gates, G-NOTIF per environment and kind family, production enablement per release, G-GA, and G-ADOPT per wave. §16.2 budgets them at about 40 to 45 hours plus about an hour a week. Under A-35 (about four hours a week of programme time), the queue on his desk, not agent build time, sets the pace.
6.5 The binding constraint¶
In likely order:
- Chris's decision and acceptance throughput. This is the binding constraint.
- The statistics chain with #3987, which Chris chose to activate (D1-03).
- X-ELIG, in a paused programme.
- Tester availability (D1-06).
- X-CLAIMS: the reviewer-mode transition (M15) has no owner.
- CI host and Bramble capacity, managed by §10.
Engineering throughput is not among them (A-36). The model therefore spends agent capacity to save approver time: dossiers, decision sittings, tiers, verifiers and a weekly digest.
6.6 R0 soak per environment¶
- Staging. R0 merges and auto-promotes to staging. A T1 rehearsal, in an approved promotion-pause window, rolls the images back to the recorded minimum (R0 or later; binaries below R0 are not a rollback target once canonical data exists) with canonical test data present; the mixed-version harness and R0's floor rows (AC-R0-01, 05, 06, 09 and 15) pass. This gates staging canonical writes, that is R2a's staging pilot.
- Production. One production promotion cycle of the R0 images through the normal
requires-reviewpromotion PR (which since #3971 waits formain's integration tests), then seven days (PROPOSAL) without deserialisation errors from the extended types in production logs. This gates the first production canonical write, that is the first production admission. - R2a builds and merges dark meanwhile; neither soak holds R2a's build.
6.7 Early-value track¶
-
3964 (D1-01; merged on 3 October), then R1b's Members & groups visibility, straight after G0.¶
- R1a's template browse and preview, through the import-target port (DS-20).
- R2a opt-in production pilots (D1-07, approved on 3 October) once R0's production soak and the X-AF2 and X-SHELL slices hold.
- R4a straight after R2b and F4, not after R3a. The reconciler form is the largest visible gap (plan §5.6).
- Defect fixes from the inventory, if Chris triages them in: the "completed sessions only" export fix (parked in R5a), the reconciliation-payload identity leak and export unmasking (inventory §7). These are follow-up candidates, not plan scope (brief §1.20).
7. Release tiers T1, T2 and T3¶
7.1 Definitions¶
This merges DS's heavy, standard and light classes with review AC's T1, T2 and T3:
- T1 heavy: the first writer of a new persisted shape or authority on a hot path, or a data migration.
- T2 standard: writes canonical data through writers a T1 release has proven, adds an aggregate off the hot path, or adds UI over canonical data.
- T3 light: read-only or derived views, exports with no new persisted state, or scaffolding.
Floor-step rule: a release that carries an R0 floor step (R2b's form claims, P1's Study root fields, R3a's screening fields, and C1 or O1 if they add embedded fields) gets a staging rehearsal for that step, whatever its tier.
7.2 Assignment¶
The assignment matches the acceptance criteria release headers and is confirmed in each release-ready check.
| Tier | Releases |
|---|---|
| T1 | R0, R2a, R2c, R3a, R4a, P2, O2; GA, the R6 waves and R7 under their programme gates |
| T2 | R1a, R1b, R1c, R1d, R2b, R2d, R3b, R3c, R3d, R4p, R4b, R4c, P1, C1, O1, AL1 |
| T3 | S0, R5a, R5b, R5c, C2; X1 if D4-09 is approved |
Review tier is separate (§9). R1b to R1d are T2 releases whose authorization PRs are all supervised.
7.3 What each tier requires¶
| Requirement | T1 | T2 | T3 |
|---|---|---|---|
| Rollback | Staging image-rollback rehearsal in a promotion-pause window, with canonical data present, plus the mixed-version harness (AC-ALL-04 b and a) | The mixed-version harness when the release persists new data (AC-ALL-04 a); a staging rehearsal only for a floor step | Flags-off check; AC-ALL-04 recorded N/A when nothing persists |
| E2E | Per-spec local runs; CI smoke on PRs touching review flows; run:e2e-full once on the release candidate; affected flows in both tracking modes (AC-ALL-23) |
Per-spec local runs; CI smoke on PRs touching review flows; both tracking modes where claims or the workspace change | Per-spec local runs for the touched flows |
| User testing | Five named testers in a summative session (D1-06) | Three testers (five for R3d, AC-UX-07) | A walkthrough only; three testers if a user-testing task is listed |
| Benchmarks | A Bramble window for every named hot path the release touches (AC-ALL-09) | Only when a named hot path changes | None |
| Pilot | Staging pilot with pilot entry and exit criteria and minimum exposure; production only through §8.6 and D1-07 | Staging pilot | Staging smoke on the release candidate |
| Chris | Dossier and a 60-minute staging walkthrough | A 30-minute walkthrough | A summary read (about 15 minutes) |
| Design QA | Both tiers (§9.6) | Both tiers | Tier 1; tier 2 only for changed screens |
7.4 Tier rules¶
- A criterion with no subject (for example AC-ALL-07 and AC-ALL-08 for R0, which has no screen) is recorded N/A with its reason; it is never silently skipped (review AC-25).
- A row whose verification method needs tooling that does not exist yet cannot be marked passed (review AC-09). S0-7 and S0-8 deliver that tooling before the releases that need it; the acceptance criteria record each tool's "needed by" release.
- A stream lead may raise a release's tier, never lower it. Lowering needs Chris, in the dossier.
8. Merge criteria and activation criteria¶
8.1 Merge criteria on every PR¶
Every merge is deployed to staging automatically and can reach production at the next promotion, so continuous properties are checked on every PR, not once per release (review AC-03). The merge criteria are the M rows of acceptance criteria §2.1: AC-ALL-01 (flags off), AC-ALL-02 (legacy projects unchanged), AC-ALL-03 (capability tests for new endpoints), AC-ALL-05 (tests, CI green on the exact head, no new suppressions), AC-ALL-06 (docs and the flag decision), AC-ALL-10 (structured events and typed outcomes), AC-ALL-14 to AC-ALL-16 (the flags-off spec set when a listed flow is touched, no excluded spec for changed code, tests tagged with criterion IDs), AC-ALL-28 (no debug component on reviewer routes) and the M rows of the UI standard (UI-1, UI-3, the UI-4 token checks, UI-7, UI-9, UI-10 and UI-11). They are the slice DoD (§12.2).
8.2 Activation criteria on a release candidate¶
Everything else is evaluated once per release on a recorded release candidate: the release's own
criteria, its conformance row (AC-
8.3 Release-candidate record¶
| Field | Source |
|---|---|
| Main commit SHA | The commit the candidate was built from |
| Image references per service (API, PM, Quartz, Web, Identity) | Staging GitOps values ({version}-sha.{sha} tags), read when the candidate is recorded |
| GitOps revision; flag and admission snapshot | cluster-gitops staging values; the admission service's audit |
| Seeds and datasets | The seed-if-absent version; the benchmark dataset IDs |
| Runs | CI run URLs; e2e label run URLs; the Bramble report |
E78 captures these into the acceptance record.
8.4 Acceptance record¶
One file per release, docs/features/integrated-review/acceptance/<release>.md (the home is
settled at step 0). It has one row per criterion (ID, status, evidence link on the recorded
candidate, N/A reason where relevant) and the human notes (who, when, which candidate). It is
generated from the traceability file where possible, committed before the ship gate, and checked
by the ship-gate verifier (§9.5).
8.5 Staging promotion pause windows¶
Staging redeploys on every merge to main, so an image-rollback rehearsal needs a fixed staging
for its duration. For T1 rehearsals and floor steps:
- Chris approves each window in the digest at least 48 hours ahead; at most one window a week, at most four hours, outside peak merge hours.
- Every programme is told through STATUS. Merges to
maincontinue; staging promotion resumes after the window with the queued images. - The pause mechanism (holding the auto-merge of staging promotion PRs, or an equivalent switch) is agreed with the cluster-gitops owner and tested once before R0's ship gate (E78). It has not been verified yet.
- Acceptance that tolerates a moving staging uses staging with the candidate SHAs recorded, or a preview environment pinned to the candidate.
8.6 Production enablement step¶
Every release that reaches production users has its own enablement step after its ship gate, with its own evidence (DS-04; acceptance criteria §4.34):
- The release's production chain is met (§6.3) and recorded in the dossier.
- For pilots: staging acceptance passed, R0's production soak complete and the X-AF2 and X-SHELL slices built (D1-07 answered "yes" on 3 October).
- Named pilot projects are admitted through R0's audited admin action, and nothing else is.
- User-guide pages drafted under
[TARGET - Phase N]markers are published, and the "what changed" entry is added (DS-25). - The production rollback is covered by the tier's rehearsal.
- Chris approves.
R1a's step makes the new question editor the default entry point once C17 defines its two modes. Environment-wide enablement of AF2, the redesigned shell and eligibility stays a GA prerequisite.
9. Review tiers¶
9.1 Supervised tier¶
/claude-review opuson the exact head of a non-draft PR targetingmain.- A fresh-context verifier (
pr-deep-analysis,cross-reviewfor high-stakes changes, or a fresh Opus session) reads the slice brief, the diff and the relevant rules files, runs the verifying commands, and posts a PASS or FAIL report with file:line evidence. - Chris reads the summary (the review verdict and the verifier report) before merge.
- One review round, then fix and merge. Second-order findings become follow-up issues. Stale docs for changed behaviour stay blocking.
- Merge only after
pr-review-settled.shreports settled on the current head and the bot's summary comment carries norequest changesverdict.
9.2 Delegated tier¶
- Default
/claude-review(Sonnet) on the exact head; the settled check; no unresolved threads; green checks. - Merged after Chris's
/approve, batched daily: D1-04, approved on 3 October, keeps his/approveon merges.
9.3 Which tier applies¶
A PR is supervised when it touches any of:
- the canonical engine, CAS, transactions, idempotency or canonical repositories;
- migrations, adoption, backfills or any data operation;
- authorization, permissions, blinding, disclosure or presence payloads;
- flags, kill switches or the admission service;
- contract ADRs, DTOs, fakes or conformance suites;
- FEAT-024 seams or pinned command budgets;
- claims, capacity guards or the claim contract;
- CI workflows or runner routing.
Everything else is delegated. Each stream brief lists the globs. A stream lead may raise a PR's
tier, never lower it. The list follows the readiness analysis's "supervise closely" column
(docs/planning/ai-development-readiness-analysis.md, Part 4).
9.4 Stacks and retargeting¶
/claude-review runs only on open, non-draft, same-repository PRs targeting the default branch,
and never re-runs automatically (.github/workflows/README.md, "Claude comment reviews"). So:
- stack depth is at most two;
- a PR is retargeted to
mainbefore review; after the retarget, mergemainand push so the required Test Summary check reports against the new base; - a conflicting PR runs no
pull_requestworkflows at all, somergeStateStatusis checked before an all-green status is believed.
The eight-deep notification stack is being unwound by its merge train (§11.9); it is not a pattern to copy.
9.5 Ship-gate verifier¶
At every ship gate a fresh-context verifier (AC-ALL-13):
- maps every criterion ID that applies to the release (its own rows, its conformance row and the AC-ALL, AC-UX and UI rows for its tier) to evidence on the recorded candidate, using the traceability file;
- checks invariants 1 to 12 across the release's PRs: each invariant the release touches has an executable check (INV-01 to INV-12) passing on the candidate;
- checks the acceptance record, the C16 compatibility ledger entry and the docs;
- confirms that no pending,
PROPOSALor conditional row was counted as passed; - lists the exceptions, each with a recommendation, for the dossier.
Chris reviews the exceptions, not the whole matrix.
9.6 Design QA tiers¶
UX strategy §13 owns the checklist; this is how it runs:
- Tier 1, on every UI PR, by agents: theme and contrast guards; the screenshot matrix at UI-6's widths; axe at named journey states; a keyboard journey transcript; state coverage; copy-deck compliance; the design-QA checklist against the handoff; and a second agent's review of that evidence.
- Tier 2, per release, by Chris: one staging walkthrough on the recorded candidate (dark mode is
reachable there because
themeToggleis on in staging), with the bundle of screens and the tier-1 evidence; per-PR preview acceptance only for new shared patterns and five high-risk surfaces (the publication flow, the reconciliation workspace, the stage designer, Members & groups and guided setup), if Chris agrees (D3-02). The rewritten A-24 records this. - Materially changed follows UX strategy §13.3: a new route, a new or changed shared pattern, a changed primary action or its placement, changed copy for a core verb, a changed layout at any UI-6 width, or a changed keyboard model or focus order.
10. CI and host budget¶
10.1 Measured capacity¶
| Host | What runs there | Measured on 3 October |
|---|---|---|
| Juniper (the agent host) | 13 listener services, juniper-01 to juniper-12 and juniper-syrf-tests-01 (the juniper-ci .NET and validation lanes and the 60-minute Claude review jobs); the agent sessions; other users |
48 threads; load average 17.1, 22.1 and 29.4 (1, 5 and 15 minutes) at 15:14 BST with about 80 logged-in sessions; root disk 79% used; 195 PR worktrees, 127 with web node_modules |
| pomegranate | pomegranate-01 to pomegranate-12: the Angular and Sonar lanes; pomegranate-01 runs the E2E perf and Bulk PDF entries (docs/how-to/juniper-runner-routing.md) |
Not re-measured here |
| Bramble (Chris's workstation) | bramble-01 and bramble-02 (native, no Docker), bramble-gpu-01, and the KVM guest bramble-e2e-vm-01, which runs both functional E2E shards and smoke |
FEAT-024's gate (b) rerun and 7-day soak are pending there |
PR Tests: among the last 60 completed runs, the 23 successful runs that executed product lanes (five minutes or longer) took a median 32 minutes (p90 39, maximum 44). Five of the 60 started more than 30 minutes after creation; run 37112268597 started 227 minutes after it was created. The .NET unit lane alone takes about 22 to 23 minutes against a 45-minute budget (#3886 tracks splitting it). Each E2E entry is a 45-minute job, and the full suite runs four entries two at a time.
10.2 Gating after #3971¶
3971 (merged on 3 October) makes a failed test stop publishing, tagging and promotion, and makes¶
the required Test Summary check fail closed. Per the owner decision recorded in the #3961
synthesis, main's integration tests block production promotion only. For this programme:
- a programme PR that breaks
mainnow stops staging promotion for everyone, so it is reverted first and fixed second; - R0's production promotion cycle (§6.6) waits for
main's integration lane to be green; - the merge criteria (§8.1) are what keep
mainpromotable.
10.3 Budget rules¶
- Conformance suites live in path-filtered test projects with a target of five minutes each on the
PR lane. A workflow change that adds path filters triggers the lanes it changes and runs
.github/scripts/validate-workflows.sh. - Benchmarks are gated by an environment variable, never run in default CI, and run only in booked Bramble windows.
- Opus reviews only for the supervised tier.
- One push per review round; fix commits are batched.
- Docs-only ADR PRs carry no product code and select only documentation checks.
- Aggregate need is modest (§16.3). Bursts, and agent builds competing with listeners on Juniper, are the real risk (§10.6).
10.4 E2E strategy¶
- Per spec locally for evidence (
bash e2e/run-local.sh --spec <name>), on Bramble when the Juniper cap is reached. E2E is hermetic and never runs against staging. - CI smoke (
run:e2e-smoke) on PRs that touch review flows. run:e2e-fullonce per T1 release candidate, and on #3932's regenerated head in the merge train. A PR touching a flow covered only by@fullspecs evidences it with per-spec local runs; the CI full run happens on the candidate. This is the reading of AC-ALL-14 the E2E budget assumes.- Both tracking modes (AC-ALL-23): the affected review-flow specs run with
activeReviewerTrackingEnabledon and off, as a Playwright project matrix on one stack, for R2a, R2b, R3a, R4a and any release touching claims, admission or the reviewer workspace. E2E runs with tracking on while every deployed environment runs with it off (RT-04). Budget: about eight extra minutes per release.
10.5 Bramble calendar¶
Bramble is Chris's workstation, a CI E2E listener, and the benchmark and soak host; it is not unlimited exclusive capacity (DS-12). Windows are booked in STATUS and approved by Chris, who starts the work there (remote writes from Juniper are blocked).
| Order | Window | Owner | Why at this position |
|---|---|---|---|
| 1 | FEAT-024 gate (b) idle-host rerun | FEAT-024 | X-STATS-b1 heads the statistics chain on this plan's path |
| 2 | The S0 baseline (session submit, screening save, RV-DS tiers) | Stream A | The M0 thresholds need it |
| 3 | FEAT-024 7-day soak (#3952, #3510) | FEAT-024 | A long block; benchmark windows pause the soak driver rather than overlap it |
| 4 | The M0 measurement | Stream A | The M0 go/no-go |
| 5 onwards | T1 release-candidate benchmarks, batched with several candidates per window; X-CLAIMS load and failover runs; ASySD parity (P2: 80,000 citations in under an hour, D4-21) | Streams | At most one window a week |
A window that needs the E2E VM idle stops run:e2e-full for its duration, so it is scheduled
outside working hours.
10.6 Juniper session cap and queue-time tracking¶
- At most eight implementer sessions building or testing on Juniper at once, across programmes,
and at most two heavy local test runs at once (.NET with Testcontainers, or the full web suite),
each run with
nice -n 19 ionice -c3, single-project builds and capped parallelism (PROPOSAL). Agent builds have starved CI before: on 2 September, load above 200 produced Testcontainers start-up failures that looked like code bugs (session notes). - Full local suites and long runs go to Bramble sessions in booked windows.
- The digest tracks start delay (p50 and p90) for PR Tests, E2E and reviews. If PR Tests' p90 exceeds 15 minutes, or Juniper's load per CPU stays above 0.8 for an hour, the programme lead lowers the cap.
11. Conflict avoidance¶
11.1 Hot-file register¶
Non-merge commits since 3 September, counted on main at de3e98c59:
| File | Commits | Lines | Class | Rule |
|---|---|---|---|---|
.generated-checksums.json |
141 | 69 | Generated | Never hand-merged (§11.2) |
src/services/web/swagger.json |
105 | 20,783 | Generated | Never hand-merged |
src/services/web/src/app/core/services/api-client.generated.ts |
104 | 17,614 | Generated | Never hand-merged |
src/services/api/SyRF.API.Endpoint/Controllers/ReviewController.cs |
55 | 1,707 | Hot source | New canonical endpoints in new controllers; seam calls only |
docs/planning/feature-flag-overhaul/consumer-manifest.json |
50 | 1,700 | Shared registry | Programme entries added once, in S0-6 |
src/charts/syrf-common/env-mapping.yaml |
47 | 2,439 | Shared registry | Programme flags registered once, in S0-6 (§11.4) |
src/services/web/src/app/stage/stage-review/stage-review.component.ts |
47 | 2,216 | Shell | Stream C only, under lease (§11.3) |
src/libs/project-management/SyRF.ProjectManagement.Mongo.Data/Repositories/StudyRepository.cs |
42 | 3,253 | Hot source | Canonical repositories in new files; seam changes only, pinned by command-budget tests |
src/services/web/src/app/shared/annotation/annotation-form-v2/annotation-form-v2.component.ts |
42 | 2,478 | Shell | Stream C only, under lease |
src/services/web/src/app/shared/annotation/annotation-form-v2/annotation-form-v2.store.ts |
34 | 3,036 | Shell | Stream C only; #3989's work only as stream C seam slices |
src/services/api/SyRF.API.Endpoint/Controllers/ProjectController.cs |
26 | 1,365 | Hot source | Merge-train order (§11.9) |
src/services/api/SyRF.API.Endpoint/SignalR/NotificationHub.cs |
24 | 1,650 | Hot source | New hub methods, never new parameters (claim contract v2) |
src/libs/project-management/SyRF.ProjectManagement.Core/Model/ProjectAggregate/Project.cs |
12 | 1,728 | Hot source | Small canonical markers only; no new job state (#3961 direction) |
General rule: new canonical code goes in new files (controllers, services, repositories, stores) and reaches AF2 through its ports. A hot source file gets only a minimal seam call per PR, landed by the owning stream. The register lives in STATUS and is refreshed monthly.
11.2 Generated files¶
On a conflict in any generated file, take main's copy, re-run the generator and commit
(docs/how-to/work-with-generated-files.md):
swagger.json,api-client.generated.tsand their checksums:dotnet build src/services/api/SyRF.API.Endpoint -c Release, which regenerates the spec, the client and the checksums;- flag and configuration outputs:
pnpm run generate:env-blocks(insrc/charts/syrf-common) andpnpm run generate:flags(insrc/services/web); - then
pnpm run validate:generatedfrom the repository root.
The validate-generated-code PR lane is the backstop. A hand-edited generated file is a blocking
review finding.
11.3 Single shell-writer stream¶
Stream C is the only writer of the AF2 and stage-review shell files and the Dockview layout files. It lands the extension points first, as code, at F1c. After that, a release slice that needs a shell file takes a lease on it (one open PR per shell file): the first ready slice lands and the later one rebases. Other streams reach AF2 through its persistence port and data source. This replaces the plan's fixed L5 landing order, which made ready work wait (DS-09). The separate editable reconcile host (R4a, R4c) proceeds in parallel under stream D.
11.4 Flags registered once¶
S0-6 registers the five stream kill switches and R0's admission flag once. Releases then use R0's
admission data for per-project enablement, and touch env-mapping.yaml only to flip a default at
production enablement or to add a flag the release genuinely needs environment-wide, declared in
its brief. Every PR still states its flag decision.
11.5 Claim step before any worktree¶
No worktree exists before a claim (DS-19). #3964 and #3969 duplicated the plan's first deliverable within six minutes of each other.
- The slice has an issue carrying the programme, release and stream labels.
- The session searches open PRs and issues touching the same paths (
gh pr list --search, file overlap), including the architecture review's issues. - It records the claim in STATUS (slice, session, date, hot-file leases) and on the issue as a
claimed-by:line, because every session uses Chris's account. - Only then does it run
wt newin the foreground, using the wt-resolvedpr<N>.<slug>path under/home/chris/workspace/syrf/pr/.
A claim with no PR after three working days lapses.
11.6 Post-merge cleanup and worktree hygiene¶
- Merge through
/ship-pr <n> --no-cleanup, then remove only that worktree and delete its branch within 24 hours. The default post-merge cleanup mergesmaininto every active worktree, which touches other sessions' trees. - Weekly: prune merged or closed worktrees older than 14 days (
wt clean). - Worker sessions never use
git stash: the stash list is shared by every worktree.
Evidence: 195 PR worktrees, 127 of them with node_modules, and the root disk 79% used on
3 October.
11.7 PR size¶
About 800 changed lines of non-generated, non-test code per PR, or fewer (PROPOSAL; the readiness
analysis suggests sub-tasks of 500 lines or fewer). Exceptions are declared in the PR body with a
reason. Refactors and seams go in their own PRs; decision ADRs go in docs-only PRs. Recent PRs of
2,000 to 6,000 added lines (#3949, #3895, #3934, #3939) hurt bot-review quality and widened conflict
windows; splitting finer than slices would multiply approvals instead. E81 reports the count in the
PR body.
11.8 ADR number block¶
docs/decisions ends at ADR-020 and already holds two ADR-008 documents. ADR-030 to ADR-069 are
reserved for this programme in STATUS; each ADR PR claims the next number in the same PR by
editing STATUS. ADR-021 to ADR-029 stay free for other work, such as #3961's #3986 and #3987.
Minimum rollback images go in one C16 compatibility ledger, not one ADR per release. ADRs follow
the template in docs/README.md.
11.9 Merge trains¶
The notification stack merges in a fixed order (D1-09, approved on 3 October; NS §4.3):
-
3964, the ownership fix kept by D1-01. Done: it merged on 3 October 2026 at 20:27 BST¶
(85e6facf7) after an approving Claude review on head16788f9and green checks, and #3969 is closed. (When checked at 15:15 BST, its commits then were still local and unpushed.) It editedProjectController.UpdateProject, which #3941 wraps. -
3932, regenerated on current
main, with full checks on the head retargeted tomain, a¶run:e2e-fullrun and human approval. -
3938.¶
-
3941, rebased on step 0, with a test that a refused owner-reserved grant captures nothing.¶
-
3942, with tolerant preferences first.¶
-
3943.¶
-
3944, then #3965 restacked onto it. Restacking is the stack owner's call; otherwise #3965 lands¶
in the same train before any environment enables conversations. -
3945.¶
-
3947 last.¶
X-NOTIF is met after step 5. Other multi-PR sequences, such as #3939 in slices (D3-13f), follow the same pattern: an ordered list in STATUS and one PR in review at a time per train.
12. Definitions of ready and done¶
12.1 Slice ready¶
- The slice brief exists (§13.3), with decision IDs, and its release brief has been authorised by a passed gate.
- Every contract it consumes is frozen, or it builds against a published fake whose version the brief names.
- Fixture files exist or ride in the PR; the test plan names a layer and a fixture for each criterion ID.
- For UI slices, the UI validation has passed against its pass bar, and copy comes from the C17 deck.
- Its flag is registered and off by default.
- No behaviour depends on an unanswered question, or the brief states the "until answered" behaviour.
- Excluded specs in the touched areas are identified for re-enabling.
- The claim step is done (§11.5): no competing claim, and any hot-file lease it needs is free.
- The stream is within its WIP limit, and the review tier is assigned.
12.2 Slice done¶
- AC-ALL-14 to AC-ALL-16 pass: the flags-off spec set where a listed flow is touched; no excluded spec for changed code; tests tagged with criterion IDs; the traceability check.
- Conformance suites for touched contracts are green against fake and real providers.
- CI is green on the exact head, including the fail-closed Test Summary. The SonarCloud new-code
gate passes. There are no new lint suppressions or test exclusions. For web changes,
check:theme-migration,check:contrastand the repository guard specs pass. - Engineering docs and any ADR are in the same PR; user-guide changes are drafted under
[TARGET - Phase N]markers (DS-25); the flag decision is stated. - The tier's review passed on the exact head:
pr-review-settled.shsettled, the bot's summary verdict read, no unresolved threads; for supervised PRs, the verifier report is posted and Chris has read the summary. - Generated files were regenerated, never hand-merged.
- The PR body's programme section is complete; STATUS and the traceability file are updated.
12.3 Release ready¶
- The freeze gate has passed (ADR, DTOs, fake, suite), and the release brief (slice table and dependency list) is authorised.
PROPOSALthresholds are confirmed and pending rows re-confirmed from the answers, or that behaviour is descoped.- Fixture files and the benchmark dataset exist; the seed project is designed.
- UI validations have passed against their pass bars.
- Pilot entry criteria, the pilot plan (projects, testers, duration) and telemetry are agreed.
- The minimum rollback image and the rehearsal plan are recorded in the C16 ledger.
- The tier is assigned, and the walking-skeleton slice is first in the slice table.
12.4 Release done¶
- A release candidate (commit and image SHAs) is recorded and deployed to staging.
- Every automated row passes on that candidate (CI, e2e label runs, and the Bramble report where the tier requires one).
- The tier's rehearsals and containment checks are done; seeds are deployed additively.
- A staging acceptance note exists (who, when, which candidate), and Chris has done the tier's walkthrough.
- The pilot exit criteria are met with monitor evidence, and user testing is complete for the tier.
- The ship-gate verifier report has no open exceptions; the acceptance record is committed.
- Chris gives the go/no-go.
12.5 Production enablement done¶
As §8.6: the production chain met, the pilot conditions met, named projects admitted, the user guide published, the rollback covered, and Chris's approval recorded.
13. Slice briefs and the agent brief template¶
13.1 Release brief format¶
At each freeze gate the lead stream writes a release brief for every release the gate unblocks, in
the format of FEAT-024's async-fold implementation plan
(docs/features/materialized-project-statistics/async-point-fold-design.md §10: one slice per PR,
red-first tests, an explicit dependency list; slices 0 to 7 were delivered in about three days):
- The MVP boundary and the "done" sentence.
- The slice table: number, slice, main files, red-first test shapes, criterion IDs, flag or admission, docs, depends on, review tier, size estimate.
- The dependency list ("slice 0 is independent; slice 2 needs slice 1; …").
- Mandatory test shapes for the risky slices.
- The paths whose later changes force automated rows to rerun (§8.2).
- The tier, the rehearsal plan and the pilot plan.
The first code slice is the walking skeleton (§4.6).
13.2 Example outline for R0¶
Illustrative only: the R0 release brief written at F1a is authoritative. The slices follow R0's MVP as the consistency model restates it (capture, reader floor, markers and guards, enrolment service, writer floor, operational prerequisites, rollback image); the C16 design text belongs to the contracts drafter (brief §1.5).
| # | Slice | Main files (indicative) | Red-first tests | Review tier |
|---|---|---|---|---|
| R0-1 | Walking skeleton: the mixed-version harness (from S0-8) extended to R0's types; one type round-trips through the normal replace path with unknown elements | Harness; StudyRepository class maps |
An older image strips nothing on a whole-document replace (AC-R0-06) | Supervised |
| R0-2 | Extra-element capture (not just ignore) on every embedded type the R0 ADR enumerates | src/libs/kernel/SyRF.SharedKernel/BaseClasses/Entity.cs; class maps |
Capture survives an unrelated-field edit | Supervised |
| R0-3 | Reader floor: the legacy computed getters and the pool, capacity and readiness predicates merge Study.CanonicalSummary through the membership-facts seam; the claim pipeline merges form-keyed counts and per-reviewer markers (RT-07) |
ExtractionInfo.cs; Filters.cs; the claim pipeline in StudyRepository.cs |
R0 and R2a writes alternating on one Study keep the tallies correct | Supervised |
| R0-4 | Legacy-writer refusal on the existing choke point: CanonicalScopes markers on Study and Project, a composite registered IAggregateWriteGuard, project-wide pre-checks, the extended StudyWriteLockArchitectureTests, the UpdateMany inventory (DS-10) |
src/libs/mongo/SyRF.Mongo.Common/AggregateWriteGuards.cs; StudyWriteLockArchitectureTests.cs |
One refusal test per inventoried writer (AC-R0-02); an unguarded write fails the build | Supervised |
| R0-5 | The audited ownership registry with its reconciliation check; PM consumer guards (after X-ARCH-b); the tracking writers (RT-08) and the notification stack's Study writers | New registry files; PM consumers | A stage-keyed claim on a canonical form is refused or translated | Supervised |
| R0-6 | The per-project enrolment service (API and web), the audited admin action, the new-project rule, the AF2 per-project admission input, and the writer floor that refuses canonical commands while any instance runs below R0 | New enrolment files; annotation-form-v2-eligibility.ts |
API and web agree for the same project (AC-R0-04); a canonical command is refused below the writer floor | Supervised |
| R0-7 | Operational prerequisites (canonical collections and indexes at start-up; new pmStudy indexes through the operator route); the C16 compatibility-ledger entry, the runbook and the rehearsal record | Start-up registration; docs | Indexes exist after start-up; validate-docs.sh --skip-indexes |
Supervised |
Dependencies: R0-1 is first; R0-2 follows R0-1; R0-3 follows R0-2; R0-4 and R0-6 are independent of R0-3; R0-5 follows R0-4; R0-7 is last.
13.3 Agent brief template¶
Each slice brief stays at or under 300 lines.
# Slice <ID>: <title>
Release <R> | Stream <A to E> | Review tier <supervised or delegated> | Issue <URL> | Size estimate <lines>
Worktree: created with `wt new` after the claim step; one writer; never `git stash`.
## Goal and boundary
<two to five sentences, and what is out of scope>
## Decisions (one line each)
- <ledger or §1.11 ID>: <what it requires here>
- <Batch B, C or D ID>: <the answer, or the "until answered" behaviour>
- <A-xx>: <the assumption relied on>
## Contracts and fakes
- <C-number> version <x>; fake <type or path> at commit <sha>
## Invariants touched
- <invariant number>: <how this slice keeps it>; proved by <INV check or test>
## Files
- Allowed: <globs>
- Forbidden: shell or hot files without a lease; generated files except through their generators;
other streams' folders; production configuration
## Red-first tests
- <test shape>; layer <U, I, C or E>; tag <criterion ID>
## Criteria to evidence
- <criterion IDs>, with the test names to cite in the PR body
## Flag and admission
<flag, default off; admission behaviour; the flag-decision sentence>
## Docs
<engineering doc to update; user-guide draft under a target marker; ADR, if any>
## Verification commands
<exact commands; on Juniper with nice -n 19 ionice -c3, single projects and capped parallelism;
e2e per spec>
## Stop and ask when
- <the operating model's §2.9 triggers, plus any slice-specific ones>
## Hygiene
- Use `git -C <worktree>` and absolute paths; no `cd` in compound commands.
- Regenerate generated files; build the API in Release before NSwag.
- One review round; second-order findings become issues.
## Deliverable
A PR targeting main with the programme section of the PR template completed.
13.4 PR template programme section¶
S0-5 adds this section to .github/pull_request_template.md, which is generic today:
## Integrated review programme (delete if not a programme PR)
- Slice: <ID> | Release: <R> | Stream: <A to E> | Review tier: <supervised or delegated> | Issue: <URL>
- Criteria advanced, with test names: <AC IDs>
- Decisions relied on: <IDs>
- Contracts and fakes consumed: <C-number and version>
- Invariants touched: <numbers and checks>
- Flag decision: <flag, default, why>
- Generated files: <regenerated with which command, or none>
- Docs: <engineering docs; user-guide draft under a target marker; ADR>
- Size: <non-generated, non-test changed lines>; exception: <reason, or none>
13.5 Release notes from this review¶
- R1a (DS-20): import goes through an import-target port with a legacy adapter now and a canonical adapter later. R1a ships browse, preview and legacy apply; canonical apply is an R2a slice, so the #3934 and #2781 work is not plumbed twice.
- R2a (DS-21): R2a writes the StageSettingsVersion envelope frozen at F1a (bindings, a step list holding one implicit step, policy slots), so R3a adds step semantics without migrating pilot data. The Stage aggregate itself is settled at F3 (brief §1.12).
- R4a (DS-22): the #3944 conversations leave R4a's gate. If #3944 and #3965 have merged, R4a rebinds conversations to the reconciliation task; otherwise they stay disabled.
- R0 (DS-10): the legacy-writer refusal is built on the existing write-guard choke point (R0-4 above), not as edits inside about fifteen legacy writers.
14. Progress visibility¶
14.1 STATUS ledger¶
docs/features/integrated-review/STATUS.md (the home is settled at step 0) is updated as part of
every slice's DoD (DS-18), modelled on FEAT-024's STATUS slice table. It holds:
- gates: state, date and dossier link;
- releases: state (§5.1), tier, lead stream, release candidate and acceptance record;
- slices: ID, issue, PR, stream, state, claim and hot-file lease;
- decisions waiting on Chris: ID, date asked, age and the gate that needs it;
- external chains: step, owner, RAG and forecast;
- the Bramble calendar, WIP counts, the ADR block and the hot-file register;
- links to the C16 compatibility ledger and the traceability file.
14.2 One issue per slice¶
The stream lead creates one issue per slice (to-issues) when a gate authorises the release
brief. Labels: programme:integrated-review, irp-release:<R>, irp-stream:<A to E>, and
review:supervised or review:delegated. These are new labels: the existing release:R1 to
release:R3 labels belong to an earlier plan and are not reused. The issue links the slice brief
and carries the claim line. Each gate dossier gets its own issue. Creating labels is a GitHub write,
done by the programme lead after G0.
14.3 Weekly digest¶
A gh-based script (E76) produces the digest before the weekly review and writes it into STATUS:
- gates and decisions waiting on Chris, with their age;
- PRs waiting for
/approveor for Chris's summary read; - red CI on
mainand on programme PRs; start delay p50 and p90 for PR Tests, E2E and reviews; - external chains with RAG status: X-STATS-b1 to b7, X-ELIG, X-CLAIMS, the X-NOTIF steps, X-AUTH, X-BATCH, X-DEL, X-IMPORT, X-AF2 and X-SHELL, and the X-ARCH items;
- Bramble windows booked and used, with their results;
- WIP per stream against the limits; conflicting PRs older than seven days;
- criteria coverage per release (rows green of total), from the traceability file;
- re-plan triggers fired; worktree and disk hygiene.
14.4 Weekly review¶
Thirty minutes with Chris: the digest, any dossier that is ready, screens for tier-2 acceptance, and the re-plan triggers. Decisions wait for the next sitting unless they are urgent.
15. Integration with the architecture-review roadmap¶
15.1 Where #3961 stands¶
The architecture review (draft PR #3961; synthesis at
/home/chris/workspace/syrf/pr/pr3961.awesome-wozniak-anqdaa/docs/planning/architecture-review-2026-10-synthesis.md)
started on 3 October with issues #3972 to #3990. Its premise is to make existing rules enforceable
and to remove surface area, not to add features. Of its Phase 0 fixes, #3967, #3968, #3970 and #3971
have merged; #3966 is parked under #3992; #3969 duplicated #3964 and is closed, and #3964 merged on 3 October (D1-01). It
competes with this plan for the same approver, agents, CI and files, and several of its items change
foundations F1a freezes (DS-02). Programme integration §10
carries its row in plan §8 and its platform risks; this section carries the sequencing.
15.2 Joint sequencing¶
D1-02, approved on 3 October, covers the Phase 0 row, X-ARCH-a to d and the #3987, #3988 and #3989
timings; the other rows are coordination notes and stay PROPOSAL.
| #3961 item | Why it matters here | Sequencing |
|---|---|---|
| Phase 0 fixes | #3971 changes gating (§10.2); the rest do not block | Continue as they are |
| #3985 non-upsert saves; version bump on direct writes | C18 and C1 rely on version CAS and isolated reads | X-ARCH-a: before F1a, or canonical repositories use isolated reads and non-upsert saves enforced by an architecture test |
| #3973 await domain-event handlers | C19 allows in-process events only for loss-tolerant effects, and only once events are awaited | X-ARCH-a: before F1a |
| #3987 ProjectStatistics activate or freeze | Decides the statistics chain (§6.2) | D1-03, decided on 3 October: activate, on a date still to be set (G0 needs it) |
| #3986 MassTransit after v8 | R0 guards PM consumers; C19 dispatchers | X-ARCH-b: decided before R0's consumer-guard slice |
| #3975 runtime flag provider resets overrides | Admission and acceptance evidence must not depend on runtime overrides | X-ARCH-c: before R0's admission relies on overrides and before any G-NOTIF evidence |
| #3988 v0/v1 schema retirement | System-question snapshots (E24) depend on SystemQuestionVersion variants |
Folded into E24, or after R2a ships |
| #3989 web state convergence (AF2 store, stage-review god files) | Stream C's shell files | Only as stream C seam slices under the shell-writer rule (§11.3) until R3a ships |
| #3979 session filter hard-codes two reviewers; #3980 ValueObject equality and agreement threshold serialisation | R3a's collective rule reproduces the project threshold; target-aware counts | X-ARCH-d: before R3a's build |
| #3984 MassTransit retry, outbox, contract round trips | C19 dispatchers; PM consumers | Coordinated at F1a: C19 names the retry policy it assumes |
| #3974 liveness and readiness; change-stream health | Best-effort hints (C19 class c) | Not blocking: hints never carry correctness |
| #3976 SignalR re-subscribe after reconnect | Presence and hints (AC-T-01) | Before the X-CLAIMS evidence runs |
| #3983 service registry from the csproj graph | New canonical projects must reach change detection | S0-1 registers new projects in today's maps; #3983 later replaces them |
| #3981 ng lint and strict typecheck in CI | New programme web code | New folders are lint-clean and strict from their first slice |
| #3990 simplify CI workflows | Path filters for conformance projects | Coordinated; any workflow change triggers the lanes it changes |
| #3972, #3977, #3978, #3982 | None | Independent |
15.3 Precedence¶
Approved by Chris as D1-02 on 3 October (decision register §1.13):
- The architecture review's Phase 0 continues as it is and lands first on any shared file.
- X-ARCH-a to d and the #3987 and #3988 timings in §15.2 apply.
- Otherwise, on a shared hot file, the item on its own programme's approved critical path lands first and the other rebases.
- One weekly digest covers both programmes. They share the limit on items waiting for Chris, the Juniper session cap and the Bramble calendar.
15.4 Shared rules¶
- S0-1's module follows the review's explicit per-feature registration direction: no convention scan, and a singleton-identity startup test.
- Canonical repositories never serve deciding reads from the shared
RepositoryCacheand never upsert (brief §1.7;.claude/rules/repository-cache.md). - In-process domain events are used only for loss-tolerant effects, and only after #3973 (brief §1.6).
- This programme adds no job state to
Project; its canonical markers there stay small. - Canonical collections have one writer host each, declared in C16.
- New web code passes lint and strict typecheck from its first slice (#3981).
16. Budget and delivery risks¶
16.1 PR budget by family¶
Estimates, refined in each release brief.
| Family | PRs | Review tier | E2E in CI | Release tier |
|---|---|---|---|---|
| S0 | 8 | S0-1, S0-6 and S0-8 supervised; the rest delegated | None | T3 |
| M0 | 4 to 5 | Supervised | None (local journey) | Milestone |
| R0 and floor steps | 6 to 7, plus 1 to 2 per floor step | Supervised | Smoke | T1 |
| R1a to R1d | 10 to 16 | Delegated; grants and authorization supervised | Smoke | T2 |
| R2a to R2d | 23 to 33 | Engine, claims and publication supervised | Full at R2a and R2c; both tracking modes for affected flows | T1, T2 |
| R3a to R3d | 22 to 31, plus 3 to 5 absorbed eligibility slices if D3-09 | Admission, decisions and claims supervised | Full at R3a | T1, T2 |
| R4a, R4p, R4b, R4c | 19 to 27 | Gold, the editor claim and queries supervised | Full at R4a | T1, T2 |
| R5a to R5c | 9 to 13 | Export and disclosure supervised | Smoke | T3 |
| P1, P2 | 13 to 19 | Dedup and merge supervised, plus the parity suite | Full at P2 | T1, T2 |
| C1, C2, O1, O2, AL1 | 21 to 29 | O2 supervised | Smoke | T1, T2, T3 |
| Admission slices (AF2, shell, eligibility) | 3 to 6 | Supervised | Smoke | With R0, R2a and R3a |
| ADRs and docs | 20 to 25 | Supervised; Chris reads summaries | None | Not applicable |
| Total | about 160 to 230 |
16.2 Approver budget¶
| Touchpoint | Count | Each | Total |
|---|---|---|---|
| Decision sittings | 7, covering about 91 open questions | 60 to 90 minutes | 7 to 10.5 hours |
| Gate dossiers | 14 freeze gates plus the M0 go/no-go | 30 minutes | 7.5 hours |
| Ship-gate walkthroughs | T1: 7; T2: 16; T3: 5 (with S0) | 60, 30 and 15 minutes | about 16 hours |
| Supervised-PR summaries | about 70 to 90 | 5 minutes | 6 to 7.5 hours |
| Production enablement approvals | about 10 | 15 minutes | 2.5 hours |
| G-NOTIF passages | 3 to 5 | 15 minutes | about 1 hour |
| Weekly review | weekly | 30 minutes | 0.5 hours a week |
| Checklist exceptions | weekly | about 30 minutes | 0.5 hours a week |
| Total | about 40 to 45 hours, plus about 1 hour a week |
Testers: T1 releases with user-testing tasks need five testers and T2 releases three, batched into monthly rounds of 60 to 90 minutes per tester, about 8 to 10 rounds over the programme (D1-06).
16.3 CI estimate¶
About 190 PRs, times about 2.5 pushes each, times a 32-minute median PR Tests run, is roughly 250 listener-hours over the programme, plus about 190 review jobs and seven full e2e runs (four 45-minute entries each, run two at a time). Against 25 persistent listeners this is small in aggregate. The constraint is contention at peaks (the 227-minute start delay) and agent builds on Juniper, which §10.6 caps.
16.4 Delivery risks¶
| Risk | Mitigation |
|---|---|
| Approver throughput is the binding constraint: about 91 open decisions, 14 freeze gates, the M0 go/no-go and 27 ship gates pass through one person | Per-gate authorisation (D1-04); one dossier per gate; decision sittings by gate; the weekly digest with ages; tiers; two-tier design QA; re-plan when a decision waits more than 10 days |
| Juniper is both the CI host and the agent host, and agent builds starve CI jobs | Session cap; niced, single-project builds; conformance in path-filtered projects; Opus only for supervised reviews; batched pushes; start-delay tracking; full suites on Bramble |
| Bramble is treated as unlimited exclusive capacity, though it runs CI E2E shards and FEAT-024's gate (b) rerun and soak | The Bramble calendar with gate (b) first; benchmarks batched in booked windows; benchmark criteria limited to named hot paths against the S0 baseline |
| The architecture review changes foundations F1a freezes and competes for the same approver, agents, CI and files | Joint sequencing (§15): X-ARCH-a to d, #3987 before F1a, #3988 into E24 or after R2a, #3989 only as shell seam slices; precedence under D1-02 |
| Building against fakes repeats QM v2's "complete but not wired" outcome | The M0 walking skeleton merged before F1a; each release's first slice end to end; at most three slices or ten working days against fakes alone; suites run against fake and real providers |
| Parallel sessions duplicate work, as #3964 and #3969 did | The claim step before any worktree; claims in STATUS; open-PR path search |
| Generated-file and hot-file conflicts | Regenerate, never hand-merge; new canonical code in new files; flags registered once in S0; the hot-file register with leases |
Stacked PRs cannot be reviewed, because reviews run only on non-draft PRs targeting main |
Stack depth at most two; retarget before review, then merge main so Test Summary reports |
| Staging moves on every merge, under acceptance | Acceptance on a recorded release candidate (commit and image SHAs); promotion-pause windows for T1 rehearsals |
A red main now stops all promotion (#3971), and production promotion waits for main's integration tests |
Merge criteria on every PR; revert first, fix second; R0's production cycle scheduled on a green main |
| Runtime flag overrides are silently reset (#3975) | X-ARCH-c; evidence uses GitOps values or per-project admission, never runtime overrides |
| The notification stack merges with a conflicting base and no CI E2E | The merge train (D1-09) with #3964 first (merged 3 October); #3932 regenerated with run:e2e-full; X-NOTIF met at #3943; G-NOTIF per environment and kind family |
| Claims and capacity guards do nothing in production (tracking is off), and turning tracking on is an unowned FEAT-024 mode transition | X-CLAIMS production prerequisite (D3-16); E2E of affected flows in both tracking modes |
| Tester availability limits acceptance | A named panel (D1-06); monthly batched sessions; tiered tester counts |
| Worktree and disk exhaustion | Cleanup within 24 hours of merge; prune merged or closed worktrees older than 14 days |
| ADR numbers collide (ADR-008 is already duplicated) | ADR-030 to ADR-069 reserved in STATUS; one C16 compatibility ledger instead of per-release ADRs |
| External production chains slip (X-STATS-b, X-ELIG, X-CLAIMS) | Named on the GA path with RAG status in the digest; the Q-31(b) path as the designed first pilot path; re-plan triggers |
17. Decisions needed and engineering items¶
17.1 Batch D questions this model depends on¶
| ID | Subject | Needed by | Until answered |
|---|---|---|---|
| D1-01 | #3964 against #3969 | Decided | Chris, 3 October: keep #3964, port #3969's active-member check and tests, close #3969. Carried out: #3964 merged on 3 October (85e6facf7) and #3969 is closed |
| D1-02 | Precedence with the architecture review | Decided | Chris, 3 October (evening): as recommended; §15 carries it, and X-ARCH-a is an F1a prerequisite |
| D1-03 | #3987 activate or freeze, and GA counting | Decided; the activation date is still needed for G0 | Chris, 3 October (evening): activate, as recommended; the GA path includes X-STATS-b1 to b7, and Q-31(b) is not extended to GA |
| D1-04 | Implementation authorisation per gate | Decided | Chris, 3 October (evening): as recommended; each gate's dossier authorises its slices (§3.6), merges keep his /approve, batched daily, and nothing is built before G0 |
| D1-05 | Step 0: merge the ledger, package and inputs to main |
Decided; step 0 (G0's entry) merged on 3 October 2026 (f5318074d) |
Chris, 3 October (evening): as recommended; PR #3617 merges as a docs-only PR. Merged on 3 October 2026 (f5318074d); the authority is on main |
| D1-06 | Tester panel and tiers | Decided; the names are still needed for G0 | Chris, 3 October (evening): as recommended (five testers for T1, three for the rest, monthly sessions, at least two external users where possible). Until the panel is named, user-testing sessions stay unscheduled and T1 activation is blocked |
| D1-07 | Production opt-in pilots before GA | Decided; binding before the first production pilot | Chris, 3 October (evening): as recommended; opt-in production pilots under §8.6, one per family before GA |
| D1-08 | Write-path gate shape and scale | Decided for the start thresholds; F1a confirms them from M0 evidence | Chris, 3 October (evening): as recommended; M0 uses the start thresholds (§4.4) |
| D1-09 | Notification merge order and #3965's place | Decided; the #3965 restack depends on the stack owner agreeing | Chris, 3 October (evening): as recommended (§11.9). Step 0 (#3964) has merged; #3965 waits on top of #3947 until the stack owner agrees to restack it onto #3944 |
| D2-16 | Initial form-size ceiling | F1a | M0 reports the maximum tier only |
| D3-02 | Design acceptance cadence | F1c | UI-8's per-PR preview acceptance applies to new or materially changed screens |
| D3-09 | Eligibility slices absorbed into R3a | F3 | X-ELIG stays an external chain |
| D3-10 | Statistics integration (this model relies on the pilot rules, b and d) | F2 (a, b, d), F5 © | Project 0102 stays out of pilots; preview pilots are exempt from PS1 |
| D3-14 | Seed-if-absent job | F1a (S0), or before S0-4 is enabled if earlier | The hook is built; no staging job runs |
| D3-15 | Firefox and WebKit smoke | F1c, or before S0-7's browser projects count as evidence if earlier | Chromium only; rows needing other browsers stay blocked |
| D3-16 | Production claims route | F1a (contract part: the claim contract fields and route seam), F3 (production route), before any R2b/R3a production pilot | R2b and R3a production pilots wait |
| D3-21 | Notification enablement | Before any notification enablement (G-NOTIF) | No enablement outside e2e and Mailpit |
17.2 Engineering items E76 to E81¶
These settle delivery tooling. The fixture corpus (E99), baseline benchmark arm (E98), seed job (E97), traceability check (E94) and acceptance tooling (E85, E95, E96) belong to the acceptance and UX drafters; S0 builds them.
| ID | Item | Owner | Needed by |
|---|---|---|---|
| E76 | The STATUS ledger format, slice-issue labels, claim records and a gh-based weekly digest script (decision ages, start delays, chain RAG, WIP, criteria coverage from the traceability file) |
Programme lead | S0 (S0-5) |
| E77 | Flags registered once: the five stream kill switches and R0's admission flag in env-mapping.yaml with regenerated outputs, catalogue counts and consumer-manifest entries; later slices only flip defaults at enablement |
Stream A with each stream | S0 (S0-6) |
| E78 | Release-candidate and acceptance-record tooling: candidate commit and image SHAs captured from the staging GitOps values; the acceptance-record template; the rerun rule when later merges touch the release's paths; the staging promotion-pause procedure agreed with the cluster-gitops owner and tested once | Programme lead with L17 | Before R0's ship gate |
| E79 | Fresh-context verifier checklists: one per programme rules file (§2.5) and the ship-gate verifier (criterion IDs to evidence; invariants 1 to 12 to INV checks), with a fixed PASS, FAIL or N/A report format and an exceptions list for the dossier | Programme lead | F1a (first use) |
| E80 | CI and host instrumentation: start-delay capture for the digest; path-filtered conformance test projects with a five-minute target and their routing-contract changes; a capped, niced local-build wrapper for Juniper sessions; the Bramble booking table in STATUS | Programme lead with stream A | S0, then F1a |
| E81 | Conflict-avoidance checks: a non-generated, non-test changed-line counter reported in the PR body; an ADR number uniqueness and block check in docs validation; a shell-file lease check against STATUS | Programme lead with L17 | S0 |
17.3 Assumptions A-35 and A-36¶
| ID | Assumption | Basis | Cost if wrong |
|---|---|---|---|
| A-35 | Chris can give the programme about four hours a week: a 30-minute weekly review; one decision sitting per gate (60 to 90 minutes, answering deviations only); one staging walkthrough per release (60 minutes for T1, 30 for T2, a summary read for T3); and about 12 supervised-PR summaries a week at about 5 minutes each | DS-01 and DS improvement 3; the budget in §16.2 | With less time, the acceptance limit drops to two releases programme-wide and decision sittings merge, so the calendar stretches; the order is unchanged |
| A-36 | Agent engineering throughput is not a binding constraint: main recorded at least 412 PR merges on 24 of the 31 days from 3 September to 3 October (mean 17 on a merge day, peak 53), all through Chris's account; the constraints are approver time, CI host capacity and Bramble's exclusive windows |
git log --first-parent --merges on main at de3e98c59; DS-01 (all 400 PRs since 8 September by chrissena) |
If engineering binds, raise WIP limits once start delays and review latency stay within budget, and split stream C into reviewer workspace and admin UX; the order is unchanged |
Resolution record¶
In the Where column, "patch §n" or "patches §n" names this drafter's change to the integrated plan §n (or, where named, to open questions or the README). Those changes are merged; the working patch file is not kept in the package.
| Finding | Category | Where | Note |
|---|---|---|---|
| DS-01 | Corrected | §2.1 to §2.9, §3.2, §16.2; patches §4, §12 and A-10 | Single approver; streams replace lane owners; checklists replace sign-offs; G0 exit changed; per-gate authorisation is D1-04; approver budget added |
| DS-02 | Corrected | §15, §16.4; patches §10 and §12 | Joint sequencing with #3961 (X-ARCH-a to d); precedence D1-02; #3987 is D1-03; #3964 against #3969 decided (D1-01); the plan §8 row and platform risks sit in programme integration |
| DS-03 | Corrected | §6.1 to §6.6; patch §6.4 | GA path is the latest of six chains, including R2d, R3c, R3d and R4p; binding constraint named; R0 soak per environment; R3c's readiness source decided at F3 |
| DS-04 | Corrected | §5.3, §6.3, §8.6; patch §6.4 | X-AF2, X-SHELL and eligibility admission are plan-owned slices (content in programme integration §11); a production enablement step per release, including R1a's default editor |
| DS-05 | Corrected | §5; patch §7 | Ready queue; windows kept as illustration; brackets added |
| DS-06 | Adopted | §3.3; patch §6.1 | F1a, F1b and F1c; the Q-03 catalogue subset moved to the G0 sitting (PROPOSAL) |
| DS-07 | Adopted | §12, §13, §14 | DoR and DoD; release briefs in the async-fold format; agent brief template; PR template section (S0-5) |
| DS-08 | Corrected | §4; patches §6.1 and §12 | S0 (eight slices) and M0 as a merged walking skeleton with thresholds (D1-08); the scratch-worktree contradiction removed |
| DS-09 | Adopted | §11.1 to §11.4 | Hot-file register re-measured; generated-file protocol; single shell-writer stream; flags registered once |
| DS-10 | Adopted | §13.2, §13.5 | Refusal built on the write-guard choke point (R0-4); design text with the contracts drafter (C16, brief §1.5) |
| DS-11 | Adopted | §7, §8.5; patch §9 | Tiers with per-tier requirements aligned to the acceptance criteria; recorded candidates; promotion-pause windows; the mixed-version harness replaces preview rehearsals |
| DS-12 | Corrected | §10.5; patch §9 | Bramble calendar with gate (b) first; benchmarks limited to named hot paths; baseline in S0 |
| DS-13 | Adopted | §9; patch §9 | Supervised and delegated tiers; stack depth two; retarget before review; ship-gate verifier (AC-ALL-13) |
| DS-14 | Adopted | §10; patch §10 | Budget rules; e2e strategy; start-delay tracking; Juniper session cap |
| DS-15 | Adopted | §5.4 | WIP limits per stream and programme-wide; weekly rebase or close |
| DS-16 | Adopted | §2.6, §7.3, §9.6, §16.2 | Tester tiers and monthly rounds (D1-06); release-level acceptance (D3-02); "materially changed" per UX strategy §13.3 |
| DS-17 | Question | §2.1, §3.2; patches §12 and README | D1-05: step 0 merges the ledger, package and inputs to main; answered 3 October |
| DS-18 | Adopted | §14 | STATUS ledger, one issue per slice, weekly digest (E76) |
| DS-19 | Adopted | §11.5, §11.6, §11.9 | Claim step; cleanup within 24 hours; pruning; D1-01 decided by Chris |
| DS-20 | Adopted | §5.3, §13.5; consequential patch to plan §5.3 | Import-target port; canonical apply moves to R2a |
| DS-21 | Adopted | §3.3, §13.5; consequential patch to plan §5.4 | StageSettingsVersion envelope frozen at F1a |
| DS-22 | Corrected | §3.4, §6.3, §13.5; consequential patch to plan §5.6 | Conversations leave R4a's gate; rebound only after #3944 and #3965 merge |
| DS-23 | Adopted | §11.7 | About 800 changed non-generated, non-test lines; exceptions declared; counter in E81 |
| DS-24 | Adopted | §11.8 | ADR-030 to ADR-069 reserved in STATUS; one C16 compatibility ledger |
| DS-25 | Adopted | §8.6, §12.2 | User-guide drafts under target markers, published at enablement (the acceptance draft's AC-ALL-06 already says so) |
| DS improvement 1 | Adopted | §6 | Revised critical path |
| DS improvement 2 | Adopted | §2.2 | Five streams; L8, L15 and L17 as cross-cutting roles |
| DS improvement 3 | Adopted | §2.7 to §2.9, §14.4 | Decision sittings by gate; per-gate authorisation; dossiers; weekly review; stop-and-ask triggers |
| DS improvement 4 (early value) | Adopted | §6.7 | #3964 and R1b; R1a browse; R2a pilots; R4a straight after R2b and F4 |
| DS improvement 4 (defect quick wins) | Follow-up | §6.7 | Export "completed sessions only", reconciliation-payload identity leak and export unmasking are backlog candidates for Chris's triage (brief §1.20) |
| DS improvement 5 | Adopted | §4.4, §4.5, §5.6 | M0 thresholds and outcomes; re-plan triggers |
| DS improvement 6 | Adopted | §16.1 | Budget table refined with S0, M0 and admission slices |
| DS improvement 7 | Adopted | §2.10 | Existing tools reused; commands spelt out for Codex sessions |
| DS question 1 | Question | §15.3 | D1-02; answered 3 October |
| DS question 2 | Question | §6.2 | D1-03; answered 3 October |
| DS question 3 | Question | §3.6, §9.2 | D1-04, with standing merge approval for delegated slices offered as part of it; answered 3 October |
| DS question 4 | Question | §8.6 | D1-07; answered 3 October |
| DS question 5 | Question | §6.3 | D3-09 |
| DS question 6 | Question | §7.3, §16.2 | D1-06; answered 3 October |
| DS question 7 | Noted | §11.9 | Decided by Chris (D1-01): keep #3964, port #3969's check and tests, close #3969 |
| DS question 8 | Adopted | §8.6, §12.2 | No question needed: adopted in brief §1.15 |
| Review AC-03 | Adopted | §8 | Merge criteria on every PR; activation criteria on a recorded candidate; acceptance record; rerun rule |
| Review AC-09 | Adopted | §4.2 (S0-7, S0-8), §7.4 | Tooling delivered as S0 slices with "needed by" releases; missing tooling cannot pass |
| Review AC-25 | Adopted | §7 | Tiers aligned with the acceptance criteria's assignment; release-level acceptance (D3-02) |
| Review AC §3.2 | Adopted | §12 | DoR and DoD aligned with AC-ALL-14 to 16 |
| PH-11 | Adopted | §4.6, §13.1; patch §10 | Walking-skeleton rule; cap on fake-only building; risk row |
| UX-13 | Adopted | §9.6; patch A-24 | Two-tier design QA; UX strategy §13 owns the checklist; cadence is D3-02 |
| MS-01 | Corrected | §6.2; patch §6.4 | Statistics chain b1 to b7 on the GA path; Q-31(b) as the designed first pilot path (chain owned by programme integration) |
| RT-01 | Corrected | §3.4, §6.1, §6.3; patches §6.1 and §6.4 | X-RECLAIM internal to R4a and frozen at F4; E6 applies always |
| RT-02 | Corrected | §6.3, §5.3 | X-CLAIMS production chain for R2b and R3a; Q-25's tracking line corrected; route is D3-16 |
| RT-03 | Corrected | §6.3 | X-CLAIMS owned jointly by the presence and FEAT-024 owners, with load, failover and backstop evidence |
| RT-04 | Adopted | §10.4, §7.3 | Both tracking modes (AC-ALL-23), budgeted at about eight minutes per release |
| RT-05 | Adopted | §3.3 | Gate part only: the presence checklist covers R2a's tracking adapter at F1a |
| RT-06 | Adopted | §3.3 | Gate part only: the form-keyed projection with per-reviewer markers freezes at F1a |
| RT-10 | Adopted | §3.3 | Gate part only: the draft lease on a stable tab ID freezes at F1a |
| RT-11 | Adopted | §3.3 | Gate part only: the claim contract v2 and hub, DTO and command versioning freeze at F1a |
| RT-24 | Adopted | §6.3 | Gate part only: the orphan-claim backstop is X-CLAIMS evidence |
| RT-27 | Adopted | §2.5, §3.2, §3.3 | The presence owner's docs PR is authorised at G0 and is an F1a entry condition |
| NS-01 | Adopted | §3.3, §3.4 | Gate part only: C15 v2 freezes at F1b; recorded fan-out before R2c's notices |
| NS-03 | Adopted | §3.3 | Gate part only: the kind registry and disclosure hook freeze at F1b |
| NS-04 | Adopted | §3.5 | G-NOTIF per environment and kind family; D3-21 |
| NS-05 | Question | §11.9 | D1-09: merge order and #3965's restack; answered 3 October |
| NS-09 | Corrected | §5.3, §6.3 | Join part only: R1c needs #3941; X-NOTIF edges to R1c, R2c, R3c, R4a and R4b |
| NS-13 | Adopted | §3.5 | Gate part only: flood controls in place before publication notices are enabled |
| NS-17 | Adopted | §6.3, §11.9 | X-NOTIF is met at #3943; the merge protocol |