repo-manager/workplans/RMGR-WP-0004-repository-standards-conformance.md
codex c3f4ece7ea fix(workplans): adopt ADR-007 derived identifiers for unregistered records
These workplans exist only in the retired local hub. Their random pre-ADR-007
identifiers are refused by C-06 as stale references, so they cannot be
registered. Deriving from the canonical record id takes no identity from
anything: central does not hold them and the old ids die with the cache.

Records central already holds were deliberately left untouched.

Refs CUST-WP-0068-T06

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 2583210@bnt-lap001
Assistant-Session: f2bff2d5-e9b2-4338-92ca-10282a927006
2026-08-25 20:21:52 +02:00

22 KiB
Raw Permalink Blame History

id type title domain repo status owner topic_slug created updated parent_project parent_workplan related state_hub_workstream_id
RMGR-WP-0004 workplan Repository standards conformance and governed scaffolding infotech repo-manager finished codex infotech 2026-08-16 2026-08-21 prj-state-hub-retirement SHR-WP-0001
STATE-WP-0080
STATE-WP-0079
RMGR-WP-0001
CFED-WP-0001
4d6b9717-7475-5d2d-a0f2-9708d31d4a66

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

id: RMGR-WP-0004-T01
status: done
priority: high
state_hub_task_id: "86e07fae-f76f-5775-ba41-6a11dbe234eb"

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

id: RMGR-WP-0004-T02
status: done
priority: high
state_hub_task_id: "5807215b-9365-5135-9b96-7fa6882b16b4"

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

id: RMGR-WP-0004-T03
status: done
priority: high
state_hub_task_id: "5375e128-b046-5584-bb32-b744c14a10aa"

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

id: RMGR-WP-0004-T04
status: done
priority: medium
state_hub_task_id: "a93bc06a-0d2c-5145-9e3c-633ed4a21886"

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.mdSCOPE.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

id: RMGR-WP-0004-T05
status: done
priority: medium
state_hub_task_id: "72c87313-ddbc-5672-b391-14e1030a3bd7"

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 moverepo-manager. Coordination remains SHR-WP-0001.

Add compatibility and regression tests

id: RMGR-WP-0004-T06
status: done
priority: medium
state_hub_task_id: "4614bdcd-4636-553d-9b43-b9e149c2acc3"

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

id: RMGR-WP-0004-T08
status: done
priority: high
state_hub_task_id: "f79c7ca8-052e-5c8e-9b8e-a124bdeacaaa"

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):

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

id: RMGR-WP-0004-T09
status: done
priority: high
state_hub_task_id: "2dbd470a-8483-5282-8fd5-856fd721c963"

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) growingRAIL-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-platformRPF-WP-, railiance-appsRAPPS-WP-, railiance-forgeRFORGE-WP-, railiance-telemetryRTELE-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):

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:

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-00010009 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:

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

id: RMGR-WP-0004-T07
status: done
priority: low
state_hub_task_id: "c960c191-edc6-53c4-b4c7-ae2d52f8ca4f"

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.