state-hub/workplans/STATE-WP-0079-retirement-strangler.md
tegwick 64b71320e7
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
docs(STATE-WP-0079): retirement freeze policy, close T01
States the four admissible reasons for a change to state-hub during
retirement -- preserve compatibility, enable extraction, reduce scope, fix
operational risk -- and the inadmissible case: establishing new permanent
ownership in the component being retired.

The operative test is 'where does this live after cutover?', not 'is this a
good change?' Most inadmissible changes are good changes; STATE-WP-0080's
retarget to RMGR-WP-0004 is the worked example.

Enforced by review rather than new automation: a freeze-checker built inside
State Hub would itself be new permanent automation here, so the policy would
violate itself. New tables/routes/MCP tools are the one hard stop.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 07:20:56 +02:00

190 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: STATE-WP-0079
type: workplan
title: "State Hub retirement strangler and disposition execution"
domain: infotech
repo: state-hub
status: active
owner: codex
topic_slug: infotech
created: "2026-08-09"
updated: "2026-08-19"
parent_project: prj-state-hub-retirement
parent_workplan: SHR-WP-0001
related:
- STATE-WP-0074
- SHR-INV-0001
- RMGR-WP-0001
- HUB-WP-0004
state_hub_workstream_id: "749beac6-3c62-4284-aab5-9ed7fce900c2"
---
# State Hub retirement strangler and disposition execution
## Goal
Execute the **keep/move/replace/retire** dispositions from
`prj-state-hub-retirement/inventory` via strangler adapters and owner handoffs,
without adding new permanent authorities here. End state: freeze window with no
normal traffic, then archive.
## Dual-run handoff (RMGR-WP-0002)
Repo Manager Stage B dual-run is available:
- Flags: `RM_WRITEBACK`, `RM_RECONCILE`, `RM_PILOT_REPOS` (see `repo-manager/docs/dual-run.md`)
- SH adapter: `api/services/repo_manager_dual_run.py` (PATCH `/tasks` + C-15 writeback + reconcile proxy)
- Evidence: `repo-manager/docs/evidence/wp0002-completion.md`
Expand pilot list here as cutover progresses; do not add new checkout mutators in State Hub.
## Freeze policy for new scope
```task
id: STATE-WP-0079-T01
status: done
priority: high
state_hub_task_id: "375c0b66-98b0-4d5b-98dd-4ad2883a4051"
```
Document and enforce: changes during retirement must preserve compatibility,
enable extraction, reduce scope, or fix operational risk — not establish new
permanent ownership (INTENT retirement status).
**Result (2026-08-20):** `policies/retirement-freeze.md`, following the existing
`policies/` convention. States the four admissible reasons, the inadmissible
case (new permanent ownership here), and the operative test — *where does this
live after cutover?* — since most inadmissible changes are otherwise good
changes. Uses `STATE-WP-0080`'s retarget as the worked example.
**Enforced by review, not by new automation.** A freeze-checker built inside
State Hub would be new permanent automation in the component being retired, so
the policy would violate itself. Gates attach to points where changes are
already reviewed: new workplan goal statements, non-trivial task starts, and
slice execution. New tables, routes, or MCP tools carry a presumption against
and are the one hard stop.
## Capability strangler plan
```task
id: STATE-WP-0079-T02
status: done
priority: high
state_hub_task_id: "595c3936-20b6-453f-92b5-84f86798054a"
```
Group SHR-INV-0001 items into cutover slices (repo/work → repo-manager;
messages/progress/projections → hub-core; catalogs → owners; retire aliases).
Per slice: adapter flag, owner API, rollback.
**Result (2026-08-19):** `docs/retirement-cutover-slice-plan.md`. All 425
inventory items assigned to 19 slices in five waves plus Keep, computed against
`state-hub-disposition.yaml` rather than hand-counted. Each slice carries an
`RM_SLICE_*` flag (off/dual/owner), owner API, and rollback; Wave A reuses the
RMGR-WP-0002/0003 dual-run adapter rather than adding a mechanism.
Owner readiness verified: only **Wave A (repo-manager, 165 items)** is
executable — RMGR-WP-0001/0002/0003 are `finished`. Wave B is gated on
HUB-WP-0004 (`proposed`), D1 on OPS-WP-0003 (`proposed`), D2 on FIN-WP-0003
(`proposed`). Recommended first cut is A3 (registers), lowest blast radius.
Two findings for T04/T05: the 9 `ops_dependency` items carry no capability and
cannot be strangled behind a flag — they resolve at the T06 freeze window; and
the legacy-meter review window is 8 hours despite `cadence: weekly`, which is
not sufficient evidence to retire high-volume `/workstreams/` interfaces (E2).
## Register CLI and GOAL.md support
```task
id: STATE-WP-0079-T03
status: done
priority: medium
state_hub_task_id: "55716f12-fb12-4a1e-a770-076c490db111"
```
Adapt `statehub register` / scaffolding so `prj-` repos with `GOAL.md` and
`repo_flavor: project` are valid without inventing durable-product `INTENT.md`
(residual from SHR-WP-0001-T01).
**Result (2026-08-19):** Implemented by `STATE-WP-0080-T01/T02`. Project
flavor is detected from classification, `GOAL.md`, or the `prj-` slug; a repo
with an existing `GOAL.md` is registered without durable scaffolding, while a
fresh project delegates scaffolding to `rmgr scaffold`. The focused State Hub
registration suite passes (`20 passed`).
## Execute move/replace slices
```task
id: STATE-WP-0079-T04
status: todo
priority: high
state_hub_task_id: "db5291f2-3801-40fa-abf2-ceb0e77687c9"
```
Implement strangler handoffs coordinated with RMGR-WP-0001 and HUB-WP-0004.
Compatibility tests for each dispositioned route family.
**Inherited (2026-08-19) from `STATE-WP-0080-T04`:** this slice now also owns
deletion of the templating path in `statehub_register.py``INTENT.md`
generation, the `AGENTS.md` / `CLAUDE.md` / `.custodian-brief.md` templates,
`project_rules/`, and bootstrap-workplan generation. The code is dead-but-present:
project repos are already routed to `rmgr scaffold`. Gate the deletion on
`RMGR-WP-0004-T06` proving byte-identical durable output and idempotent
re-scaffolding.
## Retire legacy surfaces
```task
id: STATE-WP-0079-T05
status: todo
priority: medium
state_hub_task_id: "02e508ed-3cde-4487-907e-d324a8a877d6"
```
Complete retirement of suggestions, workstream aliases, and other `retire`
inventory items once meters/callers allow. Keep historical rows archive-readable.
**Blocker identified (2026-08-20):** the legacy-meter evidence this task gates
on was being captured over an 8-hour band, not a week —
`capture_legacy_meter_evidence.py` fell back to `hours=8` whenever `--days` was
omitted, so 39 of 40 captures sampled only 06:00Z14:00Z. Interfaces called
outside that band read as unused. Three candidates on the 2026-08-19 capture had
live callers, including `GET /tasks/?workstream_id` (seen 2026-08-18).
Script default corrected to `days=7`; corrected capture
`docs/evidence/legacy-meter-weekly-review-20260820.json`.
**Candidate rule tightened (2026-08-20):** `_retirement_state` now requires a
quiet period scaled to all-time call volume (`RETIREMENT_QUIET_LADDER`: 7d under
100 calls, 30d under 10 000, 60d above). On the 2026-08-20 capture this makes 15
of 19 legacy interfaces retirable — all `workstream` MCP tools, the `state://`
resource, and the low-volume REST aliases — while holding the three six-figure
read paths (`GET /workstreams/`, `GET /workstreams/{id}`,
`GET /workstreams/{id}/dependencies/`) and `GET /tasks/?workstream_id`, which
still has live traffic. Covered by 7 new tests in `tests/test_legacy_meter.py`.
**Remaining work for this task:** execute the retirement of the 15 evidenced
interfaces, then re-review the 4 held ones as their quiet counters run. The
ladder is evaluated at review time, so re-capture before deciding. See
`docs/retirement-cutover-slice-plan.md` § E2.
## Stabilization window and archive prep
```task
id: STATE-WP-0079-T06
status: todo
priority: high
state_hub_task_id: "d52c95c6-af3f-4b2c-804e-e07763c9a8ab"
```
With T06 gates: zero normal read/write window, final dump, backup/restore
evidence, stop service, archive repo read-only. Residuals → live owners.
## Acceptance
- [x] Freeze policy documented
- [x] Strangler plan covers all inventory capabilities
- [x] prj-/GOAL.md register path works
- [ ] Move/replace slices evidenced with tests/counts
- [ ] Retire list closed or residual-owned
- [ ] Stabilization + archive prep ready for project retirement