repo-manager/workplans/RMGR-WP-0004-repository-standards-conformance.md
tegwick ad621d6c0d feat: advance conformance and deterministic ID migration
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
2026-08-21 22:43:37 +02:00

509 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
id: RMGR-WP-0004
type: workplan
title: "Repository standards conformance and governed scaffolding"
domain: infotech
repo: repo-manager
status: finished
owner: codex
topic_slug: infotech
created: "2026-08-16"
updated: "2026-08-21"
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: done
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.
**Result (2026-08-21):** `rmgr conform` reports `missing` vs
`contradictory` and flags both known findings. The earlier C-15 gate is gone:
`RMGR-WP-0005-T06` is complete, so this task is no longer `todo` in substance.
The compatibility call is now live as State Hub consistency check C-35
(`state-hub` commit `b9d9ffe`). It executes the Repo Manager command and
projects its findings without copying flavor rules into the retiring hub.
## 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: done
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.
Result (2026-08-21): current generator and fleet output were re-audited rather
than changed from the stale task premise. Templates are brief-first and contain
no `INTENT.md` assumption; the four `prj-` repositories have zero incorrect
purpose-document references. The two literal `INTENT.md` mentions explicitly
say project repositories use `GOAL.md`, which is the desired safeguard.
Repo Manager conformance is now the regeneration guard via C-35.
## Accept the handoff from state-hub
```task
id: RMGR-WP-0004-T05
status: done
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.
**Opened (2026-08-18):** `STATE-WP-0080-T01` now refuses `prj-` scaffolding and
points at `rmgr scaffold`. T03 is done. Cutover / inventory move can start
alongside `STATE-WP-0080-T02`.
**Result (2026-08-18):** Cutover is live via `STATE-WP-0080-T02`: project
flavor delegates to `rmgr scaffold` (or registers only when `GOAL.md`
exists); durable repos keep hub templating until `STATE-WP-0080-T04`
deletes it. Inventory `caller:custodian-cli` is already `move`
`repo-manager`. Coordination remains `SHR-WP-0001`.
## Add compatibility and regression tests
```task
id: RMGR-WP-0004-T06
status: done
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 preserves the agreed durable-file contract from the State Hub
handoff (byte identity is intentionally retired with the old template owner);
- 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.
Result (2026-08-21): regression coverage exercises project and durable layouts,
the two known conformance findings, disagreeing flavor signals, CLI behavior,
and byte-stable no-op reruns. The stale byte-identity requirement was adapted
to contract equivalence because retaining State Hub's private template bytes
would make the retired implementation authoritative.
## 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.
Scope is not limited to workplans. `ADR-007` decision 1 is written for
`PREFIX-WP-NNNN`, but **canon artifacts have identical exposure and no rule at
all**. Demonstrated 2026-08-17: `ADR-008` was allocated concurrently by two
authors — `adr-008-multi-tenancy-model.md` and `adr-008-hub-authority-and-local-cache-model.md`,
both `id: ADR-008`, committed the same day. Resolved by renumbering the latter to
`ADR-010`, but only after the collision existed in the repository.
Cover every sequentially allocated identifier in a repository:
- `ADR-NNN` in `canon/architecture/`;
- versioned standards and canon documents (`*_vN.N.md`);
- any other repo-local running number the standard introduces.
The check is the same shape as for workplans — one allocator per namespace,
forward-only, no reuse — and the same detection applies: two files claiming one
`id:` is a `contradictory` finding, not a `missing` one.
**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: done
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.
### Live-collision remediation (assigned 2026-08-21)
`ADR-007` was amended to derive C2 identifiers for **live records only**, so the
blocking surface is the 11 live files below, not the 48 in the full scan.
`RMGR-WP-0005-T03` is gated on these. Per `ADR-007` decision 4, execution
belongs to a worker in each repository — this task assigns, it does not rename.
Three distinct root causes, not one:
**1. Incomplete T09 prefix migration — 5 files.** `railiance-apps` and
`railiance-platform` still carry live `RAILIANCE-WP-` plans although T09 retired
that prefix and assigned `RAPPS-WP-` and `RPF-WP-`. `railiance-platform` has
already begun using `RPF-WP-` (00180020 exist), so these are stragglers. Fix is
the assigned migration, not a fresh number:
```text
railiance-apps RAILIANCE-WP-0015-cnpg-backup-scheduledbackup-coverage.md -> RAPPS-WP-
RAILIANCE-WP-0016-railiance01-activity-core-backup-automation.md -> RAPPS-WP-
railiance-platform RAILIANCE-WP-0015-platform-rapp-consistency.md -> RPF-WP-
RAILIANCE-WP-0016-apps-pg-resource-evidence.md -> RPF-WP-
RAILIANCE-WP-0016-architecture-cleanup-backlog.md -> RPF-WP-
```
Numbers are reallocated above each repo's current maximum, not preserved —
`railiance-platform` holds two live files at `0016`, so preservation is
impossible for that pair.
**2. `WHYNOT-WP-` prefix never assigned — 4 files.** T09 assigned `CUST-WP-`,
`RAIL-BS-WP-` and `RAILIANCE-WP-`; the 2026-08-21 scan shows **five** shared
prefixes. `WHYNOT-WP-` is shared by `whynot-control` and `whynot-design` with
both `0001` and `0002` colliding.
Note the cause of `WHYNOT-WP-0001`: both files are
`WHYNOT-WP-0001-statehub-bootstrap.md` — the generic bootstrap workplan that
`statehub register` wrote unconditionally. That is the defect `STATE-WP-0080`
contained; these two files are its residue, and the same pattern will exist
wherever else that path ran before the guard landed.
Assign `WHYNOT-WP-` to one repo and a new prefix to the other, then renumber.
**3. Same-repo number reuse — 2 files.** `kontextual-engine` has two live
`KONT-WP-0013` files (`blob-storage-content-streaming`,
`cmis-browser-binding-tck-compatibility`). Straight forward-only renumber of one
to the next free `KONT-WP-` number.
### Also unassigned (not blocking T03)
`OPS-WP-` (`ops-bridge`, `ops-hub`) and `REPO-WP-` (`core-hub`,
`disaster-control`, `repo-seed`) are shared prefixes with no live collisions —
every clash is against an archived file. Assign them before either repo
allocates its next number, or they become live collisions.
Result (2026-08-21): all 11 records named by the live-collision section are now
terminal (`finished` or legacy `completed`). `rmgr identifier preflight --root
/home/worsch` sees 263 live identifiers across 113 repositories with zero
collisions, so T03's gate is cleared without rewriting frozen history. Dormant
future ownership for `WHYNOT-WP`, `OPS-WP`, and `REPO-WP` is handed off as live
residual `RMGR-IN-0002`; it must be resolved before the next allocation under
any of those prefixes.
## Confirm the canon boundary
```task
id: RMGR-WP-0004-T07
status: done
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.
Result (2026-08-21): the seam is explicit in
`docs/repository-standards_v0.1.md`: Custodian canon defines repository
standards and Repo Manager implements conformance and governed mutation. The
canon ADR for this workplan links the enforcement placement; no competing
semantic standard was introduced here.
## Closure
Finished 2026-08-21. Standards modeling, conformance, governed scaffolding,
compatibility coverage, identifier uniqueness, prefix ownership, and the canon
boundary are live. Dormant prefix ownership is preserved as registered residual
`RMGR-IN-0002` rather than keeping this implementation workplan open.