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>
5.9 KiB
| id | type | title | domain | repo | status | owner | topic_slug | created | updated | parent_project | parent_workplan | related | ||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| RMGR-WP-0005 | workplan | Registrar consolidation and deterministic hub identifiers | infotech | repo-manager | proposed | codex | infotech | 2026-08-17 | 2026-08-17 | prj-state-hub-retirement | SHR-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
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
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 theprj-canon-federationrepo 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
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_idkeep 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
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
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
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.