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