Assign all 425 SHR-INV-0001 items to 19 slices across five waves plus Keep, each with adapter flag, owner API, and rollback. Coverage computed against the inventory rather than hand-counted. Only Wave A (repo-manager, 165 items) is executable; B/D1/D2 are gated on owner-side contracts still at proposed. Flags two findings for T04/T05: the 9 ops_dependency items cannot be strangled behind a flag, and the legacy-meter weekly review window is 8h, not a week. Also corrects the workplan status from proposed to active. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
11 KiB
State Hub retirement — cutover slice plan
Workplan task: STATE-WP-0079-T02
Inventory: SHR-INV-0001 (prj-state-hub-retirement/inventory/), 425 items, v0.1.1
Created: 2026-08-19
Groups every dispositioned inventory item into an ordered cutover slice. Each
slice names its adapter flag, the owner-side API that receives the traffic, and
its rollback. Slices are the execution unit for STATE-WP-0079-T04.
Method
Slices are cut on capability, not on route or table, because a capability is
the smallest unit with a single owner and a coherent contract. The inventory's
capability field yields 51 groups; those are bundled into waves by owner, and
ordered within a wave by dependency and blast radius.
Two rules constrain the ordering:
- A slice cannot move before its owner can receive it. Owner readiness is the owner repo's own workplan status, not an assertion here.
- Read-only projections move before write paths in the same capability, so a failed cutover degrades to stale reads rather than lost writes.
Owner readiness (verified 2026-08-19)
| Owner | Items | Gating workplan | Status | Can receive? |
|---|---|---|---|---|
repo-manager |
167 | RMGR-WP-0001/0002/0003 | finished |
Yes |
hub-core |
128 | HUB-WP-0004 runtime + extension contract | proposed |
No |
state-hub-until-cutover |
55 | — (keep/retire in place) | — | n/a |
activity-core |
18 | ACTIVITY-WP-0029 hub port alignment | active |
Partial |
ops-hub |
13 | OPS-WP-0003 extension contract alignment | proposed |
No |
fin-hub |
10 | FIN-WP-0003 fabric authority boundary | proposed |
No |
archive |
30 | legacy-meter evidence | see Wave E | Conditional |
ops-bridge |
2 | — (keep) |
— | n/a |
the-custodian |
2 | — | — | Yes |
Only the repo-manager lane is fully unblocked today. Wave A is the whole of
the near-term executable surface; everything else is correctly waiting on an
owner-side contract, not on State Hub.
Adapter mechanism
Wave A reuses the dual-run strangler proven in RMGR-WP-0002/0003 rather than introducing a new mechanism:
- Adapter:
api/services/repo_manager_dual_run.py - Existing flags:
RM_WRITEBACK,RM_WRITEBACK_PUSH,RM_RECONCILE,RM_PILOT_REPOS,RM_METER_PATH,RM_DUAL_RUN_CONFIG - Reference:
repo-manager/docs/dual-run.md, evidencerepo-manager/docs/evidence/wp0002-completion.md
New slices add a slice-scoped flag of the form RM_SLICE_<NAME> with three
states — off (hub only), dual (both, hub authoritative, divergence metered),
owner (owner authoritative, hub proxies). Rollback for every Wave A slice is
therefore the same operation: set the slice flag back one state. No slice
advances to owner until it has run a full consistency-sweep cycle at dual
with zero divergence.
Waves B–D must not invent hub-side adapters ahead of their owner contract. Per the T01 freeze rule, building an adapter for an owner that cannot yet receive establishes new permanent ownership here — the exact thing retirement is removing.
Wave A — repo-manager (167 items, executable now)
A1 · Repository registry — 27 items
repository-registry (24: 16 route, 7 mcp_tool, 1 dataset) · repo-reconciliation (1)
· repo-doi (1) · repo-onboarding (1)
| Flag | RM_SLICE_REGISTRY |
| Owner API | rmgr repo registry + classification spine |
| Rollback | flag → dual, then off; hub tables retain rows throughout |
First because every other repo-manager slice keys off repo identity, and because
repo-onboarding is already delegated (STATE-WP-0080-T02, rmgr scaffold),
so the slice starts partly cut over.
A2 · Work records — 59 items
work-records (20) · work-records-workplan (12) · work-records-intake (9) ·
work-records-decision (8, move+replace) · work-records-deps (2) ·
work-records-task (8, repo-manager portion)
| Flag | RM_SLICE_WORKRECORDS |
| Owner API | rmgr file-backed work-record index + PATCH /tasks writeback |
| Rollback | flag → dual; C-15 writeback already reconciles file↔DB drift |
Highest blast radius in the program — this is the surface every agent session touches. Split the flag by record kind if divergence appears; do not cut the whole slice at once.
work-records-task is owner-split: the route/dataset portion is repo-manager,
the job portion is activity-core (Wave C1). Cut the repo-manager portion first
and leave the job dual-running.
A3 · Registers — 49 items
sbom-inventory (10) · repo-goals (9) · upstream-contributions (9) ·
register-technical-debt (9) · register-extension-points (6) · register-entries (6)
| Flag | RM_SLICE_REGISTERS |
| Owner API | rmgr register endpoints |
| Rollback | flag → off; these are append-mostly, so replay is cheap |
Low coupling and low write volume — the natural place to prove the
RM_SLICE_* pattern before A2's blast radius.
A4 · Work + repo UI — 22 items
work-coordination-ui (14, replace) · repo-ui (8)
| Flag | RM_SLICE_UI |
| Owner API | owner-side dashboard; hub pages redirect |
| Rollback | remove redirect; hub pages are unchanged behind it |
replace, not move: the contract changes. Must follow A1–A3, since the pages
render what those slices serve.
A5 · Topic spine — 8 items
topic-spine (8, replace)
| Flag | RM_SLICE_TOPICSPINE |
| Owner API | rmgr topic/classification contract |
| Rollback | flag → off |
Last in Wave A: it is a replace under a changed contract, and A1–A4 read it.
Wave B — hub-core (128 items) · gated on HUB-WP-0004
HUB-WP-0004 is proposed. No hub-side adapter work until it is at least
ready. Slices are listed to fix scope and order, not to start.
| Slice | Capabilities | Items |
|---|---|---|
| B1 catalogs | capability-catalog (18), cross-domain-registry (16) |
34 |
| B2 messaging + interface log | agent-messaging (11), interface-change-log (11) |
22 |
| B3 telemetry | token-telemetry (14), third-party-software-catalog (10), progress-telemetry (8) |
32 |
| B4 projections + policy | state-projections (9), domain-goals (6), policy-integration (2), write-idempotency (1), event-bus (1), recently-on-scope (1) |
20 |
| B5 hub UI | hub-projection-ui (14, replace), agent-integration (2), dashboard (1) |
17 |
Order B1 → B4 → B2 → B3 → B5: catalogs and projections are read-mostly and carry the contract; messaging and telemetry are write paths; UI last.
Wave C — activity-core (18 items) · ACTIVITY-WP-0029 active
| Slice | Capabilities | Items |
|---|---|---|
| C1 execution | workplan-execution-queue (7, replace), task-flow-engine (6, replace) |
13 |
| C2 jobs | ops-run-projection (1), repo-consistency (3), work-records-task activity-core portion (1) |
5 |
Both are replace — schedulers move to activity-core under a different
contract. C2 must follow A2, since the consistency job writes work records.
Wave D — remaining owners (25 items) · all gated
| Slice | Owner | Capabilities | Items | Gate |
|---|---|---|---|---|
| D1 | ops-hub |
service-catalog (9), service-catalog-ui (2) |
11 | OPS-WP-0003 proposed |
| D2 | fin-hub |
fabric-graph (10) |
10 | FIN-WP-0003 proposed |
| D3 | the-custodian |
kaizen-agents (2) |
2 | none — can go anytime |
D3 is two MCP tools with no dependants; take it opportunistically.
Wave E — retire (42 items)
| Slice | Capability | Items | Gate |
|---|---|---|---|
| E1 | suggestion-backlog → archive |
17 | caller check; no successor runtime |
| E2 | work-records-workplan-legacy → archive |
13 | legacy-meter — see caveat below |
| E3 | dashboard-meta |
1 | none |
| E4 | legacy-meter itself |
9 | last — it is the instrument for E2 |
E4 retires only after every other legacy surface is closed; retiring the meter first destroys the evidence for the retirements it gates.
Caveat on E2's evidence
The 2026-08-19 review (docs/evidence/legacy-meter-weekly-review-20260819.json)
reports 19 retirement candidates, all replacement_verified: true with zero
calls in window. But the window is 06:00Z → 14:00Z — 8 hours, not the 7 days
cadence: weekly implies. Several candidates have very large all-time counts
(GET /workstreams/{id} 511 406, GET /workstreams/ 144 086,
POST /workstreams/{id}/dependencies/ 255 865).
An 8-hour quiet window is not sufficient evidence to retire an interface at that call volume. Either the window computation is a defect or the cadence label is wrong; either way E2 should not proceed on the current evidence. Resolving this is a prerequisite, and it is worth checking before Wave A rather than after, since the same meter gates T05.
Keep — 43 items
schema-history (43 migrations, keep until cutover) plus ops-automation,
connectivity (ops-bridge). Not slices: they persist until the T06 freeze
window and are dispositioned by the final dump and archive.
Coverage
Computed against state-hub-disposition.yaml, not hand-counted. Every item is
assigned by capability; work-records-task splits on owner.
| Wave | Slices | Items |
|---|---|---|
| A repo-manager | A1 27 · A2 59 · A3 49 · A4 22 · A5 8 | 165 |
| B hub-core | B1 34 · B2 22 · B3 32 · B4 20 · B5 17 | 125 |
| C activity-core | C1 13 · C2 5 | 18 |
| D ops-hub / fin-hub / the-custodian | D1 11 · D2 10 · D3 2 | 23 |
| E retire | E1 17 · E2 13 · E3 1 · E4 9 | 40 |
| Keep | schema-history 43, ops-automation 1, connectivity 1 |
45 |
| Ops dependencies | see below | 9 |
| Total | 425 |
Wave A totals 165 rather than the owner table's 167, and Wave B 125 rather than
128: the difference is ops_dependency items, which carry no capability and
so attach to no capability slice.
Ops dependencies (9 items, no capability)
| Owner | Disposition | Items | Handling |
|---|---|---|---|
hub-core |
move / replace / keep | 3 | ride with Wave B; confirm at B4 |
ops-hub |
replace | 2 | ride with D1 |
state-hub-until-cutover |
retire | 2 | T06 freeze window |
activity-core |
keep | 1 | keep to cutover |
ops-bridge |
keep | 1 | keep — external dependency, survives retirement |
These are infrastructure couplings (DB, scheduler, tunnel), not API surface. They cannot be strangled behind a flag and are dispositioned at the freeze window instead. Worth an explicit owner confirmation during T04 so none is discovered live at cutover.
Next actions
- Resolve the legacy-meter window discrepancy above — it gates E2 and T05.
- Implement
RM_SLICE_REGISTERS(A3) first as the pattern proof. - Do not open Wave B until HUB-WP-0004 reaches
ready.