fix(canon): qualify daily ad-hoc identifiers
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Python Tests / pytest (push) Successful in 20s

This commit is contained in:
codex 2026-08-23 14:45:26 +02:00
parent 0829edc8b4
commit d113b5c0f1
6 changed files with 108 additions and 14 deletions

View file

@ -180,9 +180,13 @@ read/cache/index layer that rebuilds from files.
the completion/archive date; the frontmatter `id` does not change.
**Ad Hoc Tasks:** small opportunistic fixes discovered during a session use
`workplans/ADHOC-YYYY-MM-DD.md` with task ids `ADHOC-YYYY-MM-DD-T01`, etc. Use
this only for low-risk work completed directly; create a normal workplan for
anything needing analysis, design, approval, dependencies, or multiple phases.
`workplans/ADHOC-YYYY-MM-DD.md`, workplan id
`{WP_PREFIX}-ADHOC-YYYY-MM-DD`, and task ids
`{WP_PREFIX}-ADHOC-YYYY-MM-DD-T01`, etc. Here `{WP_PREFIX}` includes the final
`-WP` token (for example `CUST-WP`). Use this only for low-risk work completed
directly; create a normal workplan for anything needing analysis, design,
approval, dependencies, or multiple phases. Unqualified historic `ADHOC-*` ids
are grandfathered and must not be copied into new records.
**Frontmatter:**

View file

@ -229,8 +229,9 @@ coordination narrative remain queryable.
- Session start order for agents: `GOAL.md``SCOPE.md` → genesis/history →
active workplans (see project `AGENTS.md`).
- Progress and task status follow ordinary State Hub / fix-consistency rules.
- Ad-hoc low-risk fixes may use `workplans/ADHOC-YYYY-MM-DD.md`; anything
multi-step belongs in a normal workplan.
- Ad-hoc low-risk fixes may use `workplans/ADHOC-YYYY-MM-DD.md` with canonical
id `{PREFIX}-WP-ADHOC-YYYY-MM-DD`; anything multi-step belongs in a normal
workplan.
## Minimal layout example

View file

@ -7,18 +7,24 @@ 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}$"
lifecycle: [proposed, ready, active, blocked, backlog, finished, archived]
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}$"
lifecycle: [wait, todo, progress, done, cancel]
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

View file

@ -58,8 +58,8 @@ attention_cost, …) extend the spine; they never replace it.
| Kind | Id scheme | Meaning | Absorbs / legacy |
| --- | --- | --- | --- |
| `workplan` | `{PREFIX}-WP-NNNN` · `ADHOC-YYYY-MM-DD` | structured, dependency-bearing body of work; daily container for small same-day tasks | `MASON-0001` (single bootstrap record, grandfathered) |
| `task` | `{WP-ID}-TNN` (workplan) · `ADHOC-YYYY-MM-DD-TNN` | smallest executable unit | `MASON-0001-TNN` (grandfathered); issue-core issues become external projections only |
| `workplan` | `{PREFIX}-WP-NNNN` · `{PREFIX}-WP-ADHOC-YYYY-MM-DD` | structured, dependency-bearing body of work; repository-qualified daily container for small same-day tasks | unqualified `ADHOC-YYYY-MM-DD`; `MASON-0001` (grandfathered) |
| `task` | `{WP-ID}-TNN` | smallest executable unit | unqualified `ADHOC-YYYY-MM-DD-TNN`; `MASON-0001-TNN` (grandfathered); issue-core issues become external projections only |
| `intake` | `{PREFIX}-IN-NNNN` | spark: idea, finding, directive, request | hub suggestions (legacy, read-only close-out); `AWQ-NNN` (grandfathered) |
| `decision` | `{PREFIX}-DEC-YYYY-NNN` | approval package + resolution | `DEC-YYYY-NNN` (binky, grandfathered as-is) |
| `engagement` | `{PREFIX}-ENG-YYYY-NNN` | scheduled external interaction (counterparty, prepared material, time window) | `OH-YYYY-NNN` (grandfathered) |
@ -89,11 +89,14 @@ now matches ADR-007's repository-derived prefix model; prefix ownership and
uniqueness remain separate registry checks and are not weakened by this syntax
correction.
The same compatibility review registered `ADHOC-YYYY-MM-DD` as the workplan
container corresponding to the already canonical
`ADHOC-YYYY-MM-DD-TNN` task form. This aligns the machine registry with the
fleet agent convention and existing daily records; it does not permit ad hoc
containers to replace dependency-bearing workplans.
The same compatibility review initially registered unqualified
`ADHOC-YYYY-MM-DD` containers. A same-day collision between Activity Core and
Net Kingdom then demonstrated that this form violates ADR-007's fleet-namespace
uniqueness rule and cannot be used with deterministic UUID derivation. New
daily records therefore use `{PREFIX}-WP-ADHOC-YYYY-MM-DD`; the filename remains
`workplans/ADHOC-YYYY-MM-DD.md`. Existing unqualified ids are grandfathered and
are never silently re-derived or disambiguated. Ad-hoc containers remain only
for low-risk work completed directly.
Risk Nexus findings (`RISK-F-*`) and regulatory records (`RISK-REG-*`) are
registered as variants of `register-entry`, not as parallel work kinds. Their

View file

@ -60,6 +60,11 @@ class TestClassify:
assert classify("1RAPP-OPENBAO-WP-0002", kinds) is None
def test_ad_hoc_daily_container_and_task_ids(self, kinds):
assert classify("ACTIVITY-WP-ADHOC-2026-08-23", kinds) == "workplan"
assert classify("ACTIVITY-WP-ADHOC-2026-08-23-T01", kinds) == "task"
assert classify("RAPP-OPENBAO-WP-ADHOC-2026-08-23", kinds) == "workplan"
def test_unqualified_ad_hoc_ids_are_grandfathered(self, kinds):
assert classify("ADHOC-2026-08-23", kinds) == "workplan"
assert classify("ADHOC-2026-08-23-T01", kinds) == "task"

View file

@ -0,0 +1,75 @@
---
id: CUST-WP-0066
type: workplan
title: "Repository-qualified ad-hoc work-record identifiers"
domain: infotech
repo: the-custodian
status: finished
owner: codex
topic_slug: custodian
created: "2026-08-23"
updated: "2026-08-23"
related:
- CUST-ADR-007
- CUST-ADR-011
- RMGR-WP-0005
---
# Repository-qualified ad-hoc work-record identifiers
Two repositories created the canon-prescribed `ADHOC-2026-08-23` workplan and
task identifiers on the same day. Deterministic UUID derivation correctly
refused the second registration because ADR-007 requires identifiers to be
unique within the fleet namespace. Repair the naming convention rather than
weakening collision protection or treating repositories as namespaces.
## Correct the canonical identifier scheme
```task
id: CUST-WP-0066-T01
status: done
priority: high
```
Make `{PREFIX}-WP-ADHOC-YYYY-MM-DD` and its task suffixes canonical. Retain the
unqualified historic form as grandfathered compatibility only.
Completed in the machine-readable registry, prose standard, project-repository
standard, repository instructions, and regression tests. This preserves
ADR-007/ADR-011 namespace semantics and does not reinterpret repositories as
namespaces.
## Synchronize enforcement and authoring guidance
```task
id: CUST-WP-0066-T02
status: done
priority: high
```
Update Repo Manager's canon copy and State Hub's repository instruction
templates and validators so newly authored records use the collision-free form.
Repo Manager now classifies qualified daily ids as canonical and unqualified
ones as grandfathered. State Hub's two instruction templates and legacy ADR
validator use the same scheme; the validator explicitly permits the unchanged
`ADHOC-YYYY-MM-DD.md` filename.
## Repair and register the colliding Activity Core record
```task
id: CUST-WP-0066-T03
status: done
priority: high
```
Rename the not-yet-registered Activity Core record, reconcile it through the
governed registrar, and preserve the successful ACTIVITY-WP-0035 and
ACTIVITY-WP-0036 identifier writebacks from the partial attempt.
The partial writeback was verified against the central projection and pushed as
Activity Core revision `4d7623a`. The renamed daily record then registered as
workplan `32d157b1-94b2-5d29-9b41-d3d9130cbb32` and task
`330907a0-2899-5cbf-a056-4835c2f6faf8`; the registrar returned `applied` with
correlation `f272ab73-35fb-44e7-aabd-23b124e3c135` and pushed revision
`13aea81`. No actionable residual remains.