--- id: RMGR-WP-0008 type: workplan title: "Receiving surface for work records and repository registers" domain: infotech repo: repo-manager status: active owner: codex topic_slug: infotech created: "2026-08-20" updated: "2026-08-21" parent_project: prj-state-hub-retirement parent_workplan: SHR-WP-0001 related: - STATE-WP-0079 - RMGR-WP-0002 - RMGR-WP-0003 - RMGR-WP-0004 - HUB-WP-0004 state_hub_workstream_id: "f45cebf3-7d49-471d-a903-d711e19f7653" --- # Receiving surface for work records and repository registers ## Goal Build the repo-manager surfaces that `STATE-WP-0079`'s cutover slices need in order to move. Today most of those slices have nowhere to land, and that — not anything inside State Hub — is what blocks the retirement. ## Why this exists `STATE-WP-0079-T02` produced a cutover slice plan (`state-hub/docs/retirement-cutover-slice-plan.md`) assigning all 425 `SHR-INV-0001` items to slices. Its first owner-readiness pass read readiness off workplan status: RMGR-WP-0001/0002/0003 are `finished`, so all 167 repo-manager-owned items were marked receivable. That was wrong, and the correction (2026-08-20) is the reason for this workplan. Verified against `src/repo_manager/`: - `parse/` contains **only** `workplan.py` - `rmgr` subcommands are `observe`, `reconcile`, `task-status`, `conform`, `prefix`, `scaffold`, `dual-run-status` - the source tree has **no** reference to `sbom`, `repo_goal`, `contribution`, `technical_debt`, or `extension_point` - the State Hub adapter calls exactly three operations — `rm_update_task_status`, `rm_reconcile`, `rm_scaffold` What RMGR-WP-0001/0002/0003 delivered is work-record dual-run for **task status**, repository observation, and scaffolding. Not a general work-record write path, and not a register surface at all. **Net effect:** of 425 inventory items, roughly **6** can move today (slice A2a, task status + reconcile). The rest wait on surfaces built here or in `hub-core`. ## Scope boundary This workplan builds **receiving surfaces in repo-manager**. It does not change State Hub beyond the adapter calls that route to these surfaces. Building any of this in State Hub instead is inadmissible under `state-hub/policies/retirement-freeze.md`: it would establish new permanent ownership in the component being retired, and would build the capability twice. Per `SCOPE.md`, file-backed records in domain repos stay authoritative; these surfaces index and govern them, they do not become a second source of truth. ## Workplan write path ```task id: RMGR-WP-0008-T01 status: done priority: high state_hub_task_id: "5ef517b4-94a6-48d4-b200-827460f79e92" ``` Extend the work-record write path beyond task status to workplan create, update, status change, and delete. `parse/workplan.py` already reads workplans; this adds the governed mutation side and an `rm_update_workplan` counterpart to `rm_update_task_status`. Unblocks slice **A2b** (~9 routes plus `table:workplans`). Follow the RMGR-WP-0002 dual-run shape — writeback, reconcile, mutation meter — rather than inventing a second mechanism. Result (2026-08-21): `rmgr workplan create|update|delete` now owns the file-backed mutation path. Update accepts canonical ids or State Hub UUIDs; delete is a confirmed, recoverable archive operation. All three operations use optimistic HEAD checks, idempotency, Git evidence, reindexing, normalized events, mutation metering, and optional push-seal. State Hub has the matching `rm_update_workplan` compatibility adapter. Repo Manager's full suite and the adapter's focused compatibility tests pass. ## Intake records ```task id: RMGR-WP-0008-T02 status: done priority: medium state_hub_task_id: "017f3b29-7100-4771-98c0-59fe91895a5f" ``` Add an intake parser and index entry kind, plus the write path for create, route, note, and close. Intake is the successor to the retired suggestion backlog, so this is the discovery surface's permanent home. Unblocks slice **A2c** (9 items: 7 routes, `table:intakes`, `table:intake_notes`). Result (2026-08-21): Repo Manager indexes typed intake YAML fences from repository record locations and provides governed `intake create|route|note|close` commands. Mutations are file-backed, committed with correlation evidence, idempotent when keyed, reindexed, and metered. ## Decision records ```task id: RMGR-WP-0008-T03 status: done priority: medium state_hub_task_id: "392ac64d-15b6-4f4e-9e18-96dd7d299208" ``` Add a decision parser, index entry kind, and write path including resolve. Note the coupling: `resolve_decision` is one of only two write operations sanctioned against the hub in the fleet agent instructions. Whatever replaces it must keep that guarantee — agents rely on it being available and safe. Unblocks slice **A2d** (8 items, including `caller:agentic-resources`). Result (2026-08-21): typed decision records share the Markdown/YAML receiving spine and expose governed `decision create|update|resolve`. Resolve refuses incomplete decisions unless both rationale and deciding identity are present, preserving the safety guarantee of the former hub operation. ## Dependencies and human-flag records ```task id: RMGR-WP-0008-T04 status: done priority: low state_hub_task_id: "216a03e6-a0ee-4e30-ae96-fa11e77a22ac" ``` Workplan dependency edges and human-intervention flags. Smallest of the work-record slices and the least coupled; a reasonable first cut if T01 proves too large to land in one piece. Unblocks slice **A2e** (~6 items) and the dependency routes inside A2b. Result (2026-08-21): workplan and task `depends_on` values, plus task `needs_human`, `intervention_note`, and `blocking_reason`, survive parsing into the replaceable index. Their authority remains the workplan file. ## Repository registers ```task id: RMGR-WP-0008-T05 status: progress priority: high state_hub_task_id: "902c71da-1ba5-4e76-bf20-0d9f697edf7a" ``` The largest gap. Six registers with no counterpart in repo-manager at all: | Register | Items | Notes | | --- | --- | --- | | `sbom-inventory` | 10 | lockfile ingest, licence report, copyleft detection | | `repo-goals` | 9 | | | `upstream-contributions` | 9 | | | `register-technical-debt` | 9 | also backs dashboard UI feedback — check before moving | | `register-extension-points` | 6 | | | `register-entries` | 6 | MCP tools only | Unblocks slice **A3** (49 items). Treat as one register spine with per-kind schemas rather than six unrelated features — they share repo scoping, append-mostly write patterns, and the same file-backed-authority rule. Progress (2026-08-21): the shared spine is live for all six kinds as versioned `registers/.yaml` files, with parser/index support and governed `put`/`defer`/`note` commands. Kind-specific required fields cover the existing State Hub create contracts, and the generic `rm_update_register_entry` adapter can route compatibility writes. Remaining before `done`: lockfile ingestion, licence/copyleft derived reports, route-level cutover fixtures, and migration of the live register rows. ## Topic and classification contract ```task id: RMGR-WP-0008-T06 status: progress priority: medium state_hub_task_id: "ef7934de-a1e2-4541-8068-e75876446b60" ``` `observe`/`load_classification` read `.repo-classification.yaml` today. Slice **A5** (`topic-spine`, 8 items) is dispositioned `replace`, so it needs a published contract rather than a lift-and-shift of the hub's tables. Coordinate with HUB-WP-0004: the topic spine sits on the boundary between repository classification (here) and cross-domain projection (`hub-core`). Progress (2026-08-21): published `docs/repository-classification-contract_v1.0.{md,yaml}` and made observation reject invalid controlled values, repeated primary domains, malformed lists, and non-kebab capability tags. Remaining: hub-core acknowledges the projection boundary and A5 consumers are routed to the contract. Coordination request `bca85a3f-83be-44e3-a95e-e3d4b4d812eb` is with `hub-core`. ## Owner-side UI ```task id: RMGR-WP-0008-T07 status: wait priority: low state_hub_task_id: "24ee329d-85dd-4e11-9c87-2f20b8f86e81" ``` Slice **A4** (22 items, `replace`) assumes an owner-side dashboard. `rmgr` is a CLI; there is none, and it is not obvious there should be one — the work-coordination and repo views may belong to `hub-core`'s projection layer instead. Deliberately `wait`: settle ownership before building. Resolve with HUB-WP-0004 and record the outcome as a decision. Do not default to building a dashboard here just because the inventory named repo-manager. ## Acceptance - [x] Workplan write path live, A2b routable through the adapter - [x] Intake and decision parsers + write paths live; `resolve_decision` guarantee preserved - [ ] Register spine live, A3's six registers routable - [ ] Topic/classification contract published; agreement with hub-core pending - [ ] A4 ownership decided and recorded - [ ] Compatibility tests per slice, matching the RMGR-WP-0002 evidence pattern