Plan — Gap Remediation Sequencing
Date: 2026-11-09 Purpose: Define the execution order for addressing all validated gaps, with dependencies, responsible owners, and exit criteria for each phase.
Plan Overview
The remediation follows a dependency-ordered sequence. CRITICAL gaps (mandate-violating, blocking production) must be resolved before HIGH gaps (blocking critical functionality), which must be resolved before MEDIUM gaps (platform completeness). LOW gaps are addressed last as time permits.
Notation:
- Phase: A into-the-group of related remediation steps
- Exit Criteria: What must be true before moving to the next phase
- Owner: Team or individual responsible (default: platform team)
- Effort: Estimated person-weeks (T-shirt sizes: S=1, M=2, L=3, XL=5+)
Phase 1: CRITICAL — Mandate Foundations (Weeks 1-4)
Phase 1A: Zero Bespoke Tables (GAP-01) — 3 person-weeks
Dependency: None — this is the foundational mandate Exit Criteria:
- [ ] No
kazi_ormaterra_tables exist in SurrealDB (or all have been migrated to canonical kinds) - [ ] All KaziSasa routes map to canonical
claim,truth_node,truth_edge,resource, orintegration_entity - [ ] No route handler creates a non-canonical table or writes to a non-canonical field
- [ ] The codebase scan for
kazi_/materra_table references fails (all mapped canonically) - [ ] Dual-write to
integration_entityis best-effort (LET $_ = ...) but never blocks the legacy write - [ ]
verify-kazi-headless-api.mjspasses all 9 gates
Steps:
- Audit SurrealDB schema — list all tables, identify
kazi_andmaterra_(Week 1, Day 1-2) - Map each non-canonical table to a canonical kind — design the mapping (Week 1, Day 3-4)
- Create migration script
scripts/migrate-kazi-to-canonical.surql— read existing rows, create canonical rows, mark migration (Week 1-2) - Execute migration — run the script against dev, then staging, then production (Week 2-3)
- Delete/rename non-canonical tables — drop or rename tables that can be expressed as canonical kinds (Week 3)
- Update all KaziSasa routes —
apps/agent-bff/src/kazisasa-bff-routes.jsto use canonical functions (fn::claim_processing::create_claim,fn::integration::upsert_entity,fn::lifecycle::*) (Week 3-4) - Ensure scenario packs are declarative — move any hardcoded kazi scenario configs to NATS KV
SOVEREIGN_SCENARIOS/SOVEREIGN_LOOKUPS(Week 4) - Run verify-kazi-headless-api.mjs — confirm all 9 gates pass (Week 4)
- CI checkpost — add a pre-commit hook or CI step that scans for
kazi_/materra_table references and fails if found unmapped (ongoing)
Owner: Platform team + KaziSasa vertical lead Dependent phases: Phase 2 cannot start until Phase 1A exit criteria are met (because Phase 2's fail-closed work depends on the data model being clean)
Phase 1B: Fail-Closed / No Synthetic Fallbacks (GAP-03) — 3 person-weeks
Dependency: Phase 1A must be complete (clean data model makes fail-closed auditing easier, but this can start in parallel) Exit Criteria:
- [ ] No catch block in the codebase returns
{ status: "OPTIMAL" }or{ approved: true }or{ deterministic: true } - [ ] No catch block returns
null,undefined, or{}as a "graceful fallback" - [ ] All catch blocks either
throw erroror return an HTTP error response with appropriate status (400/422/502/503) - [ ] ESLint rule
no-synthetic-success-in-catchpasses - [ ] CI lint rule passes (build fails if any catch block violates the pattern)
- [ ] The three documented cases are fixed: LaunchDarkly bundle, kutuma-api environmentId, general catch audit
- [ ]
scripts/verify-fail-closed.mjspasses (infrastructure failure → HTTP error, not synthetic success)
Steps:
- Catch-block audit — run automated audit of all catch blocks in the codebase (Week 1, Day 1-2)
- Fix each catch block — change to
throw erroror return HTTP error status (Week 1-2) - Add ESLint rule
no-synthetic-success-in-catch— flag any catch block that is not justthrow errororreturn new Response(..., { status })(Week 2, Day 1-2) - Fix the three documented cases:
- LaunchDarkly: verify the entrypoint.sh sed patch is applied and idempotent (Week 2, Day 3)
- kutuma-api: verify the
getSignedTokenpatch and MongoDB backfill are in place (Week 2, Day 3) - General catch audit: verify all catch blocks are fixed (Week 2-3)
- Add CI enforcement — add the lint rule to the CI pipeline (Week 3)
- Create and run verify-fail-closed.mjs — automated verification script (Week 3-4)
- Document the pattern — update AGENTS.md mandates section with the concrete fail-closed pattern (Week 4)
Owner: Platform team + Backend team Dependent phases: Phase 3 cannot start until Phase 1B exit criteria are met (because synthetic payloads in catch blocks would violate the no-fakes mandate)
Phase 1C: No Fake Tests (GAP-05) — 2 person-weeks
Dependency: Phase 1B must be complete (CI infrastructure is in place) Exit Criteria:
- [ ] No test asserts a magic number from a non-engine without real engine data behind it
- [ ] All tests either assert structural contracts or use real engine-produced data
- [ ]
scripts/verify-fake-tests.mjspasses (identifies fake tests, counts real tests) - [ ] CI test lint rule passes
Steps:
- Audit test files — scan for magic numbers (32.4m, 17.6m, total_allocated_kg: 18500, etc.) that don't come from real engine data (Week 1, Day 1-2)
- Rewrite fake tests — either (a) create real claims/data through the engine and assert the engine-produced values, or (b) restructure to assert structural contract only (Week 1-2)
- Flag deleted/rewritten tests — document which tests were "fake" and which were rewritten (Week 2)
- Add ESLint rule
no-magic-numbers-in-tests— flag test assertions against specific number values not backed by real engine data (Week 2, Day 3-4) - Add CI enforcement — add the lint rule to the CI pipeline (Week 2-3)
- Create and run verify-fake-tests.mjs — automated identification of fake tests (Week 3-4)
- Update documentation — AGENTS.md mandates section updated with concrete examples of forbidden/fixed patterns (Week 4)
Owner: QA team + Platform team Related to: Phase 2 (no synthetic payloads) — cannot have synthetic payloads in the system if tests are asserting fake numbers
Phase 2: HIGH — Blocking Critical Functionality (Weeks 5-8)
Phase 2A: No Synthetic Payloads / Hardcoded Metrics (GAP-04) — 3 person-weeks
Dependency: Phase 1B must be complete (CI lint rules for catch blocks are in place) Exit Criteria:
- [ ] No UI component displays a hardcoded number/metric (all come from live data, skeleton loaders, or honest empty states)
- [ ] No API route returns
{ status: "OPTIMAL" },{ approved: true }, or{ deterministic: true } - [ ] No API route invents coordinates, suppliers, org IDs, or fake routes/allocations
- [ ] All three ESLint rules pass in CI:
no-hardcoded-metrics,no-synthetic-contract,no-magic-numbers-in-tests - [ ]
test_proxy_auth2.mjspasses with 0 console/page errors after Keycloak login - [ ]
capture_all.mjsshows the four previously-422 endpoints now returning 200 (e.g./v1/changes/count→{"data":13}) - [ ] 16/16 tests pass across 5 test scripts for branding/login/onboarding/redirect/API operations
Steps:
- Audit all UI metrics and values — run the audit script from Design — Eliminating Synthetic Payloads and Hardcoded Metrics (GAP-04, GAP-05) (Week 1, Day 1-3)
- Replace each hardcoded value — for UI metrics, API routes, and test files (Week 1-3)
- Add ESLint rules —
no-hardcoded-metrics,no-synthetic-contract,no-magic-numbers-in-tests(Week 2-3) - Add CI enforcement — add all three lint rules to the CI pipeline (Week 3)
- Run verification scripts —
test_proxy_auth2.mjs,capture_all.mjs, and the 5-test-script suite (Week 3-4) - Fix LaunchDarkly bundle — verify the entrypoint.sh sed patch for LD is applied and idempotent; verify the
zg?passthrough pattern works (Week 3-4) - Fix kutuma-api environmentId — verify the
getSignedTokenpatch, MongoDB backfill, and patched imagekutuma-api:patched(Week 3-4) - Final verification — all verification scripts pass (Week 4 of Phase 2, which is Week 8 overall)
Owner: Frontend team + Backend team + QA team Related to: Phase 1C (fake tests) — the no-fakes principle applies across the stack
Phase 2B: Trusted Timestamping on Finalize (GAP-06) — 2 person-weeks
Dependency: Phase 2A must be complete (the infrastructure is healthy) Exit Criteria:
- [ ] Trusted timestamp mechanism design is complete and documented
- [ ] If an external timestamp authority is available: integration is complete and tested
- [ ] If no external authority: internal deterministic timestamp mechanism is designed, backed by the receipt claim, and tested
- [ ] The FCT-18 card is no longer DEFERRED — either resolved or explicitly accepted as deferred with a clear re-unblocking condition
Steps:
- Investigate timestamp-authority options — check if any external timestamp service (e.g., AWS TimeSync, on-prem KMS with timestamps, or a dedicated timestamp-authority customer) is available (Week 1, Day 1-3)
- If external authority available: design the integration, implement the timestamp attachment to receipt claims, and test end-to-end (Week 1-2)
- If no external authority: design an internal deterministic timestamp mechanism:
- Bound to the receipt claim's root hash
- Generated at finalisation time
- Verifiable by recomputing from the session chain head
- Documented as "internal timestamp — not externally auditable but internally consistent"
- Update FCT-18 card status — change from DEFERRED to the appropriate status (resolved or deferred-with-conditions)
- Test the mechanism — create a test that exercises finalise with timestamp and verifies the receipt carries a consistent timestamp (Week 2)
Owner: Platform team + Security team Note: This work is independent of Phase 2A but cannot be considered "done" until the exit criteria are met.
Phase 2C: Live Money Movement Gating (GAP-07) — 3 person-weeks
Dependency: Phase 2A must be complete (no synthetic payloads, clean data model) Exit Criteria:
- [ ] FINMON-16 live desk gating conditions are documented in a runbook
- [ ] The soft path (FINMON-01 through FINMON-20) is fully functional and independently verifiable
- [ ]
members.environmentIdis backfilled in MongoDB for each org's first (Development) environment - [ ] The
getSignedTokenfunction falls back tomember.environmentIdwhenenvironmentIdis not supplied - [ ] A runbook documents exactly when the finance gate lifts: "finance keys + human approval + payments ledger ready"
- [ ] No live money movement opens until the finance gate lifts (this is a product decision, not a technical debt fix)
Steps:
- Document the gating conditions — write the runbook: "Live money movement opens when: finance keys present in environment variables, human approver flag set in the system, payments ledger table has recent entries" (Week 1, Day 1-3)
- Backfill
members.environmentIdin MongoDB — for each org, set the first (Development) environment ID as the fallback (Week 1, Day 3-4; this was already done per AGENTS.md but must be verified) - Verify
getSignedTokenfallback — confirm the patched function falls back tomember.environmentId(Week 2, Day 1-2) - Write the FINMON-16 runbook — detailed steps for when the finance gate lifts, including who approves, what keys are needed, and how the ledger is prepared (Week 2-3)
- Test the soft path end-to-end — create a full sandbox run from split profile creation through wallet credit (soft, not live), verifying every leg reports its real outcome (Week 3-4)
- Verify the four previously-422 endpoints now return 200 —
/v1/changes/count,/v1/environments/me,/v1/notification-groups,/v1/notification-templates(Week 4)
Owner: Finance team + Platform team + MongoDB team Note: This work is partially already done (the environmentId fix was applied per AGENTS.md), but the runbook and full verification are new.
Phase 3: MEDIUM — Platform Completeness (Weeks 9-12)
Phase 3A: Emergency-Call Location Format (GAP-08) — 1 person-week
Dependency: None — customer-driven deferration, design cannot proceed without a customer Exit Criteria:
- [ ] If a public-safety answering point (PSAP) customer arrives: design the emergency-call location format as a pack configuration in the scenarios plane
- [ ] If no PSAP customer: the deferration is documented with a clear re-unblocking condition, and no code depends on this feature
Steps:
- Monitor for PSAP customer engagement — track if any public-safety answering point expresses interest in the platform (ongoing, Week 1)
- If PSAP customer arrives: design the location pack as declarative configuration in the scenarios plane with geospatial NATS subject routing (Week 1, Day 1-5)
- If no PSAP customer: document the deferration in the program backlog with a clear re-unblocking condition (Week 1, Day 5)
- Ensure no code depends on the feature — audit the codebase for any references to emergency-call location formatting that would break if the feature remains deferred (Week 1, Day 5)
Owner: Program management + Platform team Note: This is customer-driven, not a technical debt issue. The design waits on a customer before proceeding.
Phase 3B: Six-Stage Promotion Lifecycle (GAP-09) — 3 person-weeks
Dependency: Phase 2A must be complete (the no-synthetic-payloads foundation is in place) Exit Criteria:
- [ ] The six-stage workflow (draft → submission → validation → approval → settlement → retired) is implemented as a Kestra or Camel workflow backed by the scenarios plane
- [ ] Every claim type fragment has a complete lifecycle workflow tested end-to-end
- [ ] The dual-control draft→commit→project pattern (D-08 FCT-18) is integrated with the six-stage workflow
- [ ] The workflow emits the correct outbox events at each stage
- [ ] The readiness probe correctly reports the lifecycle stage
Steps:
- Design the six-stage workflow in Kestra or Camel, backed by the scenarios plane (Week 1-2)
- Map each claim type fragment to the six-stage workflow — ensure every pilot claim type (motor, medical, home, government benefit, government compensation, community ticket, industrial) has a complete mapped lifecycle (Week 2)
- Implement the dual-control integration — the draft→commit→project pattern from D-08 FCT-18 must integrate with the six-stage workflow, not be separate (Week 2-3)
- Emit outbox events at each stage — verify that structural events write only delivery anchors, and index synchronisation follows as a consequence (Week 3)
- Test end-to-end — create a real claim through the full six-stage lifecycle, verifying the outbox events, the proof receipts, and the final state (Week 4)
- Update the readiness probe — ensure it correctly reports the lifecycle stage as part of its five-probe check (Week 4)
Owner: Platform team + Kestra/Camel team Related to: Phase 2A (no synthetic payloads) — the lifecycle workflow must emit real events, not synthetic statuses
Phase 3C: Break-Glass Elevation (GAP-10) — 2 person-weeks
Dependency: Phase 2A must be complete Exit Criteria:
- [ ] Break-glass workflow is designed that (a) records a proof event when invoked, (b) files a corrective action claim, (c) bounds the TTL and role expiry
- [ ] The break-glass workflow is tested end-to-end in a dev environment
- [ ] The AGENTS.md mandates are updated with the break-glass pattern
Steps:
- Design the break-glass workflow — records a proof event, files a corrective action claim, bounds TTL/role expiry (Week 1-2)
- Implement the workflow — in Kestra/Camel or as a SurrealQL procedure with the break-glass guard (Week 2)
- Test end-to-end — invoke break-glass in dev, verify the proof event and corrective action claim are recorded, verify the TTL and role expiry are bounded (Week 2-3)
- Document the pattern — update AGENTS.md mandates with the break-glass design (Week 3)
Owner: Platform team + Security team
Phase 3D: Customer-Held Seal/Certification/Signing Root (GAP-11) — 2 person-weeks
Dependency: Phase 2A must be complete Exit Criteria:
- [ ] Either: the customer-held seal/certification/signing root infrastructure is designed and deployed
- [ ] Or: the design explicitly documents that these are out of scope for this release and the platform operates without them, with a clear statement in AGENTS.md
- [ ] The "stop and ask the user" pattern is followed if neither option is acceptable
Steps:
- Design the customer-held seal/certification/signing root — if a customer or use case requires it, design the cryptographic infrastructure (Week 1-2)
- If a customer requires it: deploy the infrastructure and test end-to-end (Week 2-3)
- If no customer requires it: explicitly document in AGENTS.md that these are out of scope for this release, the platform operates without them, and the "stop and ask the user" pattern applies if future need arises (Week 2-3)
- Update AGENTS.md mandates — document the decision (Week 3)
Owner: Platform team + Security team + Legal/compliance (if seal/certification has legal implications)
Phase 3E: Cross-Cutting Lint for Honesty Invariants (GAP-12) — 2 person-weeks
Dependency: Phase 2A must be complete Exit Criteria:
- [ ] ESLint rule (or equivalent) checks that all module responses carry the required
invent_refuse_liveandlive_gate_metflags (where applicable) - [ ] CI passes with the new lint rule
- [ ] New modules ship with the invariant flags; old modules are updated to carry them
Steps:
- Design the cross-cutting lint rule — checks module responses for
invent_refuse_liveandlive_gate_metflags where applicable (Week 1) - Implement the lint rule — ESLint or hadolint or equivalent for the project's tech stack (Week 1-2)
- Audit existing modules — check each module's responses carry the required flags; fix any that don't (Week 2-3)
- Add CI enforcement — add the lint rule to the CI pipeline (Week 3-4)
- Document the invariant — update AGENTS.md with the honesty invariant pattern (Week 4)
Owner: Platform team + each module team (their code must comply)
Phase 3F: Kazi Lookup and Scenario Packs (GAP-13) — 3 person-weeks
Dependency: Phase 1A must be complete (zero bespoke tables remediated) Exit Criteria:
- [ ]
datasets/lookups/lookup.kazi*files exist and are properly formatted - [ ] Kazi scenario packs under
datasets/scenarios/exist and are valid - [ ] The verify-kazi-headless-api.mjs script can load and use these packs
- [ ] All 9 gates of verify-kazi-headless-api.mjs pass with real infrastructure
Steps:
- **Create
datasets/lookups/lookup.kazifiles* — the lookup tables for KaziSasa (Week 1-2) - Create kazi scenario packs under
datasets/scenarios/— the journey definitions, panel configs, SLA windows, quorum bands (Week 1-2) - Verify the verify-kazi-headless-api.mjs script can load these packs — ensure the imported helpers (
createRequisition,submitCrewBid,solveCrewMatching,bindMicroInsurance,reserveToolDepotEquipment, etc.) can load from the new files (Week 2-3) - Run verify-kazi-headless-api.mjs against real infrastructure — confirm all 9 gates pass (Week 3-4)
- Map all KaziSasa endpoints to canonical claim types — ensure every endpoint in the shim routes through canonical planes (Week 3-4)
Owner: KaziSasa vertical team + Platform team
Phase 3G: MARS Schema Fork Resolution (GAP-14) — 5 person-weeks
Dependency: Phase 1A must be complete (zero bespoke tables remediated — this is the same mandate) Exit Criteria:
- [ ] All
mars_andkillbill_mars_tables have been migrated to canonical kinds or deleted - [ ] No
database/schema/mars/table violates the zero-bespoke-tables mandate - [ ] MARS operates as a configuration pack on shared engines, not a parallel database
- [ ] The MARS-CFG backlog is updated to reflect the remediation
Steps:
- Audit
database/schema/mars/— list all tables, identifymars_andkillbill_mars_violations (Week 1, Day 1-3) - Migrate to canonical kinds — for each violable table, determine the canonical mapping (claim, truth_node, truth_edge, resource, integration_entity) and create the migration (Week 1-3)
- Delete or rename violating tables — tables that cannot be mapped canonically must be stopped-and-asked-the-user (Week 3-4)
- Update MARS-CFG backlog — reflect the remediation status, update TODO items, remove items that are now resolved (Week 4-5)
- Verify MARS-CFG backlog status — confirm the "MARS is a configuration pack, not a schema fork" headline is accurate (Week 5)
Owner: MARS team + Platform team Note: This is the same mandate as GAP-01 (zero bespoke tables) but for the MARS vertical. The remediation steps are analogous.
Phase 4: LOW — Polish and Verification (Weeks 13-16)
Phase 4A: Verifier Suites Against Real Infrastructure (GAP-18) — 2 person-weeks
Dependency: Phase 2A must be complete Exit Criteria:
- [ ]
scripts/verify-kazi-headless-api.mjsruns against real infrastructure → 9/9 gates pass - [ ]
scripts/verify-kazi-solver-gateway.mjsruns against real :3070 → 5/5 gates pass - [ ]
scripts/verify-novu-kv-templates.mjsruns → 3/3 gates pass - [ ]
scripts/verify-ai-prompts-kv.mjsruns → 4/4 gates pass - [ ] All verification suite results are documented and any failures are filed as issues or resolved
Steps:
- Execute all four verification suites against the real infrastructure stack (SurrealDB :8000, NATS :4222, Solver Gateway :3070, Agent BFF :3030, etc.) (Week 1-2)
- Document the results — for each suite, list which gates pass and which fail, with root cause for each failure (Week 1-2)
- Address failures — fix the underlying issues (may span multiple phases) or file issues with clear descriptions (Week 2-4)
- Create a verification summary report — consolidate all four suite results into one document with overall platform health assessment (Week 4)
Owner: QA team + Platform team
Phase 4B: Journey Ladder Unchecked (GAP-16) — 1 person-week
Dependency: Phase 2A must be complete Exit Criteria:
- [ ] The integrator docs journey ladder is designed as declarative configuration in the scenarios plane or NATS KV
- [ ] The journey ladder is checked against actual integrator flows
- [ ] The journey ladder is maintained as code, not hardcoded
Steps:
- Design the journey ladder as declarative configuration — in the scenarios plane or NATS KV buckets (Week 1)
- Check against actual integrator flows — verify the ladder matches real integrator workflows (Week 1, Day 3-5)
- Ensure it's maintained as code — the journey ladder is version-controlled and change-reviewed like any other code (Week 1, Day 5)
Owner: Platform team + Integrator community
Phase 4C: Wage-Floor Semantics Verification (GAP-17) — 3 person-weeks
Dependency: Phase 2A must be complete; solver gateway :3070 must be accessible Exit Criteria:
- [ ]
scripts/verify-kazi-solver-gateway.mjsruns against real :3070 → 5/5 gates pass (or failures are identified and filed) - [ ] Wage-floor Option A (default max wage floor resolution across facets) semantics are documented from the solver gateway response
- [ ] Wage-floor Option B (strict wage parity conflict detection with HTTP 422) semantics are documented from the solver gateway response
- [ ] The
procurement.basket_split@1decision-request contract is satisfied by the solver gateway
Steps:
- Execute verify-kazi-solver-gateway.mjs against real :3070 — 5/5 gates pass or identify failures (Week 1-2)
- Document the wage-floor Option A and Option B semantics from the actual solver gateway responses (Week 2)
- Verify the procurement.basket_split@1 decision-request contract — test the solver gateway with the canonical request shape and verify the response (Week 2-3)
- If the contract is not satisfied: stop and ask the user before proceeding (per mandate 9: real-infrastructure citation)
Owner: Platform team + Solver Gateway team
Phase 4D: Documentation and Closure — 2 person-weeks
Dependency: All prior phases complete Exit Criteria:
- [ ] All gap exit criteria are met or explicitly documented as deferred with re-unblocking conditions
- [ ] The Gap Analysis Validation — Cross-Document Gap Audit is updated with final status of each gap
- [ ] The DESIGN-, PLAN-, and BACKLOG- documents are complete and up to date
- [ ] AGENTS.md mandates are updated with any new concrete patterns
- [ ] A final platform health assessment is documented
Steps:
- Update Gap Analysis Validation — Cross-Document Gap Audit — mark each gap as RESOLVED, DEFERRED (with condition), or ONGOING (Week 1-2)
- Update all design documents — ensure they reflect the current state of remediation (Week 2)
- Update AGENTS.md mandates — add any new concrete patterns discovered during remediation (Week 2)
- Conduct a final platform health assessment — run the verification suites, check the exit criteria, and produce a summary (Week 2-3)
- Close the remediation program — document what was resolved, what remains deferred with conditions, and the next review date (Week 3-4)
Owner: Program management + Platform team
Phase Gate Summary
| Phase | Focus | Duration | Exit Criteria Gate |
|---|---|---|---|
| Phase 1 | CRITICAL — Mandate foundations | Weeks 1-4 | All CRITICAL exit criteria met before Phase 2 |
| Phase 2 | HIGH — Blocking functionality | Weeks 5-8 | All HIGH exit criteria met before Phase 3 |
| Phase 3 | MEDIUM — Platform completeness | Weeks 9-12 | Individual phase exit criteria; overall when most MEDIUM resolved |
| Phase 4 | LOW — Polish and verification | Weeks 13-16 | Final assessment; platform health documented |
Key dependency chain: Phase 1A (zero bespoke tables) → Phase 1B (fail-closed) → Phase 1C (no fake tests) → Phase 2A (no synthetic payloads) → rest of phases
Note: Phases 3A (emergency-call location) and 3D (customer-held crypto roots) are customer-driven deferrations — they proceed only when the relevant customer arrives, with documented re-unblocking conditions. Their timing is outside the core sequence.
Risk mitigations:
- Each phase has explicit exit criteria that must be met before moving on
- CRITICAL phases (1) have the highest priority and must be done first
- Customer-driven deferrations (3A, 3D) have clear re-unblocking conditions and don't block the core sequence
- The lint/ CI enforcement ensures patterns are institutionalized, not just one-off fixes
- Verification scripts provide objective pass/fail criteria, not subjective assessments