Plan T — Adapter Registry Pivot (umbrella)

On this page

Status

Step Description Status

1

Plan T1 — Foundations & Traits authored + filed. Drafted in its own plan-mode session per delivery-protocol.md:131-136. Body lives at docs/modules/ROOT/pages/plans/archive/adapter-registry-pivot-t1-foundations.adoc (slug locked at sub-plan plan-mode session; archived at T1.9). Child epic &51 (filed 2026-06-09 alongside this umbrella body) + ~9 step issues (T1.1-T1.9) filed deferred to right before T1 plan-mode session per Plan S Phase 2 precedent. Sub-plan scope: (a) T1.1 SHINES placement audit (lock macro shape); (b) T1.2 ErasedAdapter trait + impl_erased_adapter! macro in craig-exchange-contracts per ADR-032 A1 (object-safe BoxFuture + format: Option<&str> on both send_value + audit_value); (c) T1.3 AuditCodec trait + 10 per-partner impls in craig-partner-audit per ADR-032 A2 + Rust orphan rule; (d) T1.4 FederalPartnerCategory extension to NEW sibling file crates/craig-reference/src/federal_partner_category.rs; (e) T1.5 NEW crates/craig-state-bundle crate per ADR-032 A6 (hosts BundleContribution, StateBundle trait, BootContext, 5 registries); (f) T1.6 NEW crates/craig-state-default seed bundle per D6 (registers existing 11 partners + 14 partner_type tokens verbatim from 20260321100000_expand_partner_types.sql); (g) T1.7 impl_erased_adapter! macro adoption (10 per-partner crate invocations + 1 host-service invocation for SHINES per T1.1); (h) T1.8 per-partner audit_payload_from_value decoders (used by <X>AuditCodec impls in partner-audit); (i) T1.9 plan-completion audit + archive. Soft sequencing gate: F-065 / Plan G Step 6 / #462 should land before T1.7 (per Plan G Step 6 gating clause — non-blocking for T1.1-T1.6).

Done (2026-06-09) — body filed via !659 / 92ca2bb1

2

Plan T1 executed end-to-end. All Plan T1 steps Done; child epic &51 closed; Plan T1 body archived. Hard sequencing gate — Plan T1 lands the FOUNDATIONS (traits + crates + macros) that Plan T2’s registry migration and Plan T3’s open-closure work both depend on. Plan T2 authoring may start once T1 Step T1.5 + T1.6 land substantively (no archive needed for authoring); Plan T2 execution gated on Plan T1 archived + F-065 closed.

