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. the completion/archive date; the frontmatter `id` does not change.
**Ad Hoc Tasks:** small opportunistic fixes discovered during a session use **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 `workplans/ADHOC-YYYY-MM-DD.md`, workplan id
this only for low-risk work completed directly; create a normal workplan for `{WP_PREFIX}-ADHOC-YYYY-MM-DD`, and task ids
anything needing analysis, design, approval, dependencies, or multiple phases. `{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:** **Frontmatter:**

View file

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

View file

@ -7,18 +7,24 @@ kinds:
- kind: workplan - kind: workplan
id_patterns: id_patterns:
- "^[A-Z][A-Z0-9]*(?:-[A-Z][A-Z0-9]*)*-WP-[0-9]{4}$" - "^[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] lifecycle: [proposed, ready, active, blocked, backlog, finished, archived]
legacy_patterns: 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$" - pattern: "^MASON-0001$"
source: ops-mason bootstrap workplan created before WP infix convention source: ops-mason bootstrap workplan created before WP infix convention
grandfathered: true grandfathered: true
- kind: task - kind: task
id_patterns: id_patterns:
- "^[A-Z][A-Z0-9]*(?:-[A-Z][A-Z0-9]*)*-WP-[0-9]{4}-T[0-9]{2,3}$" - "^[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] lifecycle: [wait, todo, progress, done, cancel]
legacy_patterns: 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]$" - pattern: "^[A-Z]+-WP-[0-9]{4}-T[0-9]$"
source: early single-digit task suffixes (pre task-block convention) source: early single-digit task suffixes (pre task-block convention)
grandfathered: true grandfathered: true

View file

@ -58,8 +58,8 @@ attention_cost, …) extend the spine; they never replace it.
| Kind | Id scheme | Meaning | Absorbs / legacy | | 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) | | `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` (workplan) · `ADHOC-YYYY-MM-DD-TNN` | smallest executable unit | `MASON-0001-TNN` (grandfathered); issue-core issues become external projections only | | `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) | | `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) | | `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) | | `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 uniqueness remain separate registry checks and are not weakened by this syntax
correction. correction.
The same compatibility review registered `ADHOC-YYYY-MM-DD` as the workplan The same compatibility review initially registered unqualified
container corresponding to the already canonical `ADHOC-YYYY-MM-DD` containers. A same-day collision between Activity Core and
`ADHOC-YYYY-MM-DD-TNN` task form. This aligns the machine registry with the Net Kingdom then demonstrated that this form violates ADR-007's fleet-namespace
fleet agent convention and existing daily records; it does not permit ad hoc uniqueness rule and cannot be used with deterministic UUID derivation. New
containers to replace dependency-bearing workplans. 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 Risk Nexus findings (`RISK-F-*`) and regulatory records (`RISK-REG-*`) are
registered as variants of `register-entry`, not as parallel work kinds. Their 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 assert classify("1RAPP-OPENBAO-WP-0002", kinds) is None
def test_ad_hoc_daily_container_and_task_ids(self, kinds): 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", kinds) == "workplan"
assert classify("ADHOC-2026-08-23-T01", kinds) == "task" 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.