2026-08-19 23:44:27 +02:00
|
|
|
|
# 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:
|
|
|
|
|
|
|
|
|
|
|
|
1. **A slice cannot move before its owner can receive it.** Owner readiness is
|
|
|
|
|
|
the owner repo's own workplan status, not an assertion here.
|
|
|
|
|
|
2. **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? |
|
|
|
|
|
|
| --- | --- | --- | --- | --- |
|
docs(STATE-WP-0079): correct repo-manager owner readiness, withdraw A3 recommendation
The T02 slice plan marked all 167 repo-manager items receivable because
RMGR-WP-0001/0002/0003 are finished. That reads readiness off workplan
status, which is too coarse.
Verified against repo-manager/src/repo_manager/: those workplans delivered
work-record dual-run, repository observation, and scaffolding. parse/ holds
only workplan.py, and the source tree contains no reference to sbom,
repo_goal, contribution, technical_debt, or extension_point.
Only A1 (partial) and A2 are receivable -- 86 items, not 165. A3, A4 and A5
have no owner-side surface. A3 was recommended twice as the low-blast-radius
first cut; it is in fact the least ready slice in Wave A. Recommendation
withdrawn.
Critical path moves to repo-manager: a workplan there must build the
register, UI, and topic surfaces. Building them here is inadmissible under
policies/retirement-freeze.md. First executable slice is A2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:46:04 +02:00
|
|
|
|
| `repo-manager` | 167 | RMGR-WP-0001/0002/0003 | `finished` | **Partial — see correction below** |
|
2026-08-19 23:44:27 +02:00
|
|
|
|
| `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 |
|
|
|
|
|
|
|
docs(STATE-WP-0079): correct repo-manager owner readiness, withdraw A3 recommendation
The T02 slice plan marked all 167 repo-manager items receivable because
RMGR-WP-0001/0002/0003 are finished. That reads readiness off workplan
status, which is too coarse.
Verified against repo-manager/src/repo_manager/: those workplans delivered
work-record dual-run, repository observation, and scaffolding. parse/ holds
only workplan.py, and the source tree contains no reference to sbom,
repo_goal, contribution, technical_debt, or extension_point.
Only A1 (partial) and A2 are receivable -- 86 items, not 165. A3, A4 and A5
have no owner-side surface. A3 was recommended twice as the low-blast-radius
first cut; it is in fact the least ready slice in Wave A. Recommendation
withdrawn.
Critical path moves to repo-manager: a workplan there must build the
register, UI, and topic surfaces. Building them here is inadmissible under
policies/retirement-freeze.md. First executable slice is A2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:46:04 +02:00
|
|
|
|
Only the `repo-manager` lane is unblocked today, and **only partly** — see the
|
|
|
|
|
|
correction immediately below. Everything else is waiting on an owner-side
|
|
|
|
|
|
contract, not on State Hub.
|
|
|
|
|
|
|
|
|
|
|
|
### Correction (2026-08-20): repo-manager readiness is per-capability
|
|
|
|
|
|
|
|
|
|
|
|
The table above reads owner readiness off workplan status, which is too coarse.
|
|
|
|
|
|
RMGR-WP-0001/0002/0003 are `finished`, but what they delivered is **work-record
|
|
|
|
|
|
dual-run, repository observation, and scaffolding** — not a general register
|
|
|
|
|
|
surface. Verified against `repo-manager/src/repo_manager/` on 2026-08-20:
|
|
|
|
|
|
|
|
|
|
|
|
| `rmgr` surface | Covers | Slice |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `observe`, `load_classification` | repository representation, classification | A1 (partial) |
|
|
|
|
|
|
| `reconcile`, `index_store`, `parse/workplan.py`, `task-status`, `dual_run` | work records | A2 |
|
|
|
|
|
|
| `conform`, `standards.py`, `scaffold` | standards, onboarding | A1 `repo-onboarding` (already cut over) |
|
|
|
|
|
|
| `prefix` | workplan prefix registry | A1 (partial) |
|
|
|
|
|
|
|
|
|
|
|
|
`parse/` contains **only** `workplan.py`. A grep for `sbom`, `repo_goal`,
|
|
|
|
|
|
`contribution`, `technical_debt`, and `extension_point` across the whole source
|
|
|
|
|
|
tree returns **nothing**.
|
|
|
|
|
|
|
|
|
|
|
|
**Consequence:** A3, A4, and A5 have no owner-side surface to receive them.
|
|
|
|
|
|
|
|
|
|
|
|
| Slice | Items | Receivable? |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| A1 repository registry | 27 | Partial — `observe`/`conform` cover representation; registry CRUD does not exist |
|
|
|
|
|
|
| A2 work records | 59 | **Yes** — this is exactly what RMGR-WP-0002/0003 proved |
|
|
|
|
|
|
| A3 registers | 49 | **No** — no register surface of any kind in repo-manager |
|
|
|
|
|
|
| A4 work + repo UI | 22 | **No** — `rmgr` is a CLI; there is no owner-side dashboard |
|
|
|
|
|
|
| A5 topic spine | 8 | **No** — no topic/classification contract beyond `observe` |
|
|
|
|
|
|
|
|
|
|
|
|
The near-term executable surface is therefore **A1 + A2, not 165 items**, and
|
|
|
|
|
|
A2 is the only slice with a proven adapter.
|
|
|
|
|
|
|
|
|
|
|
|
**A3 is not the low-blast-radius first cut this plan originally recommended** —
|
|
|
|
|
|
it is the least ready slice in Wave A. The recommendation is withdrawn.
|
|
|
|
|
|
|
|
|
|
|
|
**Do not build the register surface in State Hub.** New register capability here
|
|
|
|
|
|
would be new permanent ownership in the component being retired, which
|
|
|
|
|
|
`policies/retirement-freeze.md` makes inadmissible. A3/A4/A5 need a
|
|
|
|
|
|
`repo-manager` workplan; RMGR-WP-0004 (standards conformance) and RMGR-WP-0005
|
|
|
|
|
|
(registrar consolidation) do not cover them.
|
2026-08-19 23:44:27 +02:00
|
|
|
|
|
|
|
|
|
|
## 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`, evidence
|
|
|
|
|
|
`repo-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.
|
|
|
|
|
|
|
docs(STATE-WP-0079): A2 readiness detail and dual-run state
Applied the A3 readiness check one level down. The State Hub adapter exposes
exactly three operations: rm_update_task_status, rm_reconcile, rm_scaffold.
No adapter for workplan CRUD, intake, decision, dependency or human-flag
records, and no repo-manager parser for them either.
A2 splits into A2a (task status + reconcile, ~6 items, receivable) and
A2b-A2e (~32 items, not receivable). A2a is the only slice in the plan
executable today -- roughly 6 of 425 inventory items.
Also records that dual-run is currently off entirely: no config file,
writeback and reconcile false, no pilot repos. The 23 metered mutations are
RMGR-WP-0002/0003 pilot residue. A2a's next step is operational, not code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:50:01 +02:00
|
|
|
|
### A2 readiness detail (2026-08-20)
|
|
|
|
|
|
|
|
|
|
|
|
Same check as for A3, applied one level down. The State Hub adapter
|
|
|
|
|
|
(`api/services/repo_manager_dual_run.py`) exposes exactly three operations:
|
|
|
|
|
|
|
|
|
|
|
|
| Adapter function | Routes to | Covers |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `rm_update_task_status` | `rmgr task-status` | task status writes |
|
|
|
|
|
|
| `rm_reconcile` | `rmgr reconcile` | work-record index rebuild |
|
|
|
|
|
|
| `rm_scaffold` | `rmgr scaffold` | repo scaffolding (A1 `repo-onboarding`, already cut over) |
|
|
|
|
|
|
|
|
|
|
|
|
There is no adapter for workplan create/update/delete, intake, decision,
|
|
|
|
|
|
dependency, or human-flag records — and no parser for them on the repo-manager
|
|
|
|
|
|
side either (`parse/` is `workplan.py` only). So A2 splits:
|
|
|
|
|
|
|
|
|
|
|
|
| Sub-slice | Items | Receivable |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| **A2a** task status + reconcile | ~6 (`update_task_status`, `bulk_update_task_statuses`, `PATCH /tasks/{id}`, `POST /tasks/bulk-status-sync`, index refresh job, `table:tasks`) | **Yes — adapter exists and was proven by RMGR-WP-0002/0003** |
|
|
|
|
|
|
| A2b workplan CRUD | ~9 routes + `table:workplans` | No adapter; repo-manager parses workplans but exposes no write path |
|
|
|
|
|
|
| A2c intake | 9 | No parser, no adapter |
|
|
|
|
|
|
| A2d decision | 8 | No parser, no adapter |
|
|
|
|
|
|
| A2e dependencies + human-flag | ~6 | No parser, no adapter |
|
|
|
|
|
|
|
|
|
|
|
|
**A2a is the only slice in the entire plan that is executable today**, and it is
|
|
|
|
|
|
roughly 6 items, not 59.
|
|
|
|
|
|
|
|
|
|
|
|
### Dual-run is currently off
|
|
|
|
|
|
|
|
|
|
|
|
`rmgr dual-run-status` on 2026-08-20:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
config_exists: false writeback: false reconcile: false pilot_repos: null
|
|
|
|
|
|
meter: {state-hub: 15, repo-manager: 8, total: 23}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
The 23 metered mutations are the RMGR-WP-0002/0003 pilot runs. Nothing is
|
|
|
|
|
|
dual-running now — the adapter is proven but switched off, and there is no
|
|
|
|
|
|
`~/.repo-manager/dual-run.yaml`.
|
|
|
|
|
|
|
|
|
|
|
|
**So the concrete next executable step is operational, not code:** create the
|
2026-08-20 09:02:57 +02:00
|
|
|
|
dual-run config and enable `RM_WRITEBACK` + `RM_RECONCILE`, then watch the
|
|
|
|
|
|
mutation meter for divergence. That is A2a moving from `off` to `dual`.
|
|
|
|
|
|
|
|
|
|
|
|
**The pilot repo is already established — `repo-manager`**, per RMGR-WP-0003 and
|
|
|
|
|
|
the shipped `repo-manager/config/dual-run.pilot.example.yaml`. No new decision
|
|
|
|
|
|
is needed about which repo; the procedure is documented in
|
|
|
|
|
|
`repo-manager/docs/dual-run.md`:
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
mkdir -p ~/.repo-manager
|
|
|
|
|
|
cp ~/repo-manager/config/dual-run.pilot.example.yaml ~/.repo-manager/dual-run.yaml
|
|
|
|
|
|
# then restart the State Hub API — settings are cached per process
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
Rollback is `rm ~/.repo-manager/dual-run.yaml` plus a restart, or setting
|
|
|
|
|
|
`writeback`/`reconcile` false.
|
|
|
|
|
|
|
|
|
|
|
|
**Requires an operator**, for one reason only: it changes how live task writes
|
|
|
|
|
|
flow and needs a State Hub API restart to take effect. Piloting on
|
|
|
|
|
|
`repo-manager` keeps the blast radius to a single repo.
|
docs(STATE-WP-0079): A2 readiness detail and dual-run state
Applied the A3 readiness check one level down. The State Hub adapter exposes
exactly three operations: rm_update_task_status, rm_reconcile, rm_scaffold.
No adapter for workplan CRUD, intake, decision, dependency or human-flag
records, and no repo-manager parser for them either.
A2 splits into A2a (task status + reconcile, ~6 items, receivable) and
A2b-A2e (~32 items, not receivable). A2a is the only slice in the plan
executable today -- roughly 6 of 425 inventory items.
Also records that dual-run is currently off entirely: no config file,
writeback and reconcile false, no pilot repos. The 23 metered mutations are
RMGR-WP-0002/0003 pilot residue. A2a's next step is operational, not code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:50:01 +02:00
|
|
|
|
|
2026-08-19 23:44:27 +02:00
|
|
|
|
### 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` |
|
2026-08-21 23:15:34 +02:00
|
|
|
|
| Owner API | `rmgr register ...`; `rmgr sbom scan|licence-report` |
|
|
|
|
|
|
| Rollback | flag → `off`; retain current State Hub projection |
|
docs(STATE-WP-0079): correct repo-manager owner readiness, withdraw A3 recommendation
The T02 slice plan marked all 167 repo-manager items receivable because
RMGR-WP-0001/0002/0003 are finished. That reads readiness off workplan
status, which is too coarse.
Verified against repo-manager/src/repo_manager/: those workplans delivered
work-record dual-run, repository observation, and scaffolding. parse/ holds
only workplan.py, and the source tree contains no reference to sbom,
repo_goal, contribution, technical_debt, or extension_point.
Only A1 (partial) and A2 are receivable -- 86 items, not 165. A3, A4 and A5
have no owner-side surface. A3 was recommended twice as the low-blast-radius
first cut; it is in fact the least ready slice in Wave A. Recommendation
withdrawn.
Critical path moves to repo-manager: a workplan there must build the
register, UI, and topic surfaces. Building them here is inadmissible under
policies/retirement-freeze.md. First executable slice is A2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:46:04 +02:00
|
|
|
|
|
2026-08-21 23:15:34 +02:00
|
|
|
|
**Owner ready (2026-08-21).** Finished RMGR-WP-0008 supplies the shared six-kind
|
|
|
|
|
|
register spine, governed compatibility adapter, lockfile-derived SBOM and
|
|
|
|
|
|
licence/copyleft report. Historical SBOM rows are cache provenance; rebuild
|
|
|
|
|
|
from current repository sources rather than copying them into authority.
|
2026-08-19 23:44:27 +02:00
|
|
|
|
|
|
|
|
|
|
### A4 · Work + repo UI — 22 items
|
|
|
|
|
|
`work-coordination-ui` (14, `replace`) · `repo-ui` (8)
|
|
|
|
|
|
|
|
|
|
|
|
| | |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| Flag | `RM_SLICE_UI` |
|
2026-08-21 23:15:34 +02:00
|
|
|
|
| Owner API | hub-core projection/query plus hub/ops UI clients |
|
2026-08-19 23:44:27 +02:00
|
|
|
|
| Rollback | remove redirect; hub pages are unchanged behind it |
|
|
|
|
|
|
|
|
|
|
|
|
`replace`, not `move`: the contract changes. Must follow A1–A3, since the pages
|
2026-08-21 23:15:34 +02:00
|
|
|
|
render what those slices serve. RMGR-ADR-003 corrects the earlier inventory
|
|
|
|
|
|
assignment: Repo Manager owns the repository contracts, not a dashboard. A4's
|
|
|
|
|
|
UI implementation therefore rides with B5 even though these 22 inventory items
|
|
|
|
|
|
remain grouped here for traceability.
|
2026-08-19 23:44:27 +02:00
|
|
|
|
|
|
|
|
|
|
### A5 · Topic spine — 8 items
|
|
|
|
|
|
`topic-spine` (8, `replace`)
|
|
|
|
|
|
|
|
|
|
|
|
| | |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| Flag | `RM_SLICE_TOPICSPINE` |
|
|
|
|
|
|
| Owner API | `rmgr` topic/classification contract |
|
|
|
|
|
|
| Rollback | flag → `off` |
|
|
|
|
|
|
|
2026-08-21 23:15:34 +02:00
|
|
|
|
The versioned Repo Manager classification contract is published and accepted by
|
|
|
|
|
|
finished HUB-WP-0004. Consumer route switching remains a State Hub cutover
|
|
|
|
|
|
action.
|
2026-08-19 23:44:27 +02:00
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
2026-08-21 23:15:34 +02:00
|
|
|
|
## Wave B — hub-core (128 items) · HUB-WP-0004 owner gate satisfied
|
2026-08-19 23:44:27 +02:00
|
|
|
|
|
2026-08-21 23:15:34 +02:00
|
|
|
|
HUB-WP-0004 finished 2026-08-21 and accepted the project architecture, runtime,
|
|
|
|
|
|
ports, conformance scaffold, and absorption plan. Individual production
|
|
|
|
|
|
cutovers still require their slice evidence and operator gates.
|
2026-08-19 23:44:27 +02:00
|
|
|
|
|
|
|
|
|
|
| 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 |
|
|
|
|
|
|
| --- | --- | --- | --- |
|
2026-08-20 07:42:00 +02:00
|
|
|
|
| E1 | `suggestion-backlog` → archive | 17 | history archived 2026-08-20; read surface + dashboard remain |
|
2026-08-20 01:12:37 +02:00
|
|
|
|
| E2 | `work-records-workplan-legacy` → archive | 13 | legacy-meter — candidate rule, see below |
|
2026-08-20 08:11:14 +02:00
|
|
|
|
| E3 | `dashboard-meta` (`/ui-feedback`) | 1 | T06 freeze window — owner is `state-hub-until-cutover` |
|
2026-08-19 23:44:27 +02:00
|
|
|
|
| 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.
|
|
|
|
|
|
|
2026-08-20 07:42:00 +02:00
|
|
|
|
### E1 status (2026-08-20)
|
|
|
|
|
|
|
|
|
|
|
|
Already half-retired before this plan: mutations have returned HTTP 410 since
|
|
|
|
|
|
2026-07-21 (`CUST-WP-0061-T06`), pointing at `POST /intakes/`. Reads were kept
|
|
|
|
|
|
live so the historical record stayed reachable.
|
|
|
|
|
|
|
|
|
|
|
|
**History is now archived** at `the-custodian/docs/archived-suggestion-backlog.md`
|
|
|
|
|
|
— all 10 suggestions, 10 notes, and 5 relevance bumps, with each entry's
|
|
|
|
|
|
migration target. Every entry was `declined` in the intake migration and none
|
|
|
|
|
|
was promoted, so nothing forward-looking is lost by removing the surface.
|
|
|
|
|
|
|
2026-08-20 08:11:14 +02:00
|
|
|
|
**Executed 2026-08-20.** The 8 read routes now 410 with a pointer to intake and
|
|
|
|
|
|
to the archive, the 6 MCP tools are removed (not stubbed — a retired tool that
|
|
|
|
|
|
still appears in the tool list costs every agent session context on every call),
|
|
|
|
|
|
the 5 `/suggestions` write-idempotency rules are gone, and the dashboard page is
|
|
|
|
|
|
deleted with its nav entry, `reference.md` row, and `wsjf-triage.md` link
|
|
|
|
|
|
updated. `dashboard/src/docs/suggestions.md` is rewritten as the archive
|
|
|
|
|
|
pointer. Tables stay for the T06 dump.
|
|
|
|
|
|
|
|
|
|
|
|
One naming trap worth recording: **`ui-feedback.md` and `todo.md` "suggestions"
|
|
|
|
|
|
are a different entity** — Shift+click dashboard feedback backed by
|
|
|
|
|
|
`technical_debt`, not the suggestion backlog. They are untouched. Anything
|
|
|
|
|
|
grepping for `suggestion` during cutover will hit them.
|
|
|
|
|
|
|
|
|
|
|
|
### E3 status (2026-08-20)
|
|
|
|
|
|
|
|
|
|
|
|
`dashboard-meta` is the `/ui-feedback` page — the feedback scratch surface just
|
|
|
|
|
|
mentioned. Its owner is `state-hub-until-cutover` and it is still in active use,
|
|
|
|
|
|
so it retires **at the T06 freeze window**, not before. Removing it now would
|
|
|
|
|
|
delete a working feedback loop during the retirement it serves. No action.
|
2026-08-20 07:42:00 +02:00
|
|
|
|
|
2026-08-20 01:12:37 +02:00
|
|
|
|
### E2 evidence — defect found and partly fixed (2026-08-20)
|
2026-08-19 23:44:27 +02:00
|
|
|
|
|
2026-08-20 01:12:37 +02:00
|
|
|
|
The window discrepancy flagged on 2026-08-19 was a real defect in
|
|
|
|
|
|
`scripts/capture_legacy_meter_evidence.py`, not a labelling nit.
|
2026-08-19 23:44:27 +02:00
|
|
|
|
|
2026-08-20 01:12:37 +02:00
|
|
|
|
`_review_query` fell back to `hours=8` whenever `--days` was omitted, and
|
|
|
|
|
|
`--hours` defaulted to `8`. Every unattended capture therefore sampled an
|
|
|
|
|
|
8-hour band (06:00Z–14:00Z) while writing a file named `weekly-review` with
|
|
|
|
|
|
`cadence: weekly` in the payload. **39 of 40 captures ran this way** — only the
|
|
|
|
|
|
first, 2026-07-08, used a true 7-day window.
|
|
|
|
|
|
|
|
|
|
|
|
Calls in the other 16 hours of each day were never sampled, so quiet-in-band
|
|
|
|
|
|
interfaces were reported as retirement candidates while still having live
|
|
|
|
|
|
callers. On the 2026-08-19 capture three candidates had recent traffic:
|
|
|
|
|
|
|
|
|
|
|
|
| Interface | All-time calls | Last seen |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `GET /tasks/?workstream_id` | 594 | 2026-08-18 |
|
|
|
|
|
|
| `GET /progress/?workstream_id` | 2 | 2026-08-12 |
|
|
|
|
|
|
| `GET /workstreams/` | 144 086 | 2026-08-10 |
|
|
|
|
|
|
|
|
|
|
|
|
**Fixed:** the script now defaults to `days=7`, matching the endpoint name and
|
|
|
|
|
|
the cadence label. `--hours` is retained for spot checks and documented as not
|
|
|
|
|
|
retirement evidence. Corrected capture:
|
|
|
|
|
|
`docs/evidence/legacy-meter-weekly-review-20260820.json` — 18 candidates of 20
|
|
|
|
|
|
interfaces, `GET /tasks/?workstream_id` correctly excluded.
|
|
|
|
|
|
|
2026-08-20 07:13:44 +02:00
|
|
|
|
**Candidate rule tightened (2026-08-20).** `_retirement_state` now requires a
|
|
|
|
|
|
quiet period scaled to all-time call volume, because a clean window only proves
|
|
|
|
|
|
silence for that window — for a heavily used interface an infrequent caller can
|
|
|
|
|
|
fall outside it entirely. `RETIREMENT_QUIET_LADDER` in
|
|
|
|
|
|
`api/services/legacy_meter.py`:
|
2026-08-20 01:12:37 +02:00
|
|
|
|
|
2026-08-20 07:13:44 +02:00
|
|
|
|
| All-time calls | Days since `last_seen_at` required |
|
|
|
|
|
|
| --- | --- |
|
|
|
|
|
|
| 0 | none — never used |
|
|
|
|
|
|
| 1 – 99 | 7 |
|
|
|
|
|
|
| 100 – 9 999 | 30 |
|
|
|
|
|
|
| 10 000+ | 60 |
|
|
|
|
|
|
|
|
|
|
|
|
Applied to the 2026-08-20 capture this splits the 19 legacy interfaces cleanly:
|
2026-08-20 01:12:37 +02:00
|
|
|
|
|
2026-08-20 07:13:44 +02:00
|
|
|
|
**15 retirable** — all four `workstream` MCP tools, the `state://` resource, and
|
|
|
|
|
|
the low-volume REST aliases, plus `PATCH /workstreams/{id}` (571 calls, quiet
|
|
|
|
|
|
42d), `POST /workstreams/` (824, quiet 42d) and
|
|
|
|
|
|
`POST /workstreams/{id}/dependencies/` (4 971, quiet 49d).
|
2026-08-20 01:12:37 +02:00
|
|
|
|
|
2026-08-20 07:13:44 +02:00
|
|
|
|
**4 held:**
|
|
|
|
|
|
|
|
|
|
|
|
| Interface | All-time calls | Reason |
|
|
|
|
|
|
| --- | --- | --- |
|
|
|
|
|
|
| `GET /tasks/?workstream_id` | 595 | traffic inside the window |
|
|
|
|
|
|
| `GET /workstreams/` | 144 086 | quiet 9d of 60d |
|
|
|
|
|
|
| `GET /workstreams/{id}` | 511 406 | quiet 19d of 60d |
|
|
|
|
|
|
| `GET /workstreams/{id}/dependencies/` | 255 865 | quiet 42d of 60d |
|
|
|
|
|
|
|
2026-08-20 07:28:54 +02:00
|
|
|
|
**Executed 2026-08-20:** the 15 are retired; the meter reads 16 retired / 4
|
|
|
|
|
|
legacy with 0 outstanding candidates. Journalled at
|
|
|
|
|
|
`the-custodian/docs/retired-legacy-interfaces.md`. The four
|
2026-08-20 07:13:44 +02:00
|
|
|
|
held are the three six-figure read paths and the one with live traffic — exactly
|
|
|
|
|
|
the set where a false retirement would hurt most. They clear on their own as the
|
|
|
|
|
|
quiet counter runs, provided no new traffic arrives; the earliest,
|
|
|
|
|
|
`GET /workstreams/{id}/dependencies/`, needs 18 more silent days.
|
|
|
|
|
|
|
|
|
|
|
|
Re-check before executing E2: the ladder is evaluated at review time, so a
|
|
|
|
|
|
capture older than the retirement decision is not evidence for it.
|
2026-08-19 23:44:27 +02:00
|
|
|
|
|
|
|
|
|
|
## 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
|
|
|
|
|
|
|
docs(STATE-WP-0079): correct repo-manager owner readiness, withdraw A3 recommendation
The T02 slice plan marked all 167 repo-manager items receivable because
RMGR-WP-0001/0002/0003 are finished. That reads readiness off workplan
status, which is too coarse.
Verified against repo-manager/src/repo_manager/: those workplans delivered
work-record dual-run, repository observation, and scaffolding. parse/ holds
only workplan.py, and the source tree contains no reference to sbom,
repo_goal, contribution, technical_debt, or extension_point.
Only A1 (partial) and A2 are receivable -- 86 items, not 165. A3, A4 and A5
have no owner-side surface. A3 was recommended twice as the low-blast-radius
first cut; it is in fact the least ready slice in Wave A. Recommendation
withdrawn.
Critical path moves to repo-manager: a workplan there must build the
register, UI, and topic surfaces. Building them here is inadmissible under
policies/retirement-freeze.md. First executable slice is A2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:46:04 +02:00
|
|
|
|
1. ~~Resolve the legacy-meter window discrepancy~~ — done 2026-08-20; E1 and the
|
|
|
|
|
|
evidenced part of E2 are executed.
|
2026-08-21 23:15:34 +02:00
|
|
|
|
2. ~~Build the Repo Manager receiving surface for A3/A5 and settle A4
|
|
|
|
|
|
ownership~~ — finished in RMGR-WP-0008. A4 belongs to hub-core projection UI,
|
|
|
|
|
|
not Repo Manager.
|
docs(STATE-WP-0079): A2 readiness detail and dual-run state
Applied the A3 readiness check one level down. The State Hub adapter exposes
exactly three operations: rm_update_task_status, rm_reconcile, rm_scaffold.
No adapter for workplan CRUD, intake, decision, dependency or human-flag
records, and no repo-manager parser for them either.
A2 splits into A2a (task status + reconcile, ~6 items, receivable) and
A2b-A2e (~32 items, not receivable). A2a is the only slice in the plan
executable today -- roughly 6 of 425 inventory items.
Also records that dual-run is currently off entirely: no config file,
writeback and reconcile false, no pilot repos. The 23 metered mutations are
RMGR-WP-0002/0003 pilot residue. A2a's next step is operational, not code.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:50:01 +02:00
|
|
|
|
3. Cut **A2a** (task status + reconcile, ~6 items) — the only slice in the plan
|
|
|
|
|
|
executable today. First step is operational: create `~/.repo-manager/dual-run.yaml`
|
|
|
|
|
|
and enable writeback/reconcile for one pilot repo, then watch the mutation
|
|
|
|
|
|
meter. A2b–A2e need repo-manager parsers and adapters that do not exist.
|
2026-08-21 23:15:34 +02:00
|
|
|
|
4. HUB-WP-0004's owner-readiness gate is satisfied; advance Wave B only through
|
|
|
|
|
|
its per-slice dual-run and operator gates.
|
docs(STATE-WP-0079): correct repo-manager owner readiness, withdraw A3 recommendation
The T02 slice plan marked all 167 repo-manager items receivable because
RMGR-WP-0001/0002/0003 are finished. That reads readiness off workplan
status, which is too coarse.
Verified against repo-manager/src/repo_manager/: those workplans delivered
work-record dual-run, repository observation, and scaffolding. parse/ holds
only workplan.py, and the source tree contains no reference to sbom,
repo_goal, contribution, technical_debt, or extension_point.
Only A1 (partial) and A2 are receivable -- 86 items, not 165. A3, A4 and A5
have no owner-side surface. A3 was recommended twice as the low-blast-radius
first cut; it is in fact the least ready slice in Wave A. Recommendation
withdrawn.
Critical path moves to repo-manager: a workplan there must build the
register, UI, and topic surfaces. Building them here is inadmissible under
policies/retirement-freeze.md. First executable slice is A2.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 08:46:04 +02:00
|
|
|
|
5. Do not build register, UI, or topic capability in State Hub to unblock
|
|
|
|
|
|
items 2–3 — `policies/retirement-freeze.md` makes that inadmissible.
|