the-custodian/canon/architecture/adr-007-workplan-identity-and-repo-worker-topology.md
codex 81cdce4173 docs(canon): ADR-007 workplan identity, single registrar, worker topology (proposed)
Globally unique PREFIX-WP-NNNN; one prefix per repo; forward-only running
numbers; prefixes never derived from flavor markers. Exactly one registrar
mints hub IDs into git-tracked files. Automated normalization may not
promote proposed to active. Repo manipulation defaults to a worker agent in
that repo; prj- repos may act across their declared participants.

Fleet scan of 955 workplans found 3 shared prefixes and 5 duplicated
identifiers. Migration of existing collisions deliberately left for a
separate ruling.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-16 18:54:39 +02:00

158 lines
6.9 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: 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