Compare commits
No commits in common. "2c60e5bcf76c31a2d2336f104ac9d5f01fc22e90" and "74a3b22c05f6e1c3e1e74a6c84c53387d286d156" have entirely different histories.
2c60e5bcf7
...
74a3b22c05
8 changed files with 478 additions and 1849 deletions
|
|
@ -256,7 +256,7 @@ use `/state/health`, not `/state/summary`.
|
||||||
|--------|-----------|
|
|--------|-----------|
|
||||||
| `/topics` | CRUD (soft-delete: `archived`) |
|
| `/topics` | CRUD (soft-delete: `archived`) |
|
||||||
| `/workplans` | Preferred CRUD surface for repo-backed workplans (soft-delete: `archived`) |
|
| `/workplans` | Preferred CRUD surface for repo-backed workplans (soft-delete: `archived`) |
|
||||||
| `/workstreams` | Retired REST routes (410); use `/workplans`. Rejected calls remain metered |
|
| `/workstreams` | Legacy compatibility CRUD surface; usage is recorded by legacy-meter |
|
||||||
| `/tasks` | CRUD (soft-delete: `cancel`); `PATCH` updates status |
|
| `/tasks` | CRUD (soft-delete: `cancel`); `PATCH` updates status |
|
||||||
| `/decisions` | CRUD (soft-delete: `superseded`); auto-escalation |
|
| `/decisions` | CRUD (soft-delete: `superseded`); auto-escalation |
|
||||||
| `/progress` | `GET` list + `POST` append — no DELETE |
|
| `/progress` | `GET` list + `POST` append — no DELETE |
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,7 @@ The Goals page groups everything by domain:
|
||||||
|
|
||||||
Workplans carry an optional `repo_goal_id` field. Setting it traces *why* a workplan exists — which specific repo goal it contributes to. This connection is currently recorded in the DB but is not yet visualised in the Workplans page.
|
Workplans carry an optional `repo_goal_id` field. Setting it traces *why* a workplan exists — which specific repo goal it contributes to. This connection is currently recorded in the DB but is not yet visualised in the Workplans page.
|
||||||
|
|
||||||
To set the link when creating a workplan through the preferred API, pass `repo_goal_id`. To update an existing one, use `PATCH /workplans/{id}/` with `{"repo_goal_id": "<uuid>"}`. The legacy `create_workstream` tool is removed and `/workstreams/{id}` returns 410; use `create_workplan` and `/workplans/{id}`.
|
To set the link when creating a workplan through the preferred API, pass `repo_goal_id`. To update an existing one, use `PATCH /workplans/{id}/` with `{"repo_goal_id": "<uuid>"}`. Legacy `create_workstream` and `/workstreams/{id}/` callers remain compatibility-supported while they are metered.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
# STATE-WP-0079 caller and receiver review — 2026-09-05
|
|
||||||
|
|
||||||
## Actions and scope
|
|
||||||
|
|
||||||
User authorized the proposed SBOM meter retirements, caller tracing/migration,
|
|
||||||
and refreshed cutover checklist. No application image, production writer,
|
|
||||||
network policy, runtime deployment, or compatibility handler was changed.
|
|
||||||
|
|
||||||
A fresh seven-day primary review re-confirmed both candidates before mutation.
|
|
||||||
Direct Nexus licence-report and snapshot reads returned HTTP 200 from the State
|
|
||||||
Hub pod. Both meter records were patched with STATE-WP-0079-T05 provenance.
|
|
||||||
The saved before/after receipt is
|
|
||||||
`STATE-WP-0079-sbom-retirement-20260905.json`: eight retired, seven legacy,
|
|
||||||
zero remaining candidates. Handler deletion is not claimed by meter retirement.
|
|
||||||
|
|
||||||
## Caller trace
|
|
||||||
|
|
||||||
Searched non-hidden source trees under `/home/worsch` for `workstream_id`,
|
|
||||||
`/workstreams`, and the two SBOM endpoints, covering Python, shell, JS/TS and
|
|
||||||
YAML while excluding tests, dependency trees, docs, archives and fixtures.
|
|
||||||
517 matching lines were triaged by receiver and operation. A second Markdown
|
|
||||||
instruction scan excluded workplans, generated indexes, docs, archives and
|
|
||||||
session evidence. Matching strings alone were not treated as runtime callers.
|
|
||||||
|
|
||||||
- Repo Manager's licence-report client uses explicit `SBOM_NEXUS_URL`; it is a
|
|
||||||
direct Nexus client, not evidence of a State Hub caller.
|
|
||||||
- SBOM Nexus importer intentionally reads source and target snapshots/licences
|
|
||||||
for migration comparison. Its matching paths do not establish ongoing use.
|
|
||||||
- The bundled State Hub skill advertised removed `create_workstream` and
|
|
||||||
`POST /workstreams/`; README and dashboard goals documentation also described
|
|
||||||
retired routes as supported. Corrected these to current workplan contracts,
|
|
||||||
file-first sync and component attribution.
|
|
||||||
- No current hard-coded State Hub workstream route caller was found in the
|
|
||||||
scanned runtime sources. This does not cover hidden installations, remote
|
|
||||||
checkouts, dynamically built paths or past one-off commands.
|
|
||||||
|
|
||||||
Targeted local agent-session review extracted only tool-call timestamp, working
|
|
||||||
repository and legacy path. Full session contents were not copied into evidence.
|
|
||||||
|
|
||||||
| Time (UTC) | Caller context | Observed operation | Confidence / correction |
|
|
||||||
| --- | --- | --- | --- |
|
|
||||||
| 2026-09-04 17:21:25.339 | Claude agent, fluid-telegram | Task query with legacy `workstream_id`, targeting `f2373858-c932-5a4d-81b6-db9a3595135a` | Actual command in session history; within four seconds of meter last_seen 17:21:29.173850. Strong correlation, not request-ID proof. AGENTS.md now prescribes canonical query and `X-StateHub-Component: fluid-telegram` |
|
|
||||||
| 2026-08-29 12:57:27.083 | Claude agent, ops-warden | Task query with legacy `workstream_id`, targeting `ae3ff76f-883d-5e2f-b6aa-144d61e8fdef` | Actual command in session history. AGENTS.md now prescribes canonical query and `X-StateHub-Component: ops-warden` |
|
|
||||||
|
|
||||||
Caller guidance commits: fluid-telegram `f7af151`, ops-warden `96dbb22`.
|
|
||||||
Both changes are restricted to the repository-owned AGENTS.md extension.
|
|
||||||
|
|
||||||
Replayed only the **canonical** task queries with those component headers:
|
|
||||||
HTTP 200, 8 and 5 tasks respectively. No legacy query was replayed, so the
|
|
||||||
retirement clocks were not reset by verification. Agent instructions reduce
|
|
||||||
future misuse; they do not prove that future sessions will follow them.
|
|
||||||
|
|
||||||
Remaining attribution: the meter's 11 task-filter calls are not all individually
|
|
||||||
explained, seven workstream-detail calls remain unidentified, and the one SBOM
|
|
||||||
index call remains unidentified. These are STATE-WP-0079-T07 live work, not
|
|
||||||
claimed completed migrations.
|
|
||||||
|
|
||||||
## Log retention limit
|
|
||||||
|
|
||||||
Requested seven days of `deployment/state-hub` pod logs. Available logs start
|
|
||||||
2026-09-04T20:10:36Z, after the relevant last-seen timestamps. No matching legacy
|
|
||||||
requests appear in that retained interval. Kubernetes has no previous container
|
|
||||||
log for this pod. Hence these logs cannot retrospectively identify the calls;
|
|
||||||
absence in this interval is not evidence of seven quiet days.
|
|
||||||
|
|
||||||
## Receiving runtime probe
|
|
||||||
|
|
||||||
The live State Hub deployment image was `main-cdff3b7`; its configmap directs
|
|
||||||
both SBOM read and write compatibility paths to the cluster Nexus service.
|
|
||||||
|
|
||||||
`core-hub-api` and `core-hub-api-candidate` deployments both reported 1/1 ready.
|
|
||||||
From the State Hub pod, requests to both Core Hub service addresses on port 8010
|
|
||||||
were connection-refused. Cause was not established and no connectivity change
|
|
||||||
was made. From candidate pod loopback, `/openapi.json` returned a **Hub Core
|
|
||||||
Runtime** schema with 31 paths. It exposes `/api/v2/interaction-events`, but no
|
|
||||||
`/messages`, `/progress`, `/token-events` or `/interface-changes` family.
|
|
||||||
|
|
||||||
Shared Python routers exist for messages/progress, but importing them into
|
|
||||||
State Hub does not deploy them on the owner runtime or migrate their rows.
|
|
||||||
HUB-WP-0005's successful Core Hub `/api/v2` absorption must not be used as proof
|
|
||||||
of the State Hub family cutover. STATE-WP-0079-T08 owns the bounded follow-up:
|
|
||||||
identify/expose one deployed message-read contract, historical data projection,
|
|
||||||
transport and parity/rollback evidence before changing any reader/writer.
|
|
||||||
|
|
||||||
## Validation
|
|
||||||
|
|
||||||
- Live primary identity and fresh seven-day eligibility verified before PATCH.
|
|
||||||
- Direct receiving SBOM reads: 200; canonical caller task reads: 200.
|
|
||||||
- State Hub skill passes the skill-creator frontmatter validator; this also
|
|
||||||
corrected an existing unquoted colon that made its description invalid YAML.
|
|
||||||
- Documentation and caller-instruction edits pass `git diff --check`.
|
|
||||||
- No executable application code changed; no database test suite was needed.
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,93 +1,472 @@
|
||||||
# State Hub retirement — cutover slice plan
|
# State Hub retirement — cutover slice plan
|
||||||
|
|
||||||
**Execution owner:** STATE-WP-0079-T04/T05
|
**Workplan task:** `STATE-WP-0079-T02`
|
||||||
**Re-baselined:** 2026-09-05
|
**Inventory:** `SHR-INV-0001` (`prj-state-hub-retirement/inventory/`), 425 items, v0.1.1
|
||||||
**Inventory:** SHR-INV-0001, original 425-item inventory in
|
**Created:** 2026-08-19
|
||||||
`prj-state-hub-retirement/inventory/`. Counts below identify historical slices;
|
|
||||||
current owner contracts take precedence over the original owner assignments.
|
|
||||||
|
|
||||||
This checklist replaces the obsolete August 19–20 readiness snapshot. That
|
Groups every dispositioned inventory item into an ordered cutover slice. Each
|
||||||
snapshot and the original off/dual/owner proposal remain in Git history.
|
slice names its adapter flag, the owner-side API that receives the traffic, and
|
||||||
`RM_SLICE_*` names were proposed controls, not proof of deployed flags. Do not
|
its rollback. Slices are the execution unit for `STATE-WP-0079-T04`.
|
||||||
execute the old workstation dual-run instructions against the cluster service:
|
|
||||||
ADR-002 forbids central services from mutating workstation checkouts.
|
|
||||||
|
|
||||||
## Evidence required to switch a slice
|
## Method
|
||||||
|
|
||||||
For each route family, identify the current caller and destination endpoint,
|
Slices are cut on **capability**, not on route or table, because a capability is
|
||||||
compare representative identities/content/counts in a read-only parity run,
|
the smallest unit with a single owner and a coherent contract. The inventory's
|
||||||
record the exact deployment/source revisions, exercise rollback, and retain the
|
`capability` field yields 51 groups; those are bundled into waves by owner, and
|
||||||
switch receipt. An owner workplan marked finished or an imported Python router
|
ordered within a wave by dependency and blast radius.
|
||||||
proves neither deployed endpoint availability nor data migration. Production
|
|
||||||
writer changes require a concrete recoverable cutover, within user authorization.
|
|
||||||
No new permanent receiving authority belongs in State Hub during retirement.
|
|
||||||
|
|
||||||
## Current route-family checklist
|
Two rules constrain the ordering:
|
||||||
|
|
||||||
| Slice / historical items | Receiver and contract evidence | Caller / route-switch evidence | Remaining gate and rollback |
|
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? |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| `repo-manager` | 167 | RMGR-WP-0001/0002/0003 | `finished` | **Partial — see correction below** |
|
||||||
|
| `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 |
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
### Owner readiness refresh (2026-08-31)
|
||||||
|
|
||||||
|
The original readiness table is retained above as planning history. Current
|
||||||
|
workplan status changes which owners can receive a slice, but it does not count
|
||||||
|
as State Hub cutover evidence by itself:
|
||||||
|
|
||||||
|
| Owner | Current owner evidence | State Hub cutover consequence |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| `repo-manager` | RMGR-WP-0005 finished deterministic identifier migration; RMGR-WP-0008 finished register/classification surfaces | Receiving-side identity and register gates are satisfied; each State Hub writer/read switch still needs its own parity and rollback receipt. |
|
||||||
|
| `hub-core` | HUB-WP-0005 finished and its production runtime owns all declared hub-core route/writer groups with exercised rollback | Receiving runtime is available; B1-B5 are not complete until State Hub caller/route switches and counts are evidenced. |
|
||||||
|
| `activity-core` | ACTIVITY-WP-0029 finished schedule, sweep, interaction-event, and execution-boundary work | The launch-request defect is retired; remaining C-slice caller switches still require explicit evidence. |
|
||||||
|
| `ops-hub` | OPS-WP-0003 finished; owner package and implemented conformance profile pass | D1 receiving-side gate is satisfied. State Hub route/caller switch, count parity, rollback, and writer authorization remain cutover evidence. |
|
||||||
|
| `fin-hub` | FIN-WP-0003 remains `proposed`; 0/3 tasks done | D2 cannot move. Do not implement the fabric authority contract here. |
|
||||||
|
| `archive` | 2026-08-31 central meter: 6 newly retired, 9 legacy, 0 candidates | E2/E4 remain gated; live callers and volume-scaled quiet windows prohibit retirement. |
|
||||||
|
|
||||||
|
Accordingly, `STATE-WP-0079-T04` is waiting on the missing owner workplans,
|
||||||
|
the still-unrecorded State Hub route-switch receipts, and explicit production
|
||||||
|
writer-cutover authorization. `T05` waits on fresh central meter evidence, and
|
||||||
|
`T06` cannot begin while State Hub remains the healthy, active `railiance01`
|
||||||
|
primary.
|
||||||
|
|
||||||
|
## 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.
|
||||||
|
|
||||||
|
### 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
|
||||||
|
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.
|
||||||
|
|
||||||
|
### 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` |
|
||||||
|
| Owner API | `rmgr register ...`; `rmgr sbom scan|licence-report` |
|
||||||
|
| Rollback | flag → `off`; retain current State Hub projection |
|
||||||
|
|
||||||
|
**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.
|
||||||
|
|
||||||
|
### A4 · Work + repo UI — 22 items
|
||||||
|
`work-coordination-ui` (14, `replace`) · `repo-ui` (8)
|
||||||
|
|
||||||
|
| | |
|
||||||
|
| --- | --- |
|
||||||
|
| Flag | `RM_SLICE_UI` |
|
||||||
|
| Owner API | hub-core projection/query plus hub/ops UI clients |
|
||||||
|
| Rollback | remove redirect; hub pages are unchanged behind it |
|
||||||
|
|
||||||
|
`replace`, not `move`: the contract changes. Must follow A1–A3, since the pages
|
||||||
|
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.
|
||||||
|
|
||||||
|
### A5 · Topic spine — 8 items
|
||||||
|
`topic-spine` (8, `replace`)
|
||||||
|
|
||||||
|
| | |
|
||||||
|
| --- | --- |
|
||||||
|
| Flag | `RM_SLICE_TOPICSPINE` |
|
||||||
|
| Owner API | `rmgr` topic/classification contract |
|
||||||
|
| Rollback | flag → `off` |
|
||||||
|
|
||||||
|
The versioned Repo Manager classification contract is published and accepted by
|
||||||
|
finished HUB-WP-0004. Consumer route switching remains a State Hub cutover
|
||||||
|
action.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Wave B — hub-core (128 items) · HUB-WP-0004 owner gate satisfied
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
| 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) · fin-hub gated
|
||||||
|
|
||||||
|
| Slice | Owner | Capabilities | Items | Gate |
|
||||||
|
| --- | --- | --- | --- | --- |
|
||||||
|
| D1 | `ops-hub` | `service-catalog` (9), `service-catalog-ui` (2) | 11 | OPS-WP-0003 `finished`; receiving contract ready, cutover receipt pending |
|
||||||
|
| 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 |
|
||||||
| --- | --- | --- | --- |
|
| --- | --- | --- | --- |
|
||||||
| A1 registry / 27 | Repo Manager observation/scaffolding; STATE-WP-0081 and 0086 establish forge-derived projection | `rmgr sync` verified pushed commit `74a3b22` on primary/railiance01 in the preceding session | Inventory remaining registry callers per endpoint. Keep current projection while proving the owner read; do not restore checkout mutation in central |
|
| E1 | `suggestion-backlog` → archive | 17 | history archived 2026-08-20; read surface + dashboard remain |
|
||||||
| A2 work records / 59 | RMGR-WP-0008 implements file-backed workplan, intake, decision, dependency and task mutations; RMGR-WP-0005 identifiers finished | Repository files + `rmgr sync` are the current write convention. Two ad-hoc task-filter callers identified and guidance corrected in this review | Work-record caller inventory and per-kind writer receipts still required. Revert source commit and reconcile for a reviewed rollback; no second file authority |
|
| E2 | `work-records-workplan-legacy` → archive | 13 | legacy-meter — candidate rule, see below |
|
||||||
| A3 registers / 49 | RMGR-WP-0008 register spine; **SBOM Nexus** is the current SBOM product owner | Live State Hub config uses Nexus for both SBOM reads/writes. Direct Nexus licence and snapshot reads return 200. Two more compatibility interfaces retired in the meter September 5 | Other registers need individual caller/parity receipts. Preserve SBOM history; remaining `/sbom/` traffic and retained compatibility handlers prevent deleting the whole router |
|
| E3 | `dashboard-meta` (`/ui-feedback`) | 1 | T06 freeze window — owner is `state-hub-until-cutover` |
|
||||||
| A4 work/repo UI / 22 | hub-core projection + UI clients; RMGR-ADR-003 excludes a Repo Manager dashboard | No complete State Hub UI redirect receipt established | First prove backing reads; rollback redirects to the retained UI |
|
| E4 | `legacy-meter` itself | 9 | **last** — it is the instrument for E2 |
|
||||||
| A5 topic spine / 8 | Published Repo Manager classification contract, accepted by HUB-WP-0004 | No complete State Hub caller-switch receipt established | Prove deployed consumer contract and parity; retain source-backed classification projection |
|
|
||||||
| B1 catalogs / 34 | HUB-WP-0004/0005 receiving architecture and `/api/v2` absorption | Completion covers the Core Hub route groups, not every State Hub capability/registry route | Map each State Hub catalog to a deployed endpoint and migration receipt |
|
|
||||||
| B2 messaging/interface log / 22 | Shared `hub_core.routers.messages` exists; State Hub interface log is a separate family | Live Hub Core OpenAPI has **no `/messages` or `/interface-changes`**. `/api/v2/interaction-events` exists but is not asserted equivalent | **Next bounded read slice:** STATE-WP-0079-T08. Owner must expose/identify the message read contract and history projection before a parity run or switch. Retain current reads/writer |
|
|
||||||
| B3 telemetry / 32 | Shared `hub_core.routers.progress` exists; token/software catalogs need separate mappings | Live Hub Core OpenAPI has **no `/progress` or `/token-events`** | Owner runtime assembly/mapping plus historical identity/count parity; writer exclusivity and rollback receipts remain necessary |
|
|
||||||
| B4 projection/policy / 20 | HUB-WP-0004/0005; policy publication belongs to policy-nexus | State Hub still serves its projection routes; no full family receipt established | Map individual projections and policy publication; retain source/runtime boundaries and current reads |
|
|
||||||
| B5 hub UI / 17 | Hub Core runtime/console exists | Core Hub absorption does not establish replacement of State Hub dashboard pages | Prove A4/B1–B4 data contracts before redirect; retain UI rollback |
|
|
||||||
| C1 execution / 13 | ACTIVITY-WP-0029 finished; Activity Core owns scheduling/ops_run | STATE-WP-0079 records launch-request rejection (410), replacement semantics, and corrected unconsumed requests | Verify every remaining execution caller uses the owner contract. Do not revive the obsolete launch queue for rollback |
|
|
||||||
| C2 jobs / 5 | ACTIVITY-WP-0029 finished; scheduler is Activity Core, reconciliation engine is Repo Manager | Receiving/sweep handoffs recorded in owner workplan | Attach remaining per-job deployment and caller receipts; keep scheduler ownership distinct from work-record authority |
|
|
||||||
| D1 service catalog / 11 | OPS-WP-0003 finished; reviewed packages and `/api/v2` conformance gate | Owner contract completion established; State Hub family-switch receipt still missing | Compare catalog identities and UI bindings; preserve current reads until switched |
|
|
||||||
| D2 Fabric / 10 | **railiance-fabric** authority, FIN-WP-0003 consumer gate | August 31 dual-read import: 131 nodes/117 edges; green hash/count/provenance checks, rollback and roll-forward exercised | Hosted runtime/persistence/auth/freshness remains RAIL-FAB-WP-0028 (`proposed`). Keep retained import rollback; do not claim the local authority is a hosted production receiver |
|
|
||||||
| D3 kaizen / 2 | the-custodian, original two-tool disposition | No fresh removal/delegation receipt collected in this review | Locate current tools/consumers and owner contract before removal |
|
|
||||||
| E1 suggestions / 17 | Archived history in the-custodian | STATE-WP-0079 records eight read routes at 410, six MCP tools removed, dashboard removed | Completed surface removal; tables retained for final dump |
|
|
||||||
| E2 legacy workplans / 13 | Preferred `/workplans` routes and `workplan_id` parameters | Workstream REST handlers return 410 and meter rejected calls. Task query alias still accepted | Seven legacy meter records remain after today's two SBOM retirements; observe volume-scaled quiet periods and complete T07 attribution |
|
|
||||||
| E3 UI feedback / 1 | State Hub until cutover | Feedback still needed during transition | T06 zero-normal-traffic gate; do not confuse it with retired suggestions |
|
|
||||||
| E4 meter / 9 | State Hub until all other retirement evidence complete | Eight retired / seven legacy interfaces, zero current candidates after September 5 action | Retire last, after the remaining interfaces and final evidence are closed |
|
|
||||||
|
|
||||||
## What today's probes establish
|
E4 retires only after every other legacy surface is closed; retiring the meter
|
||||||
|
first destroys the evidence for the retirements it gates.
|
||||||
|
|
||||||
- Central health identifies `primary/railiance01`.
|
### E1 status (2026-08-20)
|
||||||
- The live State Hub configuration has `SBOM_NEXUS_READ_MODE=nexus` and
|
|
||||||
`SBOM_NEXUS_WRITE_MODE=nexus`, using the cluster SBOM Nexus service.
|
|
||||||
- Direct Nexus `/sbom/report/licences/` and `/sbom/snapshots/` returned 200 from
|
|
||||||
the State Hub pod. Their State Hub meter entries are now retired. This does
|
|
||||||
**not** delete the compatibility handlers or historical data.
|
|
||||||
- Hub Core candidate runtime OpenAPI, read from its own pod loopback, has 31
|
|
||||||
paths and lacks the four State Hub families identified above. The State Hub
|
|
||||||
pod's probes to both Core Hub service addresses were connection-refused;
|
|
||||||
the deployments reported 1/1 ready. Transport readiness must be resolved as
|
|
||||||
part of any proxy-based pilot; this review did not diagnose its cause.
|
|
||||||
- Session trace identifies ad-hoc legacy task reads in fluid-telegram and
|
|
||||||
ops-warden. Their corrected canonical queries return 200 with 8 and 5 tasks.
|
|
||||||
No evidence identifies the other historical callers yet.
|
|
||||||
|
|
||||||
Evidence: `docs/evidence/STATE-WP-0079-sbom-retirement-20260905.json` and
|
Already half-retired before this plan: mutations have returned HTTP 410 since
|
||||||
`docs/evidence/STATE-WP-0079-caller-and-receiver-review-20260905.md`.
|
2026-07-21 (`CUST-WP-0061-T06`), pointing at `POST /intakes/`. Reads were kept
|
||||||
|
live so the historical record stayed reachable.
|
||||||
|
|
||||||
## Next executable work
|
**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.
|
||||||
|
|
||||||
1. T07: observe the remaining legacy readers with component attribution. The
|
**Executed 2026-08-20.** The 8 read routes now 410 with a pointer to intake and
|
||||||
known caller repositories and bundled State Hub skill now prescribe canonical
|
to the archive, the 6 MCP tools are removed (not stubbed — a retired tool that
|
||||||
reads. Preserve the quiet clocks; do not exercise legacy URLs to test them.
|
still appears in the tool list costs every agent session context on every call),
|
||||||
2. T08: obtain one **deployed message-read contract** from hub-core, including
|
the 5 `/suggestions` write-idempotency rules are gone, and the dashboard page is
|
||||||
access/transport and historical projection. Use the State Hub inbox reader as
|
deleted with its nav entry, `reference.md` row, and `wsjf-triage.md` link
|
||||||
the bounded parity client. Compare message IDs and read/archive flags against
|
updated. `dashboard/src/docs/suggestions.md` is rewritten as the archive
|
||||||
one consistent snapshot; do not change message writes during this proof.
|
pointer. Tables stay for the T06 dump.
|
||||||
Only after parity and rollback evidence should a concrete reader switch run.
|
|
||||||
3. RAIL-FAB-WP-0028-T01 remains the owner decision for runtime, persistent store,
|
|
||||||
auth, backup/restore and deployment repository. Its T02–T04 deliver deployment,
|
|
||||||
freshness and final direct-consumer receipts; no new Fabric authority here.
|
|
||||||
4. Re-evaluate eligible interfaces from a fresh seven-day meter capture. The
|
|
||||||
quiet ladder is 7 days for 1–99 historical calls, 30 for 100–9,999, and 60 for
|
|
||||||
10,000+. A new call restarts the relevant clock, including rejected requests.
|
|
||||||
|
|
||||||
## Freeze and infrastructure boundary
|
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.
|
||||||
|
|
||||||
T06 remains blocked until move/replace families and legacy retirement complete,
|
### E3 status (2026-08-20)
|
||||||
followed by a fresh zero-normal-read/write window. Final dump, restore proof,
|
|
||||||
service stop and repository archive then form one separately reviewable
|
`dashboard-meta` is the `/ui-feedback` page — the feedback scratch surface just
|
||||||
operation. The original schema-history/keep items and nine infrastructure
|
mentioned. Its owner is `state-hub-until-cutover` and it is still in active use,
|
||||||
couplings (database, scheduler, connectivity) remain explicit final-window
|
so it retires **at the T06 freeze window**, not before. Removing it now would
|
||||||
checks; they are not route flags. Ops Bridge connectivity survives retirement.
|
delete a working feedback loop during the retirement it serves. No action.
|
||||||
|
|
||||||
|
### E2 evidence — defect found and partly fixed (2026-08-20)
|
||||||
|
|
||||||
|
The window discrepancy flagged on 2026-08-19 was a real defect in
|
||||||
|
`scripts/capture_legacy_meter_evidence.py`, not a labelling nit.
|
||||||
|
|
||||||
|
`_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.
|
||||||
|
|
||||||
|
**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`:
|
||||||
|
|
||||||
|
| 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:
|
||||||
|
|
||||||
|
**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).
|
||||||
|
|
||||||
|
**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 |
|
||||||
|
|
||||||
|
**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
|
||||||
|
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.
|
||||||
|
|
||||||
|
## 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
|
||||||
|
|
||||||
|
1. ~~Resolve the legacy-meter window discrepancy~~ — done 2026-08-20; E1 and the
|
||||||
|
evidenced part of E2 are executed.
|
||||||
|
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.
|
||||||
|
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.
|
||||||
|
4. HUB-WP-0004's owner-readiness gate is satisfied; advance Wave B only through
|
||||||
|
its per-slice dual-run and operator gates.
|
||||||
|
5. Do not build register, UI, or topic capability in State Hub to unblock
|
||||||
|
items 2–3 — `policies/retirement-freeze.md` makes that inadmissible.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
name: state-hub
|
name: state-hub
|
||||||
description: Coordinate repository-backed work through State Hub REST or optional MCP, including canonical workplan reads, inbox checks, task status sync, and progress logging.
|
description: Use when coordinating with Custodian State Hub: orienting with domain summaries, checking agent inbox messages, updating workplan-backed task status, recording decisions/progress, or batching task status sync through MCP/REST without re-discovering tool schemas.
|
||||||
---
|
---
|
||||||
|
|
||||||
# State Hub Coordination
|
# State Hub Coordination
|
||||||
|
|
@ -11,32 +11,21 @@ work structure in the hub when a workplan file is the canon.
|
||||||
|
|
||||||
## Session Flow
|
## Session Flow
|
||||||
|
|
||||||
1. Prefer REST/`statehub` for Codex. Verify `/state/health` identifies the expected
|
1. Orient with `get_domain_summary(domain_slug)` when working inside one domain
|
||||||
primary, then read `/workplans/` with repo/topic filters. MCP is opt-in; use
|
repo. Use `get_state_summary()` only for cross-domain/custodian-wide work.
|
||||||
`get_domain_summary(domain_slug)` when enabled.
|
|
||||||
2. Check inbox with `get_messages(to_agent=<repo-slug>, unread_only=true)`.
|
2. Check inbox with `get_messages(to_agent=<repo-slug>, unread_only=true)`.
|
||||||
Mark acted-on messages with `mark_message_read(message_id)`.
|
Mark acted-on messages with `mark_message_read(message_id)`.
|
||||||
3. During work, edit the workplan file first. Use `workplan_id` in API payloads
|
3. During work, edit the workplan file first. Mirror task/workstream status to
|
||||||
and task queries; legacy `workstream_id` is accepted only for compatibility.
|
the hub at checkpoints.
|
||||||
4. Prefer `bulk_update_task_statuses(...)` for checkpoint syncs with multiple
|
4. Prefer `bulk_update_task_statuses(...)` for checkpoint syncs with multiple
|
||||||
task updates. Use `update_task_status(...)` for one-off changes.
|
task updates. Use `update_task_status(...)` for one-off changes.
|
||||||
5. Close with one concise progress event. After committing workplan file changes,
|
5. Close with one concise `add_progress_event(...)`, then run the repo's
|
||||||
run `uv run --project ~/repo-manager rmgr sync --path . --push`. Reserve
|
`make fix-consistency REPO=<repo-slug>` command when workplan files changed.
|
||||||
`statehub fix-consistency` for a separate deep audit.
|
|
||||||
6. If finishing a workplan with leftovers: create **residual** work records
|
6. If finishing a workplan with leftovers: create **residual** work records
|
||||||
first (intake with `origin: residual` + `origin_ref: <WP-id>`, or a child
|
first (intake with `origin: residual` + `origin_ref: <WP-id>`, or a child
|
||||||
workplan). Residual is a role, not a kind; do not leave backlog only in
|
workplan). Residual is a role, not a kind; do not leave backlog only in
|
||||||
finished-file prose or `SCOPE.md`. Canon: work-record-types § Residuals.
|
finished-file prose or `SCOPE.md`. Canon: work-record-types § Residuals.
|
||||||
|
|
||||||
## Canonical reads and caller attribution
|
|
||||||
|
|
||||||
Use `GET /workplans/{id}` and `GET /tasks/?workplan_id=<id>`.
|
|
||||||
The `/workstreams/` REST routes return 410 and the `create_workstream` MCP tool
|
|
||||||
has been removed. Create repository-owned records in files before syncing.
|
|
||||||
For direct HTTP calls, send `X-StateHub-Component: <repo-slug>` so a remaining
|
|
||||||
legacy call can be attributed to its caller. Do not replace authoritative
|
|
||||||
`state_hub_workstream_id` frontmatter fields; those are a separate file contract.
|
|
||||||
|
|
||||||
## High-Frequency MCP Signatures
|
## High-Frequency MCP Signatures
|
||||||
|
|
||||||
```text
|
```text
|
||||||
|
|
@ -44,12 +33,12 @@ get_domain_summary(domain_slug: str) -> str
|
||||||
get_messages(to_agent?: str, from_agent?: str, unread_only: bool = false, limit: int = 20) -> str
|
get_messages(to_agent?: str, from_agent?: str, unread_only: bool = false, limit: int = 20) -> str
|
||||||
send_message(from_agent: str, to_agent: str, subject: str, body: str, thread_id?: str) -> str
|
send_message(from_agent: str, to_agent: str, subject: str, body: str, thread_id?: str) -> str
|
||||||
|
|
||||||
create_workplan(repo_id: str, title: str, topic_id?: str, slug?: str, description?: str, owner?: str, due_date?: str, planning_priority?: str, planning_order?: int) -> str
|
create_workstream(topic_id: str, title: str, slug?: str, description?: str, owner?: str, due_date?: str, repo_id?: str, planning_priority?: str, planning_order?: int) -> str
|
||||||
create_task(workplan_id: str, title: str, priority: str = "medium", description?: str, assignee?: str, due_date?: str) -> str
|
create_task(workstream_id: str, title: str, priority: str = "medium", description?: str, assignee?: str, due_date?: str) -> str
|
||||||
update_task_status(task_id: str, status: str, blocking_reason?: str, tokens_in?: int, tokens_out?: int, workplan_tokens_in?: int, workplan_tokens_out?: int, note?: str, model?: str, agent?: str, session_id?: str) -> str
|
update_task_status(task_id: str, status: str, blocking_reason?: str, tokens_in?: int, tokens_out?: int, workplan_tokens_in?: int, workplan_tokens_out?: int, note?: str, model?: str, agent?: str, session_id?: str) -> str
|
||||||
bulk_update_task_statuses(updates: list[dict], author?: str = "custodian", session_id?: str) -> str
|
bulk_update_task_statuses(updates: list[dict], author?: str = "custodian", session_id?: str) -> str
|
||||||
add_progress_event(summary: str, event_type: str = "note", topic_id?: str, workplan_id?: str, task_id?: str, detail?: dict | str) -> str
|
add_progress_event(summary: str, event_type: str = "note", topic_id?: str, workstream_id?: str, task_id?: str, detail?: dict | str) -> str
|
||||||
record_decision(title: str, decision_type: str = "pending", topic_id?: str, workplan_id?: str, description?: str, rationale?: str, decided_by?: str, deadline?: str) -> str
|
record_decision(title: str, decision_type: str = "pending", topic_id?: str, workstream_id?: str, description?: str, rationale?: str, decided_by?: str, deadline?: str) -> str
|
||||||
```
|
```
|
||||||
|
|
||||||
`bulk_update_task_statuses` updates `N` task statuses in one call:
|
`bulk_update_task_statuses` updates `N` task statuses in one call:
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,8 @@ MCP: get_domain_summary(domain_slug)
|
||||||
REST: GET /state/summary then filter by topic/domain when MCP is unavailable
|
REST: GET /state/summary then filter by topic/domain when MCP is unavailable
|
||||||
```
|
```
|
||||||
|
|
||||||
Use `get_domain_summary("infotech")` inside State Hub work. It returns the
|
Use `get_domain_summary("custodian")` inside State Hub work. It returns the
|
||||||
domain topic, active workplans, blocking decisions, recent progress, repos,
|
domain topic, active workstreams, blocking decisions, recent progress, repos,
|
||||||
and compact capability hints.
|
and compact capability hints.
|
||||||
|
|
||||||
## Agent Messages
|
## Agent Messages
|
||||||
|
|
@ -30,25 +30,19 @@ REST: PATCH /messages/{message_id}/read
|
||||||
Use repo slugs as agent names. Use `broadcast` only for genuinely shared
|
Use repo slugs as agent names. Use `broadcast` only for genuinely shared
|
||||||
coordination.
|
coordination.
|
||||||
|
|
||||||
## Workplans and Tasks
|
## Workstreams and Tasks
|
||||||
|
|
||||||
```text
|
```text
|
||||||
MCP: create_workplan(repo_id, title, topic_id?, slug?, description?, owner?, due_date?, planning_priority?, planning_order?)
|
MCP: create_workstream(topic_id, title, slug?, description?, owner?, due_date?, repo_id?, planning_priority?, planning_order?)
|
||||||
REST: POST /workplans/
|
REST: POST /workstreams/
|
||||||
|
|
||||||
MCP: create_task(workplan_id, title, priority="medium", description?, assignee?, due_date?)
|
MCP: create_task(workstream_id, title, priority="medium", description?, assignee?, due_date?)
|
||||||
REST: POST /tasks/
|
REST: POST /tasks/
|
||||||
|
|
||||||
MCP: update_task_status(task_id, status, blocking_reason?, tokens_in?, tokens_out?, workplan_tokens_in?, workplan_tokens_out?, note?, model?, agent?, session_id?)
|
MCP: update_task_status(task_id, status, blocking_reason?, tokens_in?, tokens_out?, workplan_tokens_in?, workplan_tokens_out?, note?, model?, agent?, session_id?)
|
||||||
REST: PATCH /tasks/{task_id}
|
REST: PATCH /tasks/{task_id}
|
||||||
```
|
```
|
||||||
|
|
||||||
For repository-owned work, write the workplan/task files and sync with Repo
|
|
||||||
Manager; the create signatures above describe the projection API. Read using
|
|
||||||
`GET /workplans/{id}` and `GET /tasks/?workplan_id=<id>`. Send
|
|
||||||
`X-StateHub-Component: <repo-slug>` on direct HTTP requests for caller attribution.
|
|
||||||
The removed workstream tools and `/workstreams/` routes are not fallbacks.
|
|
||||||
|
|
||||||
Canonical task statuses are `wait`, `todo`, `progress`, `done`, and `cancel`.
|
Canonical task statuses are `wait`, `todo`, `progress`, `done`, and `cancel`.
|
||||||
Legacy aliases are accepted during migration, but do not emit new workplan files
|
Legacy aliases are accepted during migration, but do not emit new workplan files
|
||||||
with old vocabulary.
|
with old vocabulary.
|
||||||
|
|
@ -92,10 +86,10 @@ The endpoint rejects duplicate task ids with `400` and missing task ids with
|
||||||
## Progress and Decisions
|
## Progress and Decisions
|
||||||
|
|
||||||
```text
|
```text
|
||||||
MCP: add_progress_event(summary, event_type="note", topic_id?, workplan_id?, task_id?, detail?)
|
MCP: add_progress_event(summary, event_type="note", topic_id?, workstream_id?, task_id?, detail?)
|
||||||
REST: POST /progress/
|
REST: POST /progress/
|
||||||
|
|
||||||
MCP: record_decision(title, decision_type="pending", topic_id?, workplan_id?, description?, rationale?, decided_by?, deadline?)
|
MCP: record_decision(title, decision_type="pending", topic_id?, workstream_id?, description?, rationale?, decided_by?, deadline?)
|
||||||
REST: POST /decisions/
|
REST: POST /decisions/
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -425,16 +425,6 @@ direct route are live owner residual `RAIL-FAB-WP-0028`. Evidence:
|
||||||
the non-D2 repo-manager/hub-core/activity-core/ops-hub route receipts and the
|
the non-D2 repo-manager/hub-core/activity-core/ops-hub route receipts and the
|
||||||
explicit writer-change authorization already stated above.
|
explicit writer-change authorization already stated above.
|
||||||
|
|
||||||
**Cutover re-baseline 2026-09-05.** Replaced the obsolete slice-readiness
|
|
||||||
snapshot in `docs/retirement-cutover-slice-plan.md` with a family-by-family
|
|
||||||
receiver/caller/parity/rollback checklist. Live Hub Core runtime OpenAPI lacks
|
|
||||||
`/messages`, `/progress`, `/token-events` and `/interface-changes`; its working
|
|
||||||
`/api/v2/interaction-events` is not assumed equivalent. Shared library routers
|
|
||||||
and HUB-WP-0005 completion are insufficient receiving receipts. T08 now records
|
|
||||||
the concrete first read-contract gap. State Hub-to-Core Hub service probes were
|
|
||||||
connection-refused although deployments were ready; transport is also part of
|
|
||||||
that gate. RAIL-FAB-WP-0028 remains proposed and owns hosted Fabric readiness.
|
|
||||||
|
|
||||||
## Retire legacy surfaces
|
## Retire legacy surfaces
|
||||||
|
|
||||||
```task
|
```task
|
||||||
|
|
@ -546,22 +536,6 @@ calendar passage alone is not retirement evidence.
|
||||||
the existing hold; no additional retirement is justified. T04/T05/T06 remain
|
the existing hold; no additional retirement is justified. T04/T05/T06 remain
|
||||||
`wait` with their existing owner and quiet-window dependencies.
|
`wait` with their existing owner and quiet-window dependencies.
|
||||||
|
|
||||||
**Authorized retirement and caller migration 2026-09-05.** Fresh seven-day
|
|
||||||
primary evidence made `GET /sbom/report/licences/` and `GET /sbom/snapshots/`
|
|
||||||
eligible. Verified direct Nexus endpoints (200), then marked both interfaces
|
|
||||||
retired with T05 provenance. Receipt:
|
|
||||||
`docs/evidence/STATE-WP-0079-sbom-retirement-20260905.json`. Eight retired,
|
|
||||||
seven legacy, zero remaining candidates. Compatibility handlers/history remain;
|
|
||||||
this is meter retirement, not a router deletion or application deployment.
|
|
||||||
|
|
||||||
Session traces identified ad-hoc task-filter callers in fluid-telegram and
|
|
||||||
ops-warden. Corrected their AGENTS.md canonical-query/component-header guidance,
|
|
||||||
plus this repository's stale skill and API documentation. Canonical verification
|
|
||||||
returned 200 with 8/5 tasks. This does not explain every historical call or prove
|
|
||||||
future silence: unresolved task/workstream-detail/SBOM-index attribution is T07.
|
|
||||||
Available pod logs begin after the last calls. Evidence and limits:
|
|
||||||
`docs/evidence/STATE-WP-0079-caller-and-receiver-review-20260905.md`.
|
|
||||||
|
|
||||||
## Stabilization window and archive prep
|
## Stabilization window and archive prep
|
||||||
|
|
||||||
```task
|
```task
|
||||||
|
|
@ -581,49 +555,6 @@ stop, or repository archive would therefore interrupt normal work and destroy
|
||||||
the evidence needed by T05. T06 remains `wait` until T04 and T05 are done and a
|
the evidence needed by T05. T06 remains `wait` until T04 and T05 are done and a
|
||||||
fresh central meter demonstrates the required zero normal read/write window.
|
fresh central meter demonstrates the required zero normal read/write window.
|
||||||
|
|
||||||
## Attribute and finish migrating remaining legacy readers
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: STATE-WP-0079-T07
|
|
||||||
status: wait
|
|
||||||
priority: high
|
|
||||||
state_hub_task_id: "2ac16837-454a-5a92-9385-c91cd3219aa2"
|
|
||||||
```
|
|
||||||
|
|
||||||
Owner: state-hub. T05 follow-up from the 2026-09-05 scan. Two ad-hoc task-query
|
|
||||||
callers were identified and their instructions corrected; the full 11 task
|
|
||||||
calls, seven workstream-detail calls and one SBOM index call remain only
|
|
||||||
partially attributed. Existing retained logs postdate these calls. Wait for
|
|
||||||
new attributed observations or recoverable historical request evidence; do not
|
|
||||||
reset the clocks with test calls. Trace remaining callers, migrate them to the
|
|
||||||
verified replacements, and attach fresh quiet-window evidence before retirement.
|
|
||||||
Use `X-StateHub-Component` for direct agent HTTP requests. No inference from
|
|
||||||
an `unknown` bucket alone is sufficient to assign an owner.
|
|
||||||
|
|
||||||
## Prove the first deployed hub-core message-read contract
|
|
||||||
|
|
||||||
```task
|
|
||||||
id: STATE-WP-0079-T08
|
|
||||||
status: todo
|
|
||||||
priority: high
|
|
||||||
state_hub_task_id: "9d508739-6123-5204-b829-750b3ebf0e63"
|
|
||||||
```
|
|
||||||
|
|
||||||
Receiving owner: hub-core; State Hub owns source/caller evidence under T04.
|
|
||||||
The live receiver's 31-path OpenAPI has no message/progress/token/interface-log
|
|
||||||
families. Identify or assemble the owner message-read contract, auth/transport,
|
|
||||||
and historical projection in the receiving runtime. State Hub-to-owner service
|
|
||||||
probes were connection-refused in this review; diagnose the actual transport
|
|
||||||
before assuming a usable proxy path. Do not substitute `/api/v2/interaction-events`
|
|
||||||
without an explicit semantic mapping.
|
|
||||||
|
|
||||||
Then run a bounded read-only inbox parity pilot over one consistent snapshot,
|
|
||||||
checking message IDs, ordering, read/archive flags and scope filters; record
|
|
||||||
exact revisions and rollback to the retained State Hub read. Done when receiving
|
|
||||||
readiness and parity/rollback receipts make one concrete reader switch reviewable.
|
|
||||||
Production message writers stay unchanged during this proof. Related owners:
|
|
||||||
HUB-WP-0004/0005; the full B2/B3 route migration is not implied by this task.
|
|
||||||
|
|
||||||
## Acceptance
|
## Acceptance
|
||||||
|
|
||||||
- [x] Freeze policy documented
|
- [x] Freeze policy documented
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue