repo-manager/workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md
tegwick c9b7cab9c3 docs(workplans): RMGR-WP-0005 registrar consolidation + deterministic IDs
Implements ADR-007 decision 2: interim single-writer, target UUIDv5 derived
from the globally unique PREFIX-WP-NNNN so writeback is idempotent across
instances. T04 migrates the 758 files carrying hub identifiers. T06 covers
lifecycle protection including the C-15 task-status override.

RMGR-WP-0004 gains T08 enforcing ADR-007 identifier uniqueness, which gates
RMGR-WP-0005-T03 — deriving from a non-unique identifier would manufacture
UUID collisions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 10:19:03 +02:00

167 lines
5.9 KiB
Markdown

---
id: RMGR-WP-0005
type: workplan
title: "Registrar consolidation and deterministic hub identifiers"
domain: infotech
repo: repo-manager
status: proposed
owner: codex
topic_slug: infotech
created: "2026-08-17"
updated: "2026-08-17"
parent_project: prj-state-hub-retirement
parent_workplan: SHR-WP-0001
related:
- RMGR-WP-0004
- STATE-WP-0080
- STATE-WP-0068
- CFED-WP-0001
---
# Registrar consolidation and deterministic hub identifiers
## Goal
Make hub identifiers stored in repository files **derivable rather than
database-local**, so that any number of hub instances can reconcile the same
repository without overwriting each other.
Implements `ADR-007` decision 2: interim single-writer (A), target deterministic
derivation (C2).
## The defect
`state_hub_workstream_id` and `state_hub_task_id` are database-local primary
keys stored in a shared git artifact. Two hub instances over two databases each
mint their own value for the same workplan, and every sync overwrites the other.
Observed 2026-08-16 on `STATE-WP-0080`: workplan UUID `03f38314` from the
workstation hub, `bbfce36a` from a second instance (404 against the workstation
database), plus two disjoint sets of task UUIDs. Sync commits appear under both
`+0000` and `+0200` timezones, confirming two machines write to one repository.
It also inverts `ADR-001`. Files are meant to originate work with the hub as read
model; a file carrying a hub's private key is the file holding hub state.
**Scope: 758 workplan files** across the fleet currently carry these fields.
## Apply the interim single-writer rule
```task
id: RMGR-WP-0005-T01
status: todo
priority: high
```
Until derivation ships, exactly one instance may write hub identifiers into
repository files. The interim registrar is the automated production instance;
workstation hubs are development read replicas.
- Make the writeback path refuse to mint identifiers when the instance is not
the registrar, rather than relying on operator discipline.
- Provide the configuration that designates the registrar, and make a
non-registrar instance's read/project behaviour unchanged.
- Document the accepted cost: registration requires connectivity to the
registrar, so disconnected work cannot register until T03 lands.
Interim, and deliberately so — it trades availability for correctness, and T03
removes the need for the trade.
## Re-register identifiers minted outside the registrar
```task
id: RMGR-WP-0005-T02
status: wait
priority: medium
```
Records minted by non-registrar instances before T01 need reconciliation. Known
cases, all created 2026-08-16/17 from the workstation hub:
- `RMGR-WP-0004` (`b8b3f1e0`) and its seven tasks;
- `CFED-WP-0001` (`7a96da54`) and its thirteen tasks, plus the
`prj-canon-federation` repo record (`3809b0ff`);
- `STATE-WP-0080` — already reconciled by hand to the second instance's IDs
(`bbfce36a`), retained here as the worked example.
Prefer waiting for T03 where possible: once identifiers are derived, these
converge without manual intervention. Re-register by hand only what blocks work
before then.
## Derive identifiers deterministically
```task
id: RMGR-WP-0005-T03
status: wait
priority: high
```
Replace minted UUIDs with UUIDv5 derived from the globally unique
`PREFIX-WP-NNNN` identifier (and `PREFIX-WP-NNNN-TNN` for tasks).
- Fix the namespace UUID and derivation input as a published contract — the
value must be reproducible by any implementation, not just this one.
- Field shape is unchanged, so consumers reading `state_hub_workstream_id`
keep working; only the provenance of the value changes.
- Writeback becomes idempotent: two instances write identical bytes, so the
flip-flop cannot recur regardless of how many hubs run.
**Blocked on `RMGR-WP-0004-T08`.** Deriving from a non-unique identifier
manufactures collisions: two repositories sharing `PRJ-WP-` would compute the
same UUID for different workplans. Uniqueness must be enforced first.
## Migrate the fleet
```task
id: RMGR-WP-0005-T04
status: wait
priority: high
```
One-time pass over the 758 files carrying hub identifiers: compute the derived
value, update the database to match, and write the file.
- Must be all-or-nothing per repository — a half-migrated repo has some derived
and some minted identifiers and reconciles unpredictably.
- Records whose current identifier is already referenced externally (dashboards,
saved queries, progress events) need a mapping table from old to derived, kept
as provenance rather than discarded.
- Repositories with unresolved identifier collisions cannot migrate until
`ADR-007` § Migration is ruled on; skip and report them rather than guessing.
## Retire the interim rule
```task
id: RMGR-WP-0005-T05
status: wait
priority: low
```
Once derivation is live fleet-wide, remove the single-writer restriction from
T01. Multiple hub instances become an availability choice rather than a
correctness constraint, and disconnected registration works again.
Confirm before removal: two instances reconciling the same repository produce
byte-identical writeback, and neither creates a duplicate record.
## Protect lifecycle status from automation
```task
id: RMGR-WP-0005-T06
status: wait
priority: medium
```
Implement `ADR-007` decision 3: an automated normalization pass may report
lifecycle drift but may not promote a workplan from `proposed` to `active`.
`proposed` means awaiting human review; automated promotion destroys the gate.
Observed: commit `ff909e1` ("renormalize lifecycle state [auto]") promoted
`STATE-WP-0080` to `active` hours after it was drafted for review.
Extend the same protection to task status, where the symptom is currently
sharper: `C-15` forces `CFED-WP-0001-T02` back to `wait` on every sync
regardless of file content — reproduced three times, via file edit and via
`update_task_status`, with the task never holding `todo`. Establish which
direction wins for task status and make it consistent with `ADR-001`, where the
file originates work.