Done (2026-06-10) — 8 step MRs (!662 T1.1 / !663 T1.2 / !664 T1.3 / !665 T1.4 / !666 T1.5 / !667 T1.8 / !668 T1.7 w/ #462 reviewer waiver / !669 T1.6; executed in §Step DAG order) + T1.9 audit-archive MR; epic &51 closed; body archived

3

Plan T2 — Registry Migration authored + filed. Drafted in its own plan-mode session. Body lives at docs/modules/ROOT/pages/plans/archive/adapter-registry-pivot-t2-registry-migration.adoc (archived 2026-06-10). Child epic &52 (filed 2026-06-09) + 5 step issues #570-#574 (T2.1-T2.5). Sub-plan scope: (a) T2.1 AnyAdapter → registry dispatch in services/craig-exchange + NEW bundle_orchestrator.rs + NEW ExchangeRegistries (realized as an Arc<ExchangeRegistries> Extension layer per the established Plan I F-026 pattern — exchange-only registries don’t pollute craig_api::AppState) + noop:// sentinel inline at dispatch entry point per ADR-032 A3 + a VERIFY-OR-ADD clause for test_connectivity_value on the ErasedAdapter trait (the T1.2 spec ships 3 methods; the connectivity dispatch site needs a 4th — additive); F-065 mechanical gate via glab issue view 462 --output json | jq -r .state returns closed; (b) T2.2 AuditCodecRegistry + audit_typed + dispatch_audit_typed deletion from services/craig-exchange/src/adapters/mod.rs; audit encoding keys on the RESOLVED adapter’s kind() (noop-substitution fail-closed); (c) T2.3 Mock-server static router → MockRouterRegistry per ADR-032 A5 (mock partner modules migrate from tools/craig-mock-server/src/<partner>.rs to crates/craig-partner-/src/mock.rs behind axum-gated mock Cargo feature; the planned crates/craig-mock-validation leaf crate was NOT created — execution found validation.rs had zero consumers post-Plan-L typed migration and DELETED it instead, per the T2.3 cell deviation note; shared MockState deleted; routes nest at /partner/<kind> VERBATIM per §2.5 — a uniform 10-path migration covering datagen + all 10 round_trip suites); (d) T2.4 drop adapter_kind CHECK constraint + bundle-orchestrator boot validation (adapter_kind registry membership only; write-path validation stays enum-enforced until T3.1); (e) T2.5 plan-completion audit + archive. Sequencing gates — *authoring CAN start once Plan T1 Step T1.5 + T1.6 land substantively, OR earlier against the locked Plan T1 body specs (T2 body authored 2026-06-09 per planning-sprint decision; drift risk carried as T2 body risk row 9); execution (T2.1 MR opens) gated on Plan T1 archived + F-065 / #462 closed.

Done (2026-06-09) — body filed via !660 / 3b62f07c

4

Plan T2 executed end-to-end. All Plan T2 steps Done; child epic &52 closed; Plan T2 body archived. Plan T3 sequencing gate clears.

Done (2026-06-10) — 5 MRs (!673 / !674 / !676 / !677 + the archive MR; T2.4 ran before T2.3 per the DAG); body at plans/archive/adapter-registry-pivot-t2-registry-migration.adoc; epic &52 closed; Plan T3 execution gate CLEAR

5

Plan T3 — Open Closures & Hardening authored + filed. Drafted in its own plan-mode session. Body lives at docs/modules/ROOT/pages/plans/archive/adapter-registry-pivot-t3-open-closures.adoc (archived 2026-06-11). Child epic &53 (filed 2026-06-09) + 8 step issues 575-#582 (T3.1-T3.8). Sub-plan scope: (a) T3.1 open ExchangeAdapterKind enum at DTO/store/send_worker per ADR-032 §1.3 — DELETE enum + convert DTOs to String + temp hardcoded 11-token validator preserving STATUS-level 400→400 (no transition window; the wire problem-type MAY change at the serde→handler move — verified + CHANGELOG’d at T3.1) + crates/craig-partner-audit token conversion (kind()&'static str; research-surfaced 2026-06-09) + adapters/standard.rs::config_for_kind collapse + Cargo.toml dep cleanup (contracts crate drops enum-only sqlx/strum/utoipa; partner-audit drops contracts dep — cargo machete gate); (b) T3.2 create/update partner flows + request validation via registry + NEW GET /v1/exchange/registry/adapter-kinds AND GET /v1/exchange/registry/partner-types discovery endpoints + CLI --adapter-kind create/update args; (c) T3.3 PartnerType enum deletion + DTO migration + temp hardcoded 14-token validator (14 tokens verbatim from 20260321100000_expand_partner_types.sql; deliberate 5→14 API-validation widening closing the latent API/DB mismatch — seeded rows already carry the 9 expanded tokens) + web new-partner form consumes the registry endpoints (retires the hardcoded 5-option select); (d) T3.4 FederalPartnerMappingRegistry per ADR-032 A7 — architectural seam only (craig-reporting boots its own registry from DefaultBundle; NEW service-local ReportingError enum); federal-completeness check is REPORT-EMIT time, NOT boot (per A7); reporting wire-up DEFERRED to follow-up issue; (e) T3.5 drop partner_type CHECK constraint + ALL-rows boot registry validation (no WHERE active filter — closes the inactive-row re-activation hole; retrofits T2.4’s adapter_kind check) + effective-row update validation + restrengthen validators via registry; (f) T3.6 remove hardcoded jurisdiction: "georgia" at the 1 production seed-default site at tools/craig-seed/src/datagen.rs:1630 (REDUCED scope per ADR-032 A8 — 3 of 4 §2.6 sites are #[cfg(test)] helpers; only datagen.rs is production). Seed plumbing expansion: T3.6 SHIPS the full plumbing in one MR — "env" feature on the clap dep (unconditional; not a [features] flag) + [arg(long, env = "CRAIG_SEED__JURISDICTION", value_parser = non_empty_string)] REQUIRED arg + jurisdiction threads Cli → SeedConfig (lib.rs) → SeedGenerator (datagen.rs:233) → line 1630 + ALL invocations updated (devstack seed.sh, xtask e2e direct cargo run -p craig-seed, manifest.rs reproduction command); (g) T3.7 integration test lockstep at per-service paths (per Plan N Step 8a axis-coverage convention — workspace is virtual; root tests/ doesn’t compile) — first services/craig-exchange/tests/security/ convention dir + tests/security.rs harness root + evil-corpus sweep over the opened String fields; (h) T3.8 plan-completion audit + archive. Hard sequencing gatesauthoring CAN start parallel with Plan T2 execution (planning only), OR earlier against the locked Plan T1+T2 body specs (T3 body authored 2026-06-09 per planning-sprint decision; drift risk carried as T3 body risk row 8); execution (T3.1 MR opens) gated on Plan T2 archived.

Done (2026-06-09) — body filed via the Phase E docs MR (see CHANGELOG § Unreleased)

6

Plan T3 executed end-to-end. All Plan T3 steps Done; child epic &53 closed; Plan T3 body archived.

Done (2026-06-11) — Plan T3 shipped in 8 MRs (!679/!680/!681/!682/!683/!684/!685 + the T3.8 audit+archive close-out), all 2026-06-10/11. Type-system closures opened (ExchangeAdapterKind + PartnerType enums deleted; open String tokens; registry-driven write-path + all-rows boot validation), partner_type CHECK dropped, FederalPartnerMappingRegistry report-emit seam landed in craig-reporting (follow-up #583), the last georgia seed default removed (CRAIG_SEED__JURISDICTION required), and the open-token surfaces hardened with an evil-corpus sweep (0 validator gaps). Epic &53 closed (#575-#581 + #583). Body archived at plans/archive/adapter-registry-pivot-t3-open-closures.adoc.

7

Plan T umbrella audit + archive. Standard close-out per .claude/docs/delivery-protocol.md § Plan Completion Audit. Dispatch fresh plan-completion-audit Explore subagent per the plan-completion-audit bias. Subagent verifies T1/T2/T3 Status cells have concrete !MR / sha citations for each sub-plan’s body + execution + archive. cargo xtask docs plan-archive --dry-run then execute. nav.adoc § Active Plan T umbrella row REMOVED; row ADDED under plans/archive.adoc § Architecture. .claude/CLAUDE.md § Phase Status row appended above Testing. Plan S umbrella Status cell Step 9 (Plan T3 executed) → Done (YYYY-MM-DD). Memory: EDIT Plan S mark Plan T umbrella Done. Child epic &45 closed with cross-ref to Plan T umbrella body archive + 3 sub-plan archive cites.

Done (2026-06-11) — this MR (umbrella audit + archive close-out). Fresh plan-completion-audit Explore subagent PASS on all 7 checks: steps 1-6 all Done with concrete cites, all 3 sub-plan archive bodies exist at plans/archive/ (T1 9-MR/epic &51, T2 5-MR/epic &52, T3 8-MR/epic &53), epic mapping coherent, 0 stale placeholders. The Plan T arc (T1 Foundations + T2 Registry Migration + T3 Open Closures) is complete: the adapter-registry pivot replaced the closed ExchangeAdapterKind/PartnerType enums + AnyAdapter dispatch with bundle-contributed registries and open token carriage, end to end. This MR archives the umbrella body, removes the nav Active entry, flips Plan S Step 9 → Done, and closes parent epic &45. Plan S itself stays Active (Plans U/V/W/X/Y ahead).

Context

ADR-032 (Multi-Jurisdiction Partner Registry and Transport Abstraction) anchors Plan S Phase 1; ADR-038 (Trait-Object & Registry Patterns) codifies reusable architectural principles. ADR-032 amendments A1-A11 resolve the 8-round iteration findings from the abandoned single-Plan-T body authoring session.

Plan T executes ADR-032 §1 + §2 foundation into code. The "into code" caveat: T3.4 defers reporting wire-up per A7; Plan U Step 4 ships multi-bundle activation per A10. The architectural depth surfaced during single-Plan-T body authoring justified restructuring into 3 sub-plans: T1 (foundations & traits) sets up everything T2 + T3 build on; T2 (registry migration) migrates the existing closed-enum AnyAdapter dispatch to the registry pattern; T3 (open closures & hardening) opens the type-system + DB closures + test hardening.

Plan T is the keystone of the entire Plan S umbrella: Plans U/V/W/X/Y all gate on Plan T1 (foundations) + Plan T2 (registry materialization) landing substantively. Plan T3 may run partially parallel with downstream plan authoring. Sub-clause: Plans U/V depend on Plan T2 archive for trait + registry stability; Plan W onwards can author against Plan T1 substantively-landed types + Plan T2 substantively-landed registries without waiting on Plan T3 archive.

Decisions locked (Phase A artifact)

10 D-decisions from the 8-round Plan T body iteration are locked in ADR-038 + ADR-032 amendments:

  • D1: BundleContribution + StateBundle in NEW crates/craig-state-bundle (ADR-032 A6)

  • D2: Factory-shaped adapter contribution + BootContext (ADR-032 A4)

  • D3: Typed federal_mapping() → HashMap<&'static str, FederalPartnerCategory> (ADR-032 §2.1 unchanged)

  • D4: F-065 / Plan G Step 6 / #462 mechanically hard-gates T2.1 via glab issue view 462

  • D5: ExchangeAdapterKind enum DELETED in T3.1 (ADR-032 §1.3 open-TEXT carriage; an earlier draft cited a phantom "A8a" amendment — ADR-032 amendments run A1-A11)

  • D6: NEW crates/craig-state-default seed bundle in T1.6 registers 14 partner_type tokens verbatim

  • D7: AuditCodec trait + impls BOTH in craig-partner-audit per Rust orphan rule (ADR-032 A2)

  • D8: Mock partners self-state-bound; shared MockState deleted in T2.3 (ADR-032 A5)

  • D9: Temp hardcoded validators preserve 400→400 during T3.1 + T3.3 transition windows

  • D10: T3.4 ships federal mapping seam only; reporting wire-up deferred (ADR-032 A7)

Calendar

Sub-plan Scope Anticipated MRs Calendar

Plan T1 — Foundations & Traits

T1.1-T1.9 — trait + macro + 5 NEW types/crates + per-partner adoption

~9

~1.5 wk

Plan T2 — Registry Migration

T2.1-T2.5 — AdapterRegistry + AuditCodecRegistry + MockRouterRegistry + DDL adapter_kind + ExchangeAppState (noop:// folded into T2.1)

~5

~1 wk

Plan T3 — Open Closures & Hardening

T3.1-T3.8 — open enums + DDL partner_type + georgia removal + tests + archive

~8

~1.5 wk

Plan T umbrella audit + archive

Step 7

1

~0.5 day

Total: 22 child MRs + 3 sub-plan filing MRs + 1 umbrella body MR (this MR) + 1 archive MR = ~27 MRs across ~3.5-4 weeks. ~3 sub-plan plan-mode review sessions (T1/T2/T3 each authored in own session per delivery-protocol.md:131-136).

Step DAG

Step 1 (T1 body filed)
   ↓
Step 2 (T1 executed end-to-end + archived)
   ↓
Step 3 (T2 body filed; authoring may start once T1 Step T1.5 + T1.6 substantively done)
   ↓
Step 4 (T2 executed end-to-end + archived) ──┐
   │                                            │
   │   ┌── Step 5 (T3 body filed; may parallel ─┤
   │   │       T2 execution)                    │
   ↓   ↓                                        │
Step 6 (T3 executed; gated on T2 archive) ─────┘
   ↓
Step 7 (Plan T umbrella audit + archive)

Threat model

  • Plan T1 foundation cascade — if Plan T1 ships an under-specified BundleContribution shape, every downstream Phase 2 plan (W/X/Y + U Steps 9-10) inherits the defect. Mitigation: Plan T1 body authors in its own plan-mode session with same iteration discipline as the original Plan T was; ADR-038 §4 field-sourcing rule pre-flight check before any Phase 2 plan adds a field.

  • Mock partner migration breaks E2E — Plan T2 Step T2.3 migrates mock modules from tools/craig-mock-server to per-partner crates + adds mock Cargo feature. Hardcoded mock URLs in E2E specs / devstack / per-partner test fixtures need lockstep updates. Mitigation: T2.3 audit of 5 URL surfaces (per ADR-032 A5 callout) + T3.7 test lockstep sweep.

  • Closed-aggregator limitation surfaces during non-georgia state adoptionPartnerAuditEvent is a closed enum (ADR-032 A2 known limitation). Plan T accepts this; #558 (filed via !657 Phase A) tracks decoupling. Risk realizes only on first non-georgia state adoption signal.

  • F-065 timing slip blocks T2.1 — Plan G Step 6 / #462 cross-handler DRY scan must land before T2.1 MR opens. Mitigation: F-065 surfaced as parallel work-stream during Plan T1 execution; T2.1 mechanical pre-step gate via glab issue view 462.

Cross-cutting invariants

Invariant Enforced by Verification

BundleContribution grows additively per ADR-032 §4

Per-plan MR convention

ADR-032 §4 cited

ADR-038 §3 field shape decision documented in each Phase 2 ADR

Plan-mode session discipline

Each anchoring ADR cites ADR-038 §3

Pre-1.0 destructive migrations OK

the pre-1.0 destructive-rebuild posture cited in T2.4 + T3.5 commits

Reviewer check

Quality budgets monotonic

xtask validate [4i/14] quality-budgets

Pre-push gate

Axis coverage opt-out monotonic

xtask validate [4j/14] axis-coverage

Pre-push gate

fn-name-and rule on new helpers

xtask validate [4k/14] fn-name-and

Pre-push gate

Each sub-plan body iterates through 3-4 contextless review rounds

delivery-protocol.md:131-136

Per-sub-plan plan-mode discipline

Per-sub-plan test additions tag @axis: per Plan N Step 8a discipline

xtask validate [4j/14] axis-coverage

Opt-out monotonic shrinkage at xtask/axis-coverage-opt-out.txt

Risk register

# Risk Impact Likelihood Mitigation

1

Sub-plan body authoring re-discovers Phase A architectural decisions

Plan-mode session inefficiency

Med

ADR-032 amendments + ADR-038 + this umbrella body cite D1-D10 at top; sub-plan authors read those first

2

Plan T1 → Plan T2 sequencing gap (T2 execution starts before T1 archived)

Architectural drift

Low

Plan T2 Status cell distinguishes: authoring may start once T1 Step T1.5 + T1.6 land substantively; execution (T2.1 MR) gated on Plan T1 archived + F-065 closed

3

Mock URL migration breaks E2E silently in T2.3

Test regression

Med

T2.3 audit of 5 hardcoded-URL surfaces; T3.7 sweep

4

Closed-aggregator #558 surfaces during non-georgia adoption

Adoption friction

Low

#558 filed via !657 Phase A; decoupling planned post-Plan-T

5

F-065 / Plan G Step 6 timing slip blocks T2.1

Schedule slip

Med

T2.1 mechanical glab issue view 462 gate; F-065 expected to unblock concurrent with Plan T1 execution (all 7 gating plans D/G/H/I/J/K/L now Done as of 2026-06-08; #462 ready to execute)

6

Phase 2 plan author misuses BundleContribution growth pattern

Cross-crate reference drift

Low

ADR-038 §4 field-sourcing rule + ADR-032 §4 additive growth contract + per-Phase-2-ADR §3 field-shape decision

  • ADR-032 — Multi-Jurisdiction Partner Registry + amendments A1-A11.

  • ADR-038 — Trait-Object & Registry Patterns; cited by T1.2 + T1.3 + T1.5.

  • ADR-030 — Status vocabulary on every cell.

  • Plan S — umbrella; this body sits at Plan S Step 3.

  • Plan G — F-065 cross-handler DRY scan hard-gated Plan T2 Step T2.1 (closed 2026-06-10 via !671; gate CLEAR).

  • the pre-1.0 destructive-rebuild posture — Plan T2 Step T2.4 + Plan T3 Step T3.5 commit messages cite.

  • the service-initialization pattern — T2.1 bundle wiring follows canonical service-main shape.

  • the quality-budget enforcement gate — B3a verification discipline for T1.2 macro expansion.

  • #558 (closed-aggregator decoupling tracking) — known limitation accepted; future decoupling deferred.

Edit this page · latest