--- id: STATE-WP-0069 type: workplan title: "Workplan terminology legacy retirement (State Hub)" domain: infotech repo: state-hub status: active owner: codex topic_slug: custodian planning_priority: medium planning_order: 69 created: "2026-07-08" updated: "2026-07-09" state_hub_workstream_id: "923bb94a-d16c-422c-b81e-16328bd7b60c" --- # STATE-WP-0069 — Workplan terminology legacy retirement **Parent coordination:** `the-custodian/workplans/CUST-WP-0055-workplan-terminology-fleet-refactor.md` (T02-T01 deliverable). **Prerequisite (finished):** `STATE-WP-0054` added preferred `/workplans` routes, dual-published completion events, `legacy-meter`, and weekly review payloads. Canonical guide: `docs/workplan-terminology-transition.md`. ## Goal Retire State Hub's **metered legacy `workstream` interfaces** in safe phases after `legacy-meter` weekly review shows zero callers. Make `workplan` the only user-facing and integration term inside this repo without breaking ADR-001 file sync or workplan frontmatter bridges. ## Context A fleet scan on **2026-07-08** (`the-custodian/tools/scan_workstream_terminology.py`) shows `state-hub` carries ~13,418 `workstream` string hits — mostly compat routers, tests, dashboard labels, MCP aliases, and legacy-meter registry entries. That volume is expected until this workplan retires interfaces deliberately. Retirement rule (unchanged from STATE-WP-0054): - interface registered as legacy; - replacement reference verified; - no manual hold; - **zero measured calls** in the review window. Activity-core owns the weekly wakeup; State Hub owns usage state and removal. ## Out of scope - Renaming workplan frontmatter field `state_hub_workstream_id` (separate bridge migration). - Physical database table/column renames (STATE-WP-0065 completed the spine). - Fleet-wide domain repo prose sweeps (CUST-WP-0055 T04). - activity-core `org.workstream.completed` catalog alignment (CUST-WP-0055 T03). - Removing `/workstreams` before legacy-meter proves zero callers for each key. ## Grep budget (non-compat prose) Track via `scan_workstream_terminology.py --repo state-hub --json` with `the-custodian` scan allowlist (archives, legacy-meter registry, compat routers excluded once documented in T01). | Phase | Target | | --- | --- | | After T02 | Dashboard nav + `dashboard/src/index.md` prose at zero `prose:workstream` | | After T03 | MCP tool docstrings and error messages workplan-first | | After T04 | Public OpenAPI lists `/workplans` only; `/workstreams` removed or 410 | | After T07 | Total repo hits reduced ≥50% from 2026-07-08 baseline | ## Task: Refresh inventory and ranked retirement backlog ```task id: STATE-WP-0069-T01 status: done priority: high state_hub_task_id: "ffc186e0-807d-4ee4-b11f-3f769af2ab2d" ``` Reconcile `docs/workplan-terminology-transition.md` against the live codebase. Produce `docs/workplan-terminology-legacy-retirement-backlog.md` ranking every remaining legacy interface by: - legacy-meter key; - replacement ref; - risk (REST > MCP > events > dashboard prose); - last-seen and prior-week usage from `/legacy-meter/weekly-review`. Include explicit allowlist paths for grep/scan tooling (compat routers, test fixtures, migration history). Store 2026-07-08 baseline JSON reference from CUST-WP-0055 T01. Done when the backlog is reviewed and each interface has a phase assignment (T02–T06). ## Task: Dashboard and operator docs — workplan-first labels ```task id: STATE-WP-0069-T02 status: done priority: high state_hub_task_id: "996e484e-8cfb-4c9e-8682-c9c3da0c1d72" ``` Update Observable dashboard navigation, page titles, chart empty-state copy, and operator docs to say **workplan** in user-facing prose: - `dashboard/observablehq.config.js` nav entries (`/workstreams` → `/workplans` where routes exist); - `dashboard/src/index.md` and workplan detail pages; - `README.md` legacy table footnotes. Keep URL redirects or compat notes for bookmarked `/workstreams` paths until T04. Add dashboard tests for renamed labels. Done when dashboard `npm test` passes and scan shows zero `prose:workstream` in `dashboard/src/` (excluding explicit legacy footnotes). ## Task: MCP legacy alias retirement ```task id: STATE-WP-0069-T03 status: progress priority: medium state_hub_task_id: "f701aa56-aa06-4d0e-a632-758677e7ac98" ``` Retire MCP surfaces that still lead with `workstream` terminology: - `state://workstreams/{topic_slug}` resource; - any `create_workstream` / `update_workstream` / `list_workstreams` aliases if still registered alongside `create_workplan` variants; - prose in `get_domain_summary` (`open_workstreams`, `needs_workplan` messages). Phase 1: deprecation warnings in tool responses pointing to workplan-named tools. Phase 2: remove aliases when legacy-meter shows zero MCP procedure calls for seven consecutive review windows. Done when MCP clients use workplan-named tools only and legacy MCP keys are removed from the registry or marked `retired` with zero usage. Progress 2026-07-08 (Phase 1): `_deprecation` payloads on all legacy MCP tools and `state://workstreams/{topic_slug}`; `state://workplans/{topic_slug}` preferred resource; `get_domain_summary` workplan-first prose + `workplans` key; TOOLS.md and tool docstrings updated. Phase 2 alias removal remains gated on legacy-meter zero usage for seven consecutive review windows. Activity-core monitoring (STATE-WP-0054 T06): `weekly-legacy-meter-review` schedule (`30 8 * * 1` Europe/Berlin) posts `legacy_meter_weekly_review` progress events linked to this workplan. ## Task: REST `/workstreams` compat router retirement ```task id: STATE-WP-0069-T04 status: todo priority: high state_hub_task_id: "6fba665d-ebfa-42ab-8cf9-4460f77c5375" ``` Highest-risk phase. Remove or hard-deprecate legacy REST routes in `api/routers/workstreams.py` once `/workplans` parity is proven and legacy-meter reports zero calls per key: - `GET/POST /workstreams/`, `GET/PATCH/DELETE /workstreams/{id}`; - dependency and execution intent aliases under `/workstreams/`; - `workstream_id` query param aliases where `workplan_id` is sufficient. Retain deprecation headers until removal. Update OpenAPI snapshot, router tests, and `tests/test_legacy_meter.py` retirement cases. Done when OpenAPI documents `/workplans` as the public CRUD surface and `/workstreams` returns 410 Gone or is unmounted, with regression tests green. ## Task: Legacy completion event — stop dual-publish ```task id: STATE-WP-0069-T05 status: todo priority: medium state_hub_task_id: "ebcbe5fc-b50f-4885-a18a-f8394d362c85" ``` After activity-core subscribers migrate (CUST-WP-0055 T03), stop emitting `org.statehub.workstream.completed` from `api/routers/workstreams.py`. Keep `org.statehub.workplan.completed` as the sole completion subject. Register the legacy subject as `retired` in legacy-meter. Update `docs/nats-event-subjects.md` and envelope tests. Done when only `org.statehub.workplan.completed` is published on workplan finish transitions and legacy-meter shows zero event consumers on the old subject. ## Task: Internal flows and cache identifiers ```task id: STATE-WP-0069-T06 status: progress priority: low state_hub_task_id: "221a69f9-9e61-4fde-9785-fa0dcaf698b4" ``` Rename internal non-wire identifiers when no external client depends on them: - `flows/workstream.yaml` → workplan entity type (or successor flow id); - `open_workstreams` keys in state summary cache → `open_workplans`; - test module names and comments that mislead new contributors. Coordinate with hub-core if shared types leak the old term. Done when internal code reads workplan-first and grep budget for `api:open_workstreams` hits zero. Progress 2026-07-08: `/state/summary` now dual-writes `open_workplans` alongside legacy `open_workstreams`; MCP `get_domain_summary` prefers `open_workplans`. Progress 2026-07-09 (T06): added `flows/workplan.yaml` (`custodian.workplan.v1`) and `/flows/workplan/{id}` advance path; dashboard and README now read `open_workplans` first with `open_workstreams` fallback. Legacy `flows/workstream.yaml` and summary dual-key remain until legacy-meter clears callers. ## Task: Closeout — registry cleanup and verification ```task id: STATE-WP-0069-T07 status: todo priority: medium state_hub_task_id: "06ed4814-3ba5-4226-845d-695f3041522e" ``` Final verification: 1. `make test` and `cd dashboard && npm test` pass. 2. `scan_workstream_terminology.py --repo state-hub` meets phase grep budget. 3. `legacy-meter` registry lists retired interfaces with retirement dates. 4. `docs/workplan-terminology-transition.md` updated with retirement completion notes and pointers to CUST-WP-0055 T08 fleet gate. Post State Hub progress note linking completion; notify CUST-WP-0055 T02 closeout. Done when STATE-WP-0069 can move to `finished` and CUST-WP-0055 T02-T02 is `done`. ## Sequencing ``` T01 inventory + backlog (blocking) T02 dashboard/docs (low risk, start early) T03 MCP aliases (parallel with T02 after T01) T04 REST retirement (after ≥1 zero-usage review window per route key) T05 event dual-publish stop (after CUST-WP-0055 T03) T06 internal renames (anytime after T04) T07 closeout ``` ## Acceptance criteria - `workplan` is the only recommended term in State Hub dashboard, README, and new MCP/REST docs. - Legacy interfaces are removed only with legacy-meter evidence, not by schedule alone. - ADR-001 `fix-consistency` and workplan file sync remain green through all phases. - No frontmatter `state_hub_workstream_id` renames in this workplan.