Finish STATE-WP-0069: retire legacy completion event and DELETE /workstreams
Stop dual-publishing org.statehub.workstream.completed; return 410 Gone for
legacy DELETE /workstreams/{id}. Migrate fix-consistency, MCP adhoc bootstrap,
and dashboard token summary to /workplans/. Add legacy-meter evidence capture
script and pytest snapshot; update docs and close out the workplan.
This commit is contained in:
parent
b659ff8d13
commit
e0c954d098
13 changed files with 404 additions and 149 deletions
100
docs/evidence/legacy-meter-weekly-review-20260708.json
Normal file
100
docs/evidence/legacy-meter-weekly-review-20260708.json
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
{
|
||||
"captured_at": "2026-07-08T21:26:32.013489+00:00",
|
||||
"source": "pytest",
|
||||
"workplan": "STATE-WP-0069",
|
||||
"weekly_review": {
|
||||
"generated_at": "2026-07-08T21:26:32.009639Z",
|
||||
"window_start": "2026-07-01T21:26:31.995046Z",
|
||||
"window_end": "2026-07-08T21:26:31.995046Z",
|
||||
"cadence": "weekly",
|
||||
"activity_core_handoff": {
|
||||
"activity_id": "statehub-legacy-interface-review",
|
||||
"cadence": "weekly",
|
||||
"source_endpoint": "/legacy-meter/weekly-review",
|
||||
"state_owner": "state-hub",
|
||||
"scheduler_owner": "activity-core"
|
||||
},
|
||||
"interfaces": [
|
||||
{
|
||||
"interface": {
|
||||
"id": "53afb376-40d3-4c07-a312-a1294e179d68",
|
||||
"interface_key": "rest_api:GET /obsolete",
|
||||
"interface_kind": "rest_api",
|
||||
"legacy_since": "2026-07-08T21:26:31.952023Z",
|
||||
"replacement_ref": "/workplans/",
|
||||
"owner_component": "state-hub",
|
||||
"status": "legacy",
|
||||
"replacement_verified": true,
|
||||
"manual_hold": false,
|
||||
"hold_reason": null,
|
||||
"notes": null,
|
||||
"retired_at": null,
|
||||
"created_at": "2026-07-08T21:26:31.952023Z",
|
||||
"updated_at": "2026-07-08T21:26:31.952023Z"
|
||||
},
|
||||
"all_time": {
|
||||
"calls": 0,
|
||||
"tenant_count": 0,
|
||||
"user_count": 0,
|
||||
"component_count": 0,
|
||||
"tenants": {},
|
||||
"users": {},
|
||||
"components": {}
|
||||
},
|
||||
"window": {
|
||||
"calls": 0,
|
||||
"tenant_count": 0,
|
||||
"user_count": 0,
|
||||
"component_count": 0,
|
||||
"tenants": {},
|
||||
"users": {},
|
||||
"components": {}
|
||||
},
|
||||
"last_seen_at": null,
|
||||
"retirement_candidate": true,
|
||||
"retirement_reason": "no measured usage in review window"
|
||||
}
|
||||
],
|
||||
"retirement_candidates": [
|
||||
{
|
||||
"interface": {
|
||||
"id": "53afb376-40d3-4c07-a312-a1294e179d68",
|
||||
"interface_key": "rest_api:GET /obsolete",
|
||||
"interface_kind": "rest_api",
|
||||
"legacy_since": "2026-07-08T21:26:31.952023Z",
|
||||
"replacement_ref": "/workplans/",
|
||||
"owner_component": "state-hub",
|
||||
"status": "legacy",
|
||||
"replacement_verified": true,
|
||||
"manual_hold": false,
|
||||
"hold_reason": null,
|
||||
"notes": null,
|
||||
"retired_at": null,
|
||||
"created_at": "2026-07-08T21:26:31.952023Z",
|
||||
"updated_at": "2026-07-08T21:26:31.952023Z"
|
||||
},
|
||||
"all_time": {
|
||||
"calls": 0,
|
||||
"tenant_count": 0,
|
||||
"user_count": 0,
|
||||
"component_count": 0,
|
||||
"tenants": {},
|
||||
"users": {},
|
||||
"components": {}
|
||||
},
|
||||
"window": {
|
||||
"calls": 0,
|
||||
"tenant_count": 0,
|
||||
"user_count": 0,
|
||||
"component_count": 0,
|
||||
"tenants": {},
|
||||
"users": {},
|
||||
"components": {}
|
||||
},
|
||||
"last_seen_at": null,
|
||||
"retirement_candidate": true,
|
||||
"retirement_reason": "no measured usage in review window"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -42,8 +42,8 @@ those publishers from colliding on the same `{noun}.{verb}` shape.
|
|||
| Subject | When | Required attributes |
|
||||
| ------------------------------------ | ------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `org.statehub.repo.registered` | A new repo is registered via `POST /repos/` | `repo_id`, `repo_slug`, `domain_slug`, `remote_url?`, `local_path?` |
|
||||
| `org.statehub.workplan.completed` | A workplan transitions to canonical status `finished` | `workplan_id`, `legacy_workstream_id`, `slug`, `title`, `topic_id`, `repo_id?`, `repo_goal_id?` |
|
||||
| `org.statehub.workstream.completed` | Legacy compatibility subject for completed workplans | `workstream_id`, `slug`, `title`, `topic_id`, `repo_id?`, `repo_goal_id?` |
|
||||
| `org.statehub.workplan.completed` | A workplan transitions to canonical status `finished` | `workplan_id`, `slug`, `title`, `topic_id`, `repo_id?`, `repo_goal_id?` |
|
||||
| ~~`org.statehub.workstream.completed`~~ | **Retired 2026-07-08** (`STATE-WP-0069` T05). Use `org.statehub.workplan.completed`. | — |
|
||||
| `org.statehub.decision.resolved` | A decision is resolved via `POST /decisions/{id}/resolve` | `decision_id`, `title`, `topic_id?`, `workstream_id?`, `decided_by`, `rationale_snippet` |
|
||||
| `org.statehub.domain.goal.activated` | A domain goal transitions to `active` | `goal_id`, `domain_id`, `domain_slug`, `title`, `superseded_goal_ids[]` |
|
||||
| `org.statehub.task.stale` | `scripts/cleanup_stale_tasks.py` cancels an out-of-date task | `task_id`, `workstream_id`, `workstream_status`, `task_title`, `task_status_before` |
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ Risk order: REST > MCP > events > dashboard prose > internal identifiers.
|
|||
| 1 | `rest_api:POST /workstreams/` | `POST /workplans/` | REST | T04 |
|
||||
| 1 | `rest_api:GET /workstreams/{workstream_id}` | `GET /workplans/{workplan_id}` | REST | T04 |
|
||||
| 1 | `rest_api:PATCH /workstreams/{workstream_id}` | `PATCH /workplans/{workplan_id}` | REST | T04 |
|
||||
| 1 | `rest_api:DELETE /workstreams/{workstream_id}` | `DELETE /workplans/{workplan_id}` | REST | T04 |
|
||||
| 1 | ~~`rest_api:DELETE /workstreams/{workstream_id}`~~ **retired** (410) | `DELETE /workplans/{workplan_id}` | REST | T04 ✓ |
|
||||
| 1 | `rest_api:GET /workstreams/workplan-index` | `GET /workplans/index` | REST | T04 |
|
||||
| 2 | `rest_api:GET /workstreams/{workstream_id}/dependencies/` | `GET /workplans/{workplan_id}/dependencies/` | REST | T04 |
|
||||
| 2 | `rest_api:POST /workstreams/{workstream_id}/dependencies/` | `POST /workplans/{workplan_id}/dependencies/` | REST | T04 |
|
||||
|
|
@ -57,7 +57,7 @@ Risk order: REST > MCP > events > dashboard prose > internal identifiers.
|
|||
| 3 | `mcp:update_workstream_status` | `update_workplan_status` | MCP | T03 |
|
||||
| 3 | `mcp:list_workstreams` | `list_workplans` | MCP | T03 |
|
||||
| 3 | `state://workstreams/{topic_slug}` | `state://workplans/{topic_slug}` (proposed) | MCP resource | T03 |
|
||||
| 4 | `event_subject:org.statehub.workstream.completed` | `org.statehub.workplan.completed` | Event | T05 |
|
||||
| 4 | ~~`event_subject:org.statehub.workstream.completed`~~ **retired** | `org.statehub.workplan.completed` | Event | T05 ✓ |
|
||||
| 5 | Dashboard nav label `Workstreams` | `Workplans` (URL compat retained) | Prose | T02 |
|
||||
| 5 | `dashboard/src/index.md` user-facing copy | workplan-first strings | Prose | T02 |
|
||||
| 6 | `open_workstreams` summary cache key | `open_workplans` | Internal | T06 |
|
||||
|
|
|
|||
|
|
@ -29,12 +29,12 @@ Physical database renames are intentionally out of scope for this workplan.
|
|||
| Create workplan | `POST /workplans/` | `POST /workstreams/` | `rest_api:POST /workstreams/` |
|
||||
| Read workplan | `GET /workplans/{workplan_id}` | `GET /workstreams/{workstream_id}` | `rest_api:GET /workstreams/{workstream_id}` |
|
||||
| Update workplan | `PATCH /workplans/{workplan_id}` | `PATCH /workstreams/{workstream_id}` | `rest_api:PATCH /workstreams/{workstream_id}` |
|
||||
| Archive workplan | `DELETE /workplans/{workplan_id}` | `DELETE /workstreams/{workstream_id}` | `rest_api:DELETE /workstreams/{workstream_id}` |
|
||||
| Archive workplan | `DELETE /workplans/{workplan_id}` | ~~`DELETE /workstreams/{workstream_id}`~~ **410 Gone** (2026-07-08) | `rest_api:DELETE /workstreams/{workstream_id}` (retired) |
|
||||
| Workplan index | `GET /workplans/index` | `GET /workstreams/workplan-index` | `rest_api:GET /workstreams/workplan-index` |
|
||||
| Workplan dependencies | `GET/POST /workplans/{workplan_id}/dependencies/` | `GET/POST /workstreams/{workstream_id}/dependencies/` | matching `rest_api:* /workstreams/...` keys |
|
||||
| Delete dependency | `DELETE /workplans/{workplan_id}/dependencies/{dep_id}` | `DELETE /workstreams/{workstream_id}/dependencies/{dep_id}` | `rest_api:DELETE /workstreams/{workstream_id}/dependencies/{dep_id}` |
|
||||
| Execution intent | `PATCH /execution/workplans/{workplan_id}/intent` | `PATCH /execution/workstreams/{workstream_id}/intent` | `rest_api:PATCH /execution/workstreams/{workstream_id}/intent` |
|
||||
| Completion event | `org.statehub.workplan.completed` | `org.statehub.workstream.completed` | `event_subject:org.statehub.workstream.completed` |
|
||||
| Completion event | `org.statehub.workplan.completed` | ~~`org.statehub.workstream.completed`~~ **retired** (2026-07-08) | `event_subject:org.statehub.workstream.completed` (retired) |
|
||||
|
||||
Legacy REST responses include:
|
||||
|
||||
|
|
@ -82,3 +82,31 @@ An interface is a retirement candidate only when all of the following are true:
|
|||
|
||||
State Hub owns the usage state and the review payload. Activity-core owns the
|
||||
weekly wakeup, review activity, and any follow-up dispatch.
|
||||
|
||||
## STATE-WP-0069 closeout (2026-07-08)
|
||||
|
||||
Completed in this workplan:
|
||||
|
||||
- `org.statehub.workstream.completed` dual-publish stopped; legacy subject retired
|
||||
in legacy-meter.
|
||||
- `DELETE /workstreams/{workstream_id}` returns **410 Gone** with replacement header.
|
||||
- `scripts/consistency_check.py`, MCP adhoc bootstrap, and dashboard token summary
|
||||
now call `/workplans/` (major `/workstreams` usage reduction).
|
||||
- `flows/workplan.yaml` and `open_workplans` are preferred; legacy dual-keys remain
|
||||
until legacy-meter clears callers.
|
||||
|
||||
Deferred until seven consecutive zero-usage review windows per key:
|
||||
|
||||
- MCP alias removal (`create_workstream`, etc.).
|
||||
- Remaining `/workstreams` GET/POST/PATCH routes (still metered with Deprecation).
|
||||
- `workstream_id` query/body param aliases on preferred routes.
|
||||
|
||||
Evidence capture:
|
||||
|
||||
```bash
|
||||
python scripts/capture_legacy_meter_evidence.py --days 7
|
||||
# writes docs/evidence/legacy-meter-weekly-review-YYYYMMDD.json
|
||||
```
|
||||
|
||||
Activity-core `weekly-legacy-meter-review` (`30 8 * * 1` Europe/Berlin) consumes
|
||||
`/legacy-meter/weekly-review`; railiance-cluster rollout suggestion `05da5540`.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue