--- id: STATE-WP-0080 type: workplan title: "statehub register: stop repo scaffolding, hand off to repo-manager" domain: infotech repo: state-hub status: active owner: codex topic_slug: infotech created: "2026-08-16" updated: "2026-08-19" parent_project: prj-state-hub-retirement parent_workplan: SHR-WP-0001 related: - RMGR-WP-0004 - STATE-WP-0079 - CFED-WP-0001 - SHR-WP-0001 state_hub_workstream_id: "03f38314-7d2c-42ee-bd1e-b0cc555dc06b" --- # statehub register: stop repo scaffolding, hand off to repo-manager ## Goal Stop `statehub register` from producing non-conformant repository files, and hand repository scaffolding and standards conformance to `repo-manager` — where decision `747011c6` places them. **This workplan does not implement flavor awareness.** That is `RMGR-WP-0004`. The state-hub side is a guard, a delegation, and a clean exit. ## Why this changed shape Drafted 2026-08-16 as a full flavor-awareness implementation inside `statehub_register.py`; retargeted the same day after decision `747011c6`: > Hubs are registers: they index and project repository-owned records. They do > not scaffold, template, or rewrite repository files. Repo Manager owns > repository representation and governed mutation, and therefore owns the > standards repositories must comply with. Implementing here would have built the capability twice, inside the component being retired under `STATE-WP-0079`, and deepened exactly the boundary violation the hub refactor exists to remove. The originating residual (`SHR-WP-0001-T01`) is unchanged; only its owner is. Tasks T05–T08 below are `cancel`led with pointers to their `RMGR-WP-0004` successors. They are retained rather than deleted so the handoff is legible. ## The defect being contained `statehub_register.py` has no reference to `.repo-classification.yaml`, `category`, or `repo_flavor` in 872 lines, so it cannot distinguish a project repository from a durable product repository. It therefore: - writes `INTENT.md` unconditionally (`:248`) and treats missing intent as a hard error (`:786`–`:790`), though `project-repository-flavor_v0.1` calls shipping both `INTENT.md` and `GOAL.md` an anti-pattern and forbids requiring `INTENT.md` on `prj-` repos; - derives the workplan prefix from the slug (`:78`, `_default_wp_prefix`), yielding `PRJ-WP-` for every project repo, so all `prj-` repos collide; - writes a generic `{PREFIX}-0001-statehub-bootstrap.md` (`:269`) that competes with the project's real foundation workplan. Hit twice: `prj-state-hub-retirement` and `prj-canon-federation`, both requiring manual deletion after registration. ## Guard against non-conformant scaffolding ```task id: STATE-WP-0080-T01 status: done priority: high state_hub_task_id: "65c52600-15fe-45bd-82b1-dfeff54698af" ``` Add a minimal flavor guard to the register path — detect project flavor from `.repo-classification.yaml` `category`, `GOAL.md` `repo_flavor`, or the `prj-` slug prefix, and on a match **refuse to scaffold**, with a message pointing at `repo-manager`, rather than writing files the standard forbids. Deliberately a refusal, not an implementation: a partial flavor-aware templating path here would become a second source of truth competing with `RMGR-WP-0004`. Durable-repo behaviour is untouched. **Result (2026-08-18):** `statehub register` exits before writing files when any of those three signals match. Message points at `rmgr scaffold --path --flavor project --wp-prefix -WP`. Durable path (`write_registration_files`) is unchanged. ## Delegate registration scaffolding ```task id: STATE-WP-0080-T02 status: done priority: high state_hub_task_id: "ab1e079c-b36f-4bfc-a9fd-fb43f7f93924" ``` Once `RMGR-WP-0004-T03` lands, route scaffolding through Repo Manager instead of refusing, using the dual-run strangler pattern already proven in `RMGR-WP-0002` and `RMGR-WP-0003`. Hub-side registration keeps only what a register legitimately does: record the repo, its identity, and its host path. Coordinate the cutover point with `RMGR-WP-0004-T05`. **Opened (2026-08-18):** T01 guard is live and `RMGR-WP-0004-T03` (`rmgr scaffold`) has landed. Ready to replace the refusal with a delegated scaffold call. **Result (2026-08-18):** `statehub register` on a project-flavor checkout: refuses without `--wp-prefix` if `GOAL.md` is missing (T01); with `--wp-prefix` calls `rmgr scaffold` via the dual-run adapter and skips `write_registration_files`; if `GOAL.md` already exists, registers the repo + host path only. Durable repos still use hub templating. ## Correct the inventory disposition ```task id: STATE-WP-0080-T03 status: done priority: medium state_hub_task_id: "91cb1a33-7748-4d65-bfbc-bad21234e364" ``` Confirm the register/scaffolding capability is dispositioned `move` → `repo-manager` in `prj-state-hub-retirement/inventory/`, not `keep`. If it is recorded as `keep`, correct it and cite decision `747011c6` — `SHR-INV-0001` is the retirement lane's source of truth, and a stale disposition would resurrect the boundary violation during cutover. **Result (2026-08-18):** Already `move`. `jobs-callers-ops.yaml` `caller:custodian-cli` (`custodian_cli / statehub register`) is `disposition: move`, `owner: repo-manager`, capability `repo-onboarding`. No inventory edit required. ## Remove the templating path ```task id: STATE-WP-0080-T04 status: wait priority: low state_hub_task_id: "342aa5e8-96d0-4832-be60-f48815a86f71" ``` After delegation is live and `RMGR-WP-0004-T06` compatibility tests pass, delete the templating code from `statehub_register.py` — `INTENT.md` generation, the `AGENTS.md` / `CLAUDE.md` / `.custodian-brief.md` templates, `project_rules/`, and bootstrap-workplan generation. Sequence behind `STATE-WP-0079`'s strangler so removal lands with the rest of the retirement rather than as an isolated breaking change. **Readiness audit (2026-08-19):** Delegation remains live and the State Hub registration regression suite passes (`20 passed`). Repo Manager's focused scaffold/standards suite also passes (`11 passed`), but `RMGR-WP-0004-T06` correctly remains `wait`: it does not yet test byte-identical durable output against the State Hub path or idempotent re-scaffolding. `STATE-WP-0079-T03` is now recorded done because T01/T02 above supply its project/`GOAL.md` adapter; the broader `STATE-WP-0079-T04` move/replace slice is still `todo`. Do not delete this path until both gates close. ## Moved: generated templates and briefs ```task id: STATE-WP-0080-T05 status: cancel priority: medium state_hub_task_id: "03224fa5-56f1-4e32-bc2e-40457dceb9cc" ``` Cancelled — moved to **`RMGR-WP-0004-T04`** by decision `747011c6`. Worth carrying forward explicitly: `make update-agent-instructions` runs fleet-wide and shares the flavor-blind templates, so it silently re-breaks conformant `prj-` repos on every run. That is a larger blast radius than first registration, and it must not be lost in the handoff. ## Moved: conformance check ```task id: STATE-WP-0080-T06 status: cancel priority: low state_hub_task_id: "47adb8e3-2a03-45b9-9647-fc4e42c58cd1" ``` Cancelled — moved to **`RMGR-WP-0004-T02`** by decision `747011c6`. Conformance checking is the clearest case for the new boundary: judging whether a repository satisfies its standard is repository representation, not hub projection. Repo Manager exposes it as a command and a contract; the hub consumes the result rather than computing it. ## Moved: tests ```task id: STATE-WP-0080-T07 status: cancel priority: medium state_hub_task_id: "c056b8fd-d91b-4cf0-973c-d74d8e718dd1" ``` Cancelled — moved to **`RMGR-WP-0004-T06`** by decision `747011c6`. The byte-identical-output regression guard for durable repos stays essential: the handoff must not change what ordinary repositories receive. ## Superseded: carry the fix forward ```task id: STATE-WP-0080-T08 status: cancel priority: medium state_hub_task_id: "15eca52e-7c3b-40a7-b2a8-38b0313f57a8" ``` Cancelled — superseded by decision `747011c6`, which answered this task's open question outright. It asked whether `repo-manager` was close enough to take the work; the decision settled that repository standards belong there regardless of timing, and `RMGR-WP-0004` now carries the whole implementation. Retained as the record of where the retarget originated.