--- id: ADR-007 type: architecture-decision-record title: "Workplan Identity Uniqueness, Single Registrar, and Repo Worker Topology" status: proposed decided_by: Bernd Worsch date: "2026-08-16" tags: ["architecture", "workplans", "identity", "state-hub", "repo-manager", "agents", "registrar"] --- # ADR-007: Workplan Identity Uniqueness, Single Registrar, and Repo Worker Topology ## Status Proposed. Remediation of existing collisions (§ Migration) needs a separate ruling before execution — it is disruptive and touches six repositories. ## Context On 2026-08-16, `STATE-WP-0080` was found registered **twice, in two different databases**, with two different workplan UUIDs and two disjoint sets of task UUIDs: | Registrar | Workplan UUID | Reachable at `127.0.0.1:8000` | |---|---|---| | Workstation hub (`make api`, local postgres) | `03f38314` | yes | | railiance01 primary, via `custodian-sync@railiance.local` | `bbfce36a` | **404** | Both write their IDs into the same git-tracked workplan file, so each sync overwrites the other's IDs and the file flip-flops on every round trip. The same commit (`ff909e1`, "renormalize lifecycle state [auto]") also promoted the workplan `proposed` → `active` without human review. A fleet scan of 955 hub workplans (525 with parseable `PREFIX-WP-NNNN` identifiers) found this is not an isolated incident. Two distinct identity defects are live: **Prefix reuse across repositories:** ```text CUST-WP- → state-hub, the-custodian RAIL-BS-WP- → railiance-bootstrap, railiance-cluster RAILIANCE-WP- → railiance-apps, railiance-forge, railiance-platform, railiance-telemetry ``` `PRJ-WP-` is a latent fourth: `statehub register` derives it from the `prj-` flavor marker, so every project repository would collide (see `RMGR-WP-0004`). **Running-number reuse:** ```text CUST-WP-0000 the-custodian ×2 CUST-WP-0010 the-custodian ×2 CUST-WP-0045 the-custodian ×2 RAILIANCE-WP-0015 railiance-platform, railiance-apps RAILIANCE-WP-0016 railiance-platform ×2, railiance-apps ``` `RAILIANCE-WP-0015` is actively cited in operational memory as the cnpg-backup gate in `railiance-apps`; a second record of the same name in `railiance-platform` makes that citation ambiguous. The `C-26` consistency check already flags prefix nonconformance *within* a repo against a canonical prefix, but nothing enforces uniqueness *across* repos, and nothing prevents number reuse. ## Decision **1. A workplan identifier is globally unique.** `PREFIX-WP-NNNN` names exactly one workplan across the entire fleet, for all time. - A workplan prefix is owned by exactly one repository. No two repositories may use the same prefix. - A running number is never reused within a prefix, including after a workplan is cancelled, archived, or deleted. Numbers are allocated forward only. - Prefixes are derived from the *project or repository identity*, never from a flavor marker or category (`PRJ-WP-` is invalid by construction). **2. Exactly one registrar writes hub identifiers into repository files.** A single instance is authoritative for registration and ID writeback. Other instances may read, project, and serve; they must not mint workplan or task UUIDs into git-tracked files. The workstation hub is a development read replica, not a registrar. Running `fix-consistency` with writeback from a workstation against a repository whose primary is elsewhere is the mechanism that produced the flip-flop. **3. Lifecycle status is not automatically promoted.** An automated normalization pass may report drift; it may not move a workplan from `proposed` to `active`. `proposed` means awaiting human review, and an automation that promotes it destroys the meaning of the review gate. **4. Repository manipulation is performed by a worker agent in that repository.** This is the default topology. - A worker acting in repo X owns changes to repo X. - Multiple independent top-level workers inside a single repository are an **exception**, requiring an explicit reason, not a routine mode of operation. - Concurrent independent writers are what turned a two-registrar bug into repeated git divergence. **5. Project (`prj-`) repositories may act across their participating repositories.** When work is governed by a project repo, its tasks may direct changes across every repository the project names, through the project's work agent, where that is more efficient than delegating. This is a deliberate, scoped exception to decision 4: the project repo already owns cross-repo sequencing and its `SCOPE.md` names its participants, so its authority is declared rather than ad hoc. It does not license a worker in an arbitrary repository to reach into others. ## Consequences **Positive.** Workplan identifiers become citable without qualification. Hub IDs stop flip-flopping in git. The `proposed` status regains meaning. Cross-repo authority becomes something a repository declares rather than something any session assumes. **Negative.** Existing collisions must be remediated (see below), which is disruptive. Workstation sessions lose the ability to register workplans directly and must route through the registrar or a worker in the owning repo. Prefix allocation needs a fleet-level registry, which is new machinery. **Enforcement.** Prefix ownership, uniqueness, and forward-only numbering are repository standards, so they belong to Repo Manager under decision `747011c6` (`RMGR-WP-0004`), not to a hub. Canon defines the rule; Repo Manager checks it. ## Migration — needs a separate ruling Three prefixes and five identifiers are already colliding. Remediation options, in increasing cost: 1. **Freeze and forward-fix.** Accept existing collisions as historical, enforce uniqueness only for new workplans. Cheapest; leaves `RAILIANCE-WP-0015` permanently ambiguous. 2. **Renumber the live collisions only.** Fix identifiers that are still cited or active; leave `finished`/`archived` duplicates alone. 3. **Full renaming.** Give `railiance-apps`, `railiance-forge`, `railiance-platform`, `railiance-telemetry` distinct prefixes, likewise `railiance-bootstrap`/`railiance-cluster` and `state-hub`'s legacy `CUST-WP-` files. Touches six repositories and every inbound reference. Recommendation: **option 2**, with option 3's prefix split applied only to repos that are still creating new workplans under a shared prefix — a shared prefix that is still growing keeps generating new collisions, while a dormant one does not. All five duplicated identifiers are currently `finished`, so no active work is blocked by deferring this. ## References - Decision `747011c6` — repository standards belong to Repo Manager - ADR-001 — workplans originate as repo files; hub is a read model - `RMGR-WP-0004` — repository standards conformance and governed scaffolding - `STATE-WP-0080` — register scaffolding handoff - Fleet scan 2026-08-16: 955 hub workplans, 525 parseable identifiers, 3 reused prefixes, 5 reused identifiers