state-hub/workplans/STATE-WP-0079-retirement-strangler.md
tegwick 93e95f93e7
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Build and Publish Multi-Context Image / build-and-push (push) Successful in 28s
feat(legacy-meter): scale retirement quiet period to call volume
A clean review window only proves an interface was silent for that window.
For a heavily used interface that is weak evidence -- an infrequent caller
can fall outside the window entirely, so the interface reads as retirable
while still having consumers.

_retirement_state now also requires silence since last_seen_at, scaled by
all-time volume (RETIREMENT_QUIET_LADDER): 7d under 100 calls, 30d under
10k, 60d above. Existing guards (retired / manual hold / replacement ref /
replacement verified / in-window traffic) still take precedence.

On the 2026-08-20 capture this makes 15 of 19 legacy interfaces retirable
and holds 4: the three six-figure /workstreams/ read paths, and
GET /tasks/?workstream_id which still has live traffic.

Unblocks the bulk of Wave E2 in the cutover slice plan. 7 new tests.

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

6.6 KiB
Raw Blame History

id type title domain repo status owner topic_slug created updated parent_project parent_workplan related state_hub_workstream_id
STATE-WP-0079 workplan State Hub retirement strangler and disposition execution infotech state-hub active codex infotech 2026-08-09 2026-08-19 prj-state-hub-retirement SHR-WP-0001
STATE-WP-0074
SHR-INV-0001
RMGR-WP-0001
HUB-WP-0004
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

id: STATE-WP-0079-T01
status: todo
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).

Capability strangler plan

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

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

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.pyINTENT.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

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

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

  • Freeze policy documented
  • Strangler plan covers all inventory capabilities
  • 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