--- id: RMGR-WP-0004 type: workplan title: "Repository standards conformance and governed scaffolding" domain: infotech repo: repo-manager status: active owner: codex topic_slug: infotech created: "2026-08-16" updated: "2026-08-18" parent_project: prj-state-hub-retirement parent_workplan: SHR-WP-0001 related: - STATE-WP-0080 - STATE-WP-0079 - RMGR-WP-0001 - CFED-WP-0001 state_hub_workstream_id: "b8b3f1e0-b8df-4405-849e-11ec51f80ae5" --- # Repository standards conformance and governed scaffolding ## Goal Establish Repo Manager as the owner of **the standards repositories must comply with** — flavor, required files, naming conventions, classification, and conformance checking — and of the governed scaffolding that creates conformant repositories. Hubs are registers. They index and project repository-owned records; they do not scaffold, template, or rewrite repository files. This workplan moves that capability to its correct owner. ## Decision basis `prj-state-hub-retirement` decision `747011c6` (2026-08-16, Bernd Worsch): > 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. This extends **ADR-001** (hub is a read model) from *data* to *behaviour*. A hub that writes `INTENT.md`, `AGENTS.md`, `.custodian-brief.md`, and bootstrap workplans into repositories is already outside its own boundary — the register path is repo mutation wearing hub clothing. It is a placement correction rather than a scope expansion: `SCOPE.md` already claims "repository registration, identity, classification, and lifecycle" and "controlled repository mutation through explicit commands and policy checks". ## Model repository standards explicitly ```task id: RMGR-WP-0004-T01 status: done priority: high state_hub_task_id: "dd2db30f-c48f-404d-a1b4-bd75b41d42f4" ``` Give Repo Manager a first-class representation of the standards a repository is expected to satisfy, rather than encoding them implicitly in a scaffolding script. At minimum: - **flavor** — product, tooling, research, business, experimental, project (`prj-`), and how it is determined (`.repo-classification.yaml` `category`, `GOAL.md` `repo_flavor`, slug prefix, in that precedence); - **required files** per flavor, with the purpose document differing by flavor (`INTENT.md` for durable repos, `GOAL.md` for `prj-`); - **naming conventions** — repo slug, workplan prefix derivation; - **anti-patterns** that are violations rather than gaps (shipping both `INTENT.md` and `GOAL.md`; a flavor-derived workplan prefix). Source standards: `project-repository-flavor_v0.1.md` and `repo-classification-standard_v1.0.md` in the Custodian canon. Canon stays authoritative; Repo Manager implements against it and must not fork the rules into a second definition. **Result (2026-08-18):** `src/repo_manager/standards.py` resolves flavor (classification → GOAL.md → `prj-` slug), lists required files, and names anti-patterns (`INTENT.md`+`GOAL.md`, `PRJ-WP-`). Index: `docs/repository-standards_v0.1.md`. ## Implement conformance checking ```task id: RMGR-WP-0004-T02 status: todo priority: high state_hub_task_id: "2c9b0cb1-f0f0-40f7-83ef-1828298338d3" ``` Check a repository against its flavor's standard and report violations with enough detail to fix them. Distinguish **missing** (a required file absent) from **contradictory** (an anti-pattern present) — the second is the more valuable signal and the one that went undetected twice. Expose it as a command and as a contract other components can call, so the consistency lane and agent sessions get the same answer. Known first findings, both live today: - `prj-canon-federation` and `prj-state-hub-retirement` were each scaffolded with a forbidden `INTENT.md` that had to be deleted by hand; - every `prj-` repo would collide on workplan prefix `PRJ-WP-`, because the prefix is derived from the flavor marker rather than from the project. **Opened (2026-08-18):** `rmgr conform` reports `missing` vs `contradictory` and flags both known findings. Remaining: call from the consistency lane / STATE-WP-0080 guard. (Do not set `progress` until `RMGR-WP-0005-T06` stops C-15 forcing this task back to `wait`.) ## Own governed scaffolding ```task id: RMGR-WP-0004-T03 status: done priority: high state_hub_task_id: "8e6fa8d7-f169-44f5-bdc9-29376bb2ef64" ``` Take ownership of creating conformant repository files, replacing the templating currently embedded in `state-hub/statehub_register.py` (872 lines, with no reference to `.repo-classification.yaml`, `category`, or `repo_flavor` anywhere — the root cause of both failures). Requirements: - flavor-correct purpose document: `GOAL.md` for `prj-` repos with the four sections the standard requires (Outcome, Invariants, Success gates, Project retirement), `INTENT.md` for durable repos, never both; - workplan prefix derived from the project, not the flavor marker; prompt or require explicit input rather than emitting a colliding default; - no generic bootstrap workplan for project repos, which compete with the foundation workplan the project actually needs; - scaffolding is a **command** in the Repo Manager sense — requested action distinct from confirmed repository state, with the resulting revision and a normalized event recorded (`SCOPE.md` § API boundary). Behaviour for durable product repos must be preserved exactly; this workplan changes where the capability lives and how project repos are treated, not what ordinary repos receive. **Result (2026-08-18):** `rmgr scaffold` writes flavor-correct baselines. `prj-` requires `--wp-prefix` (never `PRJ-WP-`), writes `GOAL.md` with the four required sections, and does not emit a bootstrap workplan. Durable flavors get `INTENT.md` and an optional foundation workplan. ## Regenerate agent instructions per flavor ```task id: RMGR-WP-0004-T04 status: wait priority: medium state_hub_task_id: "8cd3ba11-b16b-4910-8bf6-651a24d47b8c" ``` `make update-agent-instructions` regenerates `AGENTS.md`, `CLAUDE.md`, `.claude/rules/`, and `.custodian-brief.md` from templates that assume every repo has an `INTENT.md`. Bring regeneration under the same flavor model so running it on a `prj-` repo produces the standard's session order — `GOAL.md` → `SCOPE.md` → history → active workplans — rather than reintroducing `INTENT.md` references on every run. This matters beyond first registration: regeneration runs fleet-wide, so a flavor-blind template silently re-breaks conformant repos. ## Accept the handoff from state-hub ```task id: RMGR-WP-0004-T05 status: wait priority: medium state_hub_task_id: "8402b8b6-2a1e-4236-b27d-d50b6161a176" ``` Coordinate the transfer with `STATE-WP-0080`, which is retargeted to a thin guard plus handoff rather than a parallel implementation: - agree the cutover point at which `statehub register` delegates or refuses; - confirm the register path's disposition in `prj-state-hub-retirement/inventory/` reads `move` to `repo-manager`, not `keep`; - keep `SHR-WP-0001` as the coordination point; link by ID, do not duplicate its task list. Follow the dual-run strangler pattern already proven in `RMGR-WP-0002` and `RMGR-WP-0003` rather than a flag-day switch. ## Add compatibility and regression tests ```task id: RMGR-WP-0004-T06 status: wait priority: medium state_hub_task_id: "faaeb016-3ba8-493a-bbdf-9227de24f720" ``` Per `SCOPE.md` § Initial extraction source, extraction must preserve behaviour with compatibility tests. Cover: - a `prj-` repo scaffolds `GOAL.md`, no `INTENT.md`, no flavor-derived prefix; - a durable repo's scaffolded output is byte-identical to the state-hub path (regression guard against changing ordinary-repo behaviour); - conformance checking flags both known live findings from T02; - flavor signals that disagree warn rather than silently resolving; - re-running scaffolding on a conformant repo is idempotent. ## Enforce workplan identifier uniqueness ```task id: RMGR-WP-0004-T08 status: done priority: high state_hub_task_id: "fc7395b0-e86d-4231-baac-ea7fa5dc2174" ``` Implement `ADR-007` decision 1 as a repository standard: `PREFIX-WP-NNNN` names exactly one workplan fleet-wide, for all time. - **Prefix ownership registry** — one prefix, one repository. New machinery: no such registry exists today. `C-26` checks prefix conformance *within* a repo against a canonical prefix, but nothing checks across repos. - **Forward-only numbering** — a running number is never reused within a prefix, including after cancel, archive, or delete. - **Prefixes derive from project or repository identity**, never from a flavor marker or category. This is what makes `PRJ-WP-` invalid by construction and connects back to T03. Live violations to detect (fleet scan, 2026-08-16 — 955 hub workplans, 525 parseable identifiers): ```text prefixes shared across repos: CUST-WP- state-hub, the-custodian RAIL-BS-WP- railiance-bootstrap, railiance-cluster RAILIANCE-WP- railiance-apps, railiance-forge, railiance-platform, railiance-telemetry identifiers reused: CUST-WP-0000 / 0010 / 0045 the-custodian ×2 each RAILIANCE-WP-0015 railiance-platform, railiance-apps RAILIANCE-WP-0016 railiance-platform ×2, railiance-apps ``` Detection only. Remediating the existing collisions is an open ruling in `ADR-007` § Migration and is not authorized by this task. **This task gates `RMGR-WP-0005`.** Deterministic identifier derivation from a non-unique identifier would manufacture UUID collisions rather than remove them. **Result (2026-08-18):** `config/workplan-prefix-registry.yaml` plus `rmgr prefix-uniqueness --root `. Detection only: shared prefixes, reused identifiers, `PRJ-WP-`, retired prefixes still in use. A 112-repo scan still finds `CUST-WP`, `RAILIANCE-WP`, `PRJ-WP` (in `prj-forgejo-org-refactor`). Remediating historical collisions remains ADR-007 § Migration. ## Assign ownership of the shared prefixes ```task id: RMGR-WP-0004-T09 status: wait priority: high state_hub_task_id: "3a6ba954-4e35-4b2d-8dff-d3db84ed832c" ``` Three prefixes are shared across seven repositories, each a single number line allocated from concurrently. Under `ADR-007` decision 1 each must resolve to one owning repository **before the next workplan is created** in the affected repos. This is forward conformance, not migration: `ADR-007` § Migration ruled option 2, so historical files keep their identifiers and are not renamed. | Prefix | Current holders | State | |---|---|---| | `CUST-WP-` | the-custodian (50), state-hub (4 legacy) | dormant on the state-hub side | | `RAIL-BS-WP-` | railiance-cluster (6), railiance-bootstrap (2) | **growing** — `RAIL-BS-WP-0014` ready | | `RAILIANCE-WP-` | railiance-platform (12), apps (2), forge (1), telemetry (1) | **growing** — forge `0002` ready, telemetry `0001` proposed | Assignments: - `CUST-WP-` → `the-custodian`. `state-hub`'s canonical prefix is already `STATE-WP` (`C-26` says so today); its four legacy files stay as history. - `RAIL-BS-WP-` → **retired; neither repo keeps it** (decided 2026-08-17). `railiance-cluster` adopts **`RCLUSTER-WP-`**, `railiance-bootstrap` adopts **`RBS-WP-`**. - `RAILIANCE-WP-` → **retired; none of the four keep it** (decided 2026-08-17). `RAILIANCE` names a family, not a repository, so it fails decision 1's requirement that prefixes derive from project or repository identity — the same defect as `PRJ-WP-`. Successors: `railiance-platform` → `RPF-WP-`, `railiance-apps` → `RAPPS-WP-`, `railiance-forge` → `RFORGE-WP-`, `railiance-telemetry` → `RTELE-WP-`. ### Execution (2026-08-17) — completed as an authorized exception Executed centrally rather than by a worker in each repository, as an explicit exception to `ADR-007` decision 4, authorized by Bernd. Recorded here because decision 4 requires exceptions to carry a stated reason: six repositories needed one coordinated change with a shared numbering rule, and sequencing six independent workers would have risked partial adoption. Live plans migrated (prefix changed, running number preserved): ```text railiance-cluster RAIL-BS-WP-0007 (backlog) -> RCLUSTER-WP-0007 RAIL-BS-WP-0014 (ready) -> RCLUSTER-WP-0014 railiance-forge RAILIANCE-WP-0002 (ready) -> RFORGE-WP-0002 railiance-telemetry RAILIANCE-WP-0001 (proposed) -> RTELE-WP-0001 ``` Next allocations, each above the repo's historical maximum: `RCLUSTER-WP-0015` · `RBS-WP-0010` · `RPF-WP-0018` · `RAPPS-WP-0017` · `RFORGE-WP-0003` · `RTELE-WP-0002`. Also updated: each repo's `.claude/rules/workplan-convention.md` (and `AGENTS.md` where it declared the prefix), which governs what future agents allocate; `railiance-bootstrap/docs/POINTER-RAIL-BS-WP-0007.md` renamed and rewritten; `railiance-forge/.custodian-brief.md`. Deliberately left unchanged: `state-hub/reports/recently-on-scope/**` are dated point-in-time snapshots and must keep the identifiers current when they were written. `railiance-master`'s `REEF-RAILIANCE-WP-0001` is a different prefix and was a false positive in the reference sweep. Hub UUIDs were preserved in every migrated file, so reconciliation matches on `state_hub_workstream_id` (C-03/C-06 join on that field, not the filename) and will update slugs in place rather than registering duplicates. **Not yet reconciled** — the workstation is not the registrar under `ADR-007` decision 2. Two collisions surfaced during execution and remain as historical record under option 2: `railiance-cluster` carries its own copies of `RAIL-BS-WP-0008` and `0009`, which also exist in `railiance-bootstrap`; and `railiance-forge` holds an archived `RAILIANCE-WP-0001` that duplicated `railiance-telemetry`'s live one until this migration separated them. ### RAIL-BS- retirement detail `railiance-cluster` switches **active and future** plans to `RCLUSTER-WP-`; `railiance-bootstrap` takes `RBS-WP-` for future plans. Finished and archived files keep `RAIL-BS-WP-` as historical record, per the option 2 ruling. Migrating plans keep their running numbers — prefix changes, number does not: ```text railiance-cluster RAIL-BS-WP-0007 (backlog) -> RCLUSTER-WP-0007 RAIL-BS-WP-0014 (ready) -> RCLUSTER-WP-0014 next allocation = RCLUSTER-WP-0015 finished 0010-0013 stay as RAIL-BS-WP- railiance-bootstrap no live plans to migrate (0008, 0009 both finished) next allocation = RBS-WP-0010 ``` Preserving numbers keeps traceability and cannot violate forward-only allocation, since neither new prefix has prior history. `railiance-bootstrap` starts at **0010**, above its historical maximum of 9, rather than at 0001. This keeps `RBS-WP-0001`–`0009` free in case its two finished plans are ever adopted into the new prefix; starting at 0001 would make that adoption collide later. Execution belongs to workers in `railiance-cluster` and `railiance-bootstrap` per `ADR-007` decision 4 — this task records the assignment and the numbering rule, and does not perform the rename. Each repo also needs the hub records and any inbound references updated with the file rename. Per `ADR-007` decision 4, the rename of a repository's own convention is executed by a worker in that repository. This task assigns and records ownership in the registry (T08) and coordinates; it does not reach in and rewrite those repos. `RAILIANCE-WP-0015`'s ambiguity between `railiance-apps` and `railiance-platform` persists by design under option 2. Note it in the registry so citations are forced to name the repository. ## Confirm the canon boundary ```task id: RMGR-WP-0004-T07 status: wait priority: low state_hub_task_id: "7fdd54fe-fba7-4713-9814-d4534ff19706" ``` Repo Manager implements repository standards; it does not author them. Confirm with the Custodian that canon remains the authoritative source and record where the seam sits, so conformance rules do not drift into a second definition inside this repo. If the ownership shift warrants it, the Custodian may want an ADR recording that repository-standards enforcement is a Repo Manager responsibility — that is a Custodian decision, raised from here, not made here.