From 885575802c472e67edcfaab1edac849e64e858fe Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 23 Aug 2026 14:45:26 +0200 Subject: [PATCH] fix(identity): enforce qualified ad-hoc identifiers Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02b22-9638-76d2-bbff-b7ea1770b118 --- config/work-record-types.yaml | 10 ++++++++-- docs/work-record-uuid-derivation_v1.md | 7 +++++-- tests/test_record_identity.py | 6 ++++-- ...P-0005-registrar-consolidation-deterministic-ids.md | 8 ++++++++ 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/config/work-record-types.yaml b/config/work-record-types.yaml index c54c95e..919f124 100644 --- a/config/work-record-types.yaml +++ b/config/work-record-types.yaml @@ -7,16 +7,22 @@ kinds: - kind: workplan id_patterns: - "^[A-Z][A-Z0-9]*(?:-[A-Z][A-Z0-9]*)*-WP-[0-9]{4}$" - - "^ADHOC-[0-9]{4}-[0-9]{2}-[0-9]{2}$" + - "^[A-Z][A-Z0-9]*(?:-[A-Z][A-Z0-9]*)*-WP-ADHOC-[0-9]{4}-[0-9]{2}-[0-9]{2}$" legacy_patterns: + - pattern: "^ADHOC-[0-9]{4}-[0-9]{2}-[0-9]{2}$" + source: daily ad-hoc containers created before repository-qualified ad-hoc ids + grandfathered: true - pattern: "^MASON-0001$" source: ops-mason bootstrap workplan created before WP infix convention grandfathered: true - kind: task id_patterns: - "^[A-Z][A-Z0-9]*(?:-[A-Z][A-Z0-9]*)*-WP-[0-9]{4}-T[0-9]{2,3}$" - - "^ADHOC-[0-9]{4}-[0-9]{2}-[0-9]{2}-T[0-9]{2}$" + - "^[A-Z][A-Z0-9]*(?:-[A-Z][A-Z0-9]*)*-WP-ADHOC-[0-9]{4}-[0-9]{2}-[0-9]{2}-T[0-9]{2}$" legacy_patterns: + - pattern: "^ADHOC-[0-9]{4}-[0-9]{2}-[0-9]{2}-T[0-9]{2}$" + source: daily ad-hoc tasks created before repository-qualified ad-hoc ids + grandfathered: true - pattern: "^[A-Z]+-WP-[0-9]{4}-T[0-9]$" source: early single-digit task suffixes (pre task-block convention) grandfathered: true diff --git a/docs/work-record-uuid-derivation_v1.md b/docs/work-record-uuid-derivation_v1.md index 28dcdca..2ad0ef4 100644 --- a/docs/work-record-uuid-derivation_v1.md +++ b/docs/work-record-uuid-derivation_v1.md @@ -22,8 +22,11 @@ name bytes: UTF-8( + "\n" + ) 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` or `PREFIX-WP-NNNN-TNN`. +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 diff --git a/tests/test_record_identity.py b/tests/test_record_identity.py index 5d6aa66..009d74d 100644 --- a/tests/test_record_identity.py +++ b/tests/test_record_identity.py @@ -49,8 +49,10 @@ def test_grandfathered_mason_identity_is_loaded_from_canon_registry() -> None: def test_current_canon_accepts_repository_and_ad_hoc_workplan_forms() -> None: assert classify_record_id("workplan", "RAPP-OPENBAO-WP-0002") == "canonical" assert classify_record_id("task", "RAPP-OPENBAO-WP-0002-T01") == "canonical" - assert classify_record_id("workplan", "ADHOC-2026-08-23") == "canonical" - assert classify_record_id("task", "ADHOC-2026-08-23-T01") == "canonical" + assert classify_record_id("workplan", "ACTIVITY-WP-ADHOC-2026-08-23") == "canonical" + assert classify_record_id("task", "ACTIVITY-WP-ADHOC-2026-08-23-T01") == "canonical" + assert classify_record_id("workplan", "ADHOC-2026-08-23") == "grandfathered" + assert classify_record_id("task", "ADHOC-2026-08-23-T01") == "grandfathered" assert classify_record_id("workplan", "RAPP--OPENBAO-WP-0002") is None diff --git a/workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md b/workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md index b0a4a84..d2a8c1d 100644 --- a/workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md +++ b/workplans/RMGR-WP-0005-registrar-consolidation-deterministic-ids.md @@ -394,6 +394,14 @@ explicit override for foreign namespaces. The derivation contract, fixed UUID, collision/unarchive guard, and independent reproduction test are all active; bulk replacement remains the separately governed T04 operation. +**Ad-hoc identity correction (2026-08-23):** Activity Core and Net Kingdom both +created the canon-prescribed `ADHOC-2026-08-23` identifier. The repository is +not a namespace, so UUIDv5 correctly collided. Repo Manager's canon copy now +recognizes `{PREFIX}-WP-ADHOC-YYYY-MM-DD[-TNN]` as canonical and retains the +unqualified form only as grandfathered history. The governed Activity Core +retry registered `ACTIVITY-WP-ADHOC-2026-08-23` and its task under correlation +`f272ab73-35fb-44e7-aabd-23b124e3c135`, with no missing identifiers afterward. + ## Migrate the fleet ```task