Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a053ff-1d6f-7fe2-ac1c-a6eb40a42a0c
111 lines
5.4 KiB
Markdown
111 lines
5.4 KiB
Markdown
---
|
|
id: RMGR-CONTRACT-UUID-0001
|
|
type: contract
|
|
title: "Deterministic work-record UUID derivation"
|
|
version: "1"
|
|
status: active
|
|
created: "2026-08-21"
|
|
updated: "2026-08-21"
|
|
workplan_task: RMGR-WP-0005-T03
|
|
---
|
|
|
|
# Work-record UUID derivation v1
|
|
|
|
For a live workplan or task, implementations derive the existing
|
|
`state_hub_workstream_id` or `state_hub_task_id` field with UUIDv5:
|
|
|
|
```text
|
|
namespace UUID: a4058507-5c4a-5a00-ab06-fffa4fb46009
|
|
name bytes: UTF-8(<fleet-namespace> + "\n" + <canonical-identifier>)
|
|
```
|
|
|
|
The fixed UUID is itself UUIDv5(URL,
|
|
`https://helixforge.org/repo-manager/work-record/v1`), but consumers use the
|
|
fixed value above rather than recomputing it. Fleet namespace names are
|
|
lowercase DNS-label style. Canonical identifiers are `PREFIX-WP-NNNN`,
|
|
`PREFIX-WP-NNNN-TNN`, or the repository-qualified daily forms
|
|
`PREFIX-WP-ADHOC-YYYY-MM-DD[-TNN]`. Historic unqualified `ADHOC-*` records are
|
|
grandfathered and keep their minted identifiers; new records never use that
|
|
collision-prone form.
|
|
|
|
The repository is not a namespace. The fleet owner declared the current shared
|
|
namespace as **`helixforge`** on 2026-08-21; the versioned declaration is
|
|
`config/fleet-namespace.yaml`. This raises the namespace posture from implied
|
|
N1 to declared N2. A future fork uses its own namespace name and therefore
|
|
derives different UUIDs for the same unqualified identifier, as required by
|
|
ADR-011.
|
|
|
|
Only proposed, ready, active, blocked, or backlog workplans and their unfinished
|
|
tasks enter the live derivation set. Finished and archived history retains its
|
|
minted identifiers. Before creating, re-deriving, or unarchiving a record, run
|
|
the live-collision preflight. Any duplicate is a hard refusal; it is never
|
|
silently disambiguated with a repository slug.
|
|
|
|
```bash
|
|
rmgr identifier derive --record-id RMGR-WP-0005
|
|
rmgr identifier preflight --root /path/to/fleet
|
|
rmgr identifier migration-plan --root /path/to/fleet --output uuid-migration.json
|
|
rmgr identifier migration-verify --plan uuid-migration.json
|
|
rmgr identifier migration-verify --plan uuid-migration.json --repo repo-manager
|
|
rmgr identifier migration-batch-plan \
|
|
--plan uuid-migration.json \
|
|
--repo whynot-design \
|
|
--projection-api-base http://127.0.0.1:8000 \
|
|
--projection-api-base http://127.0.0.1:18000 \
|
|
--output batch.json
|
|
rmgr identifier migration-batch-verify \
|
|
--plan uuid-migration.json \
|
|
--batch batch.json
|
|
```
|
|
|
|
`migration-plan` is non-mutating. Its versioned JSON output preserves every
|
|
current-to-derived UUID mapping and marks each repository as one atomic apply
|
|
unit. A collision or malformed live identifier makes that whole repository
|
|
ineligible while leaving unaffected repositories visible in the plan. Existing
|
|
output files are not replaced unless `--force` is explicit.
|
|
|
|
Plans carry a canonical UTC creation time, SHA-256 integrity seal, and per-repo
|
|
Git HEAD/source fingerprints. `migration-verify` rejects a modified plan, a
|
|
namespace mismatch, an ineligible repository, or authoritative-source drift.
|
|
HEAD movement is reported but is not a hard failure when the source fingerprint
|
|
is unchanged; otherwise committing the plan itself would invalidate its own
|
|
repository. `--repo` verifies one atomic apply unit, so unrelated fleet churn
|
|
does not invalidate a stable repository. A new plan is required for each unit
|
|
whose authoritative source drifts.
|
|
|
|
`migration-batch-plan` converts selected atomic units into a bounded approval
|
|
package. Each selected repository must still match the planned Git HEAD, have a
|
|
clean worktree, exactly match its configured upstream, and use a non-retired
|
|
origin. The batch records these facts and its own SHA-256 seal, but always emits
|
|
`apply_authorized: false`. An explicit decision must cite that batch hash before
|
|
any database or file mutation. Repeat `--projection-api-base` for every hub in
|
|
the cutover. Each replacement is classified as `legacy_source`,
|
|
`derived_target`, `duplicate_target`, `both_present`, or `neither_present`. The
|
|
first three may coexist inside one repository-atomic migration: State Hub
|
|
migrates legacy rows, verifies already-derived rows against their canonical
|
|
record identity, and may coalesce a `duplicate_target` task only when both
|
|
business payloads are equal and the legacy row has zero inbound references.
|
|
Other both-present and all neither-present states are refused. Durable aliases
|
|
are recorded for every converged replacement. Saved
|
|
projection endpoints are rechecked by `migration-batch-verify`; omitting the
|
|
option retains the offline source/Git-only planning mode. A projection-aware
|
|
batch containing UUID assignments fails closed until an assignment-specific
|
|
projection identity check is implemented.
|
|
|
|
After approval, apply the sealed database phase and then the atomic file phase:
|
|
|
|
```bash
|
|
rmgr identifier migration-projection --plan PLAN.json --repo REPO \
|
|
--confirm-plan-sha256 SHA256 --api-base http://127.0.0.1:8000
|
|
rmgr identifier migration-files --plan PLAN.json --repo REPO \
|
|
--confirm-plan-sha256 SHA256 --execute
|
|
```
|
|
|
|
If the file phase fails, run `migration-projection` with `--direction reverse`
|
|
before changing the sealed plan or retrying. Routine `rmgr sync` never performs
|
|
this migration implicitly.
|
|
|
|
Activation and applying a bulk migration remain separate governed steps.
|
|
Publishing or planning this function does not retroactively rewrite existing
|
|
identifiers. `--namespace` remains an explicit override for a foreign/forked
|
|
fleet; omitting it uses the checked-in `helixforge` declaration.
|