RMGR-WP-0004-T03: project repos get GOAL.md and a required prefix. RMGR-WP-0005-T06 implemented in state-hub consistency.
393 lines
16 KiB
Markdown
393 lines
16 KiB
Markdown
---
|
||
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 <fleet>`. 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.
|