canon: resolve work-record governance packets
This commit is contained in:
parent
3db3570b93
commit
8bda6e28b4
7 changed files with 255 additions and 11 deletions
|
|
@ -61,6 +61,7 @@
|
|||
| workplan | CUST-WP-0060 | finished | — | workplans/CUST-WP-0060-work-record-canonization.md |
|
||||
| workplan | CUST-WP-0061 | finished | — | workplans/CUST-WP-0061-work-record-stage3-intake-promotion-index.md |
|
||||
| workplan | CUST-WP-0062 | proposed | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md |
|
||||
| workplan | CUST-WP-0063 | finished | — | workplans/CUST-WP-0063-inbox-governance-packets.md |
|
||||
| task | ADHOC-2026-05-02-T01 | done | — | workplans/ADHOC-2026-05-02.md |
|
||||
| task | ADHOC-2026-07-02-T01 | done | — | workplans/ADHOC-2026-07-02.md |
|
||||
| task | CUST-WP-0001-T01 | done | — | workplans/CUST-WP-0001-custodian-agent-runtime.md |
|
||||
|
|
@ -399,6 +400,11 @@
|
|||
| task | CUST-WP-0062-T04 | wait | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md |
|
||||
| task | CUST-WP-0062-T05 | wait | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md |
|
||||
| task | CUST-WP-0062-T06 | wait | — | workplans/CUST-WP-0062-sbom-nexus-daily-catchup.md |
|
||||
| task | CUST-WP-0063-T01 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md |
|
||||
| task | CUST-WP-0063-T02 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md |
|
||||
| task | CUST-WP-0063-T03 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md |
|
||||
| task | CUST-WP-0063-T04 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md |
|
||||
| task | CUST-WP-0063-T05 | done | — | workplans/CUST-WP-0063-inbox-governance-packets.md |
|
||||
| intake | CUST-IN-0001 | closed | green | intake-legacy-suggestions-migration.md |
|
||||
| intake | CUST-IN-0002 | closed | green | intake-legacy-suggestions-migration.md |
|
||||
| intake | CUST-IN-0003 | closed | green | intake-legacy-suggestions-migration.md |
|
||||
|
|
@ -409,3 +415,5 @@
|
|||
| intake | CUST-IN-0008 | open | blue | intake-legacy-suggestions-migration.md |
|
||||
| intake | CUST-IN-0009 | open | blue | intake-legacy-suggestions-migration.md |
|
||||
| intake | CUST-IN-0010 | open | green | intake-legacy-suggestions-migration.md |
|
||||
| intake | CUST-IN-0011 | open | red | intakes.md |
|
||||
| intake | CUST-IN-0012 | open | green | intakes.md |
|
||||
|
|
|
|||
|
|
@ -8,6 +8,10 @@ kinds:
|
|||
id_patterns:
|
||||
- "^[A-Z]+-WP-[0-9]{4}$"
|
||||
lifecycle: [proposed, ready, active, blocked, backlog, finished, archived]
|
||||
legacy_patterns:
|
||||
- pattern: "^MASON-0001$"
|
||||
source: ops-mason bootstrap workplan created before WP infix convention
|
||||
grandfathered: true
|
||||
- kind: task
|
||||
id_patterns:
|
||||
- "^[A-Z]+-WP-[0-9]{4}-T[0-9]{2,3}$"
|
||||
|
|
@ -20,6 +24,9 @@ kinds:
|
|||
- pattern: "^[A-Z]+-WP-[0-9]{4}-LEGACY-T[0-9]{2}$"
|
||||
source: archived-workplan legacy task renumbering
|
||||
grandfathered: true
|
||||
- pattern: "^MASON-0001-T[0-9]{2,3}$"
|
||||
source: ops-mason bootstrap tasks created before WP infix convention
|
||||
grandfathered: true
|
||||
- kind: intake
|
||||
id_patterns:
|
||||
- "^[A-Z]+-IN-[0-9]{4}$"
|
||||
|
|
@ -49,6 +56,8 @@ kinds:
|
|||
- kind: register-entry
|
||||
id_patterns:
|
||||
- "^RISK-[0-9]{3}$"
|
||||
- "^RISK-F-[0-9]{4}$"
|
||||
- "^RISK-REG-[0-9]{4}$"
|
||||
- "^TD-[0-9]+$"
|
||||
- "^CAP-[0-9]+$"
|
||||
- "^CCR-[0-9]{4}-[0-9]{4}$"
|
||||
|
|
@ -69,3 +78,6 @@ origin_values_recommended:
|
|||
residual: residual
|
||||
handoff: handoff
|
||||
legacy_suggestion_prefix: "legacy-suggestion:"
|
||||
identity_reconciliation:
|
||||
repeated_same_id_same_uuid: duplicate_source_occurrence
|
||||
repeated_same_id_different_uuid: identity_collision
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ domain: custodian
|
|||
status: active
|
||||
version: "0.1"
|
||||
created: "2026-07-20"
|
||||
updated: "2026-07-22"
|
||||
updated: "2026-08-22"
|
||||
scope: fleet
|
||||
related_workplans:
|
||||
- CUST-WP-0060
|
||||
|
|
@ -58,12 +58,12 @@ attention_cost, …) extend the spine; they never replace it.
|
|||
|
||||
| Kind | Id scheme | Meaning | Absorbs / legacy |
|
||||
| --- | --- | --- | --- |
|
||||
| `workplan` | `{PREFIX}-WP-NNNN` | structured, dependency-bearing body of work | — |
|
||||
| `task` | `{WP-ID}-TNN` (workplan) · `ADHOC-YYYY-MM-DD-TNN` | smallest executable unit | issue-core issues become external projections only |
|
||||
| `workplan` | `{PREFIX}-WP-NNNN` | structured, dependency-bearing body of work | `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 |
|
||||
| `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) |
|
||||
| `register-entry` | existing schemes: `RISK-NNN`, `TD-…`, `CAP-…`, `CCR-YYYY-NNNN`, `ADR-NNN` | risks, technical debt, capability requests, credential change requests, architecture decisions | unchanged semantics, brought under the spine |
|
||||
| `register-entry` | existing schemes: `RISK-NNN`, `RISK-F-NNNN`, `RISK-REG-NNNN`, `TD-…`, `CAP-…`, `CCR-YYYY-NNNN`, `ADR-NNN` | risks/findings, regulatory records, technical debt, capability requests, credential change requests, architecture decisions | unchanged semantics, brought under the spine |
|
||||
|
||||
Rules:
|
||||
|
||||
|
|
@ -77,6 +77,13 @@ Rules:
|
|||
follows the legacy-meter discipline of
|
||||
`workplan-terminology-fleet_v0.1.md`.
|
||||
|
||||
Risk Nexus findings (`RISK-F-*`) and regulatory records (`RISK-REG-*`) are
|
||||
registered as variants of `register-entry`, not as parallel work kinds. Their
|
||||
lifecycles remain owned by the register convention. `RISK-N-*` notes are
|
||||
deliberately not registered: a note has no lifecycle, so it does not meet the
|
||||
core definition of a work record. A note becomes part of the backbone only
|
||||
when an event promotes its substance into a lifecycle-bearing kind.
|
||||
|
||||
## Identity layering
|
||||
|
||||
- **UUIDv7 is primary** for bookkeeping, relations, dependencies, and
|
||||
|
|
@ -87,6 +94,11 @@ Rules:
|
|||
required reading.
|
||||
- The hub writes the UUID back into the source file at first index
|
||||
(pattern: today's `state_hub_*_id` fields).
|
||||
- A repeated source block with the same canonical id **and the same UUID** is
|
||||
one record with duplicate source occurrences. Index it once, retain every
|
||||
source location as diagnostic provenance, and report the duplication for
|
||||
governed cleanup. The repetition must not mint a second record. The same
|
||||
canonical id with different UUIDs is an identity collision and fails closed.
|
||||
|
||||
## Abstract lifecycles (canon-fixed, minimal)
|
||||
|
||||
|
|
|
|||
32
intakes.md
Normal file
32
intakes.md
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
# Custodian intake records
|
||||
|
||||
## CUST-IN-0011 — Provision a monitored external security-report Contact URI
|
||||
|
||||
```yaml
|
||||
id: CUST-IN-0011
|
||||
kind: intake
|
||||
title: "Provision a monitored external security-report Contact URI"
|
||||
status: open
|
||||
lane: red
|
||||
priority: high
|
||||
owner: the-custodian
|
||||
tags: [needs-human, compliance-relevant]
|
||||
origin: residual
|
||||
origin_ref: CUST-WP-0063
|
||||
notes: "The minimal RFC 9116 security.txt route is approved for policy.coulomb.social/.well-known/security.txt, with reports routed privately to risk-nexus and no bounty, response-time, or safe-harbour promise. Completion requires the operator to select and provision a real monitored Contact URI; no address may be invented or published before its receiving path is verified."
|
||||
```
|
||||
|
||||
## CUST-IN-0012 — Repair the malformed legacy inbox message identity
|
||||
|
||||
```yaml
|
||||
id: CUST-IN-0012
|
||||
kind: intake
|
||||
title: "Repair the malformed legacy inbox message identity"
|
||||
status: open
|
||||
lane: green
|
||||
priority: low
|
||||
owner: hub-core
|
||||
origin: residual
|
||||
origin_ref: CUST-WP-0063
|
||||
notes: "State Hub returns unread risk-nexus message id 0b8dd0bf-41d-47da-96ac-40e443c32e47, whose second UUID group has only three characters. PATCH /messages/{id}/read rejects it during UUID path parsing, so the already-handled superseded request cannot be marked read through the supported API. Repair must preserve the message body and chronology, assign or map a valid stable identity, and then apply the read transition without direct ad hoc database mutation from this repo."
|
||||
```
|
||||
|
|
@ -4,7 +4,7 @@
|
|||
Covers:
|
||||
- load_registry / classify — id pattern matching against the live canon
|
||||
registry, incl. grandfathered legacy schemes (AWQ-, DEC-, OH-, task
|
||||
single-digit / -LEGACY- variants)
|
||||
single-digit / -LEGACY- variants, and the exact MASON-0001 bootstrap)
|
||||
- load_validators — jsonschema-backed per-kind checks (intake, decision,
|
||||
engagement): required-field gates on non-terminal records, historical
|
||||
grace on terminal ones
|
||||
|
|
@ -64,6 +64,8 @@ class TestClassify:
|
|||
("DEC-2026-004", "decision"),
|
||||
("OH-2026-003", "engagement"),
|
||||
("CUST-WP-0060-T1", "task"),
|
||||
("MASON-0001", "workplan"),
|
||||
("MASON-0001-T01", "task"),
|
||||
],
|
||||
)
|
||||
def test_grandfathered_legacy_ids(self, kinds, legacy_id, expected_kind):
|
||||
|
|
@ -72,6 +74,11 @@ class TestClassify:
|
|||
def test_unregistered_id_returns_none(self, kinds):
|
||||
assert classify("FOO-QX-001", kinds) is None
|
||||
|
||||
def test_risk_register_species(self, kinds):
|
||||
assert classify("RISK-F-0008", kinds) == "register-entry"
|
||||
assert classify("RISK-REG-0001", kinds) == "register-entry"
|
||||
assert classify("RISK-N-0003", kinds) is None
|
||||
|
||||
|
||||
class TestValidators:
|
||||
def test_intake_open_without_lane_errors(self, validators):
|
||||
|
|
@ -305,6 +312,37 @@ class TestMainEndToEnd:
|
|||
assert result.returncode == 0, result.stdout
|
||||
assert "2 checked" in result.stdout
|
||||
|
||||
def test_mason_bootstrap_ids_pass_unmodified(self, tmp_path):
|
||||
(tmp_path / "legacy-mason.md").write_text(
|
||||
textwrap.dedent(
|
||||
"""
|
||||
```yaml
|
||||
id: MASON-0001
|
||||
title: "legacy Mason bootstrap"
|
||||
status: finished
|
||||
```
|
||||
```task
|
||||
id: MASON-0001-T01
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
"""
|
||||
),
|
||||
encoding="utf-8",
|
||||
)
|
||||
result = self._run(tmp_path, "--strict")
|
||||
assert result.returncode == 0, result.stdout
|
||||
assert "2 checked" in result.stdout
|
||||
|
||||
def test_task_fence_rejects_non_task_registered_id(self, tmp_path):
|
||||
(tmp_path / "wrong-fence.md").write_text(
|
||||
"```task\nid: CUST-WP-0063\nstatus: active\n```\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
result = self._run(tmp_path)
|
||||
assert result.returncode == 1
|
||||
assert "registered as workplan, not task" in result.stdout
|
||||
|
||||
def test_terminal_record_grace_does_not_mask_structural_errors(self, tmp_path):
|
||||
"""Historical grace waives missing-field ('required') errors on
|
||||
terminal records, but a genuine value violation (bad lane enum)
|
||||
|
|
|
|||
|
|
@ -35,9 +35,8 @@ ID_LIKE_RE = re.compile(r"^[A-Z][A-Z0-9]*(-[A-Z0-9]+)+-?[0-9]*$")
|
|||
SKIP_DIRS = {".git", "node_modules", ".venv", "history", "agents_backup"}
|
||||
TERMINAL = {"closed", "resolved", "done", "cancel", "finished", "archived"}
|
||||
|
||||
# task blocks are validated inline (state-hub owns their full parsing)
|
||||
TASK_ID_RE = re.compile(r"^([A-Z]+-WP-[0-9]{4}-(LEGACY-)?T[0-9]{1,3}"
|
||||
r"|ADHOC-[0-9]{4}-[0-9]{2}-[0-9]{2}-T[0-9]{2})$")
|
||||
# task blocks are validated inline (state-hub owns their full parsing). The
|
||||
# registry is the sole id-pattern authority, including grandfathered schemes.
|
||||
TASK_STATUS = {"wait", "todo", "progress", "done", "cancel",
|
||||
"in_progress", "blocked"} # aliases per migration window
|
||||
|
||||
|
|
@ -163,9 +162,13 @@ def main() -> int:
|
|||
f"species are sidetracks (work-record-types_v0.1)")
|
||||
continue
|
||||
checked += 1
|
||||
if fence == "task" or kind == "task":
|
||||
if not TASK_ID_RE.match(rid):
|
||||
errors.append(f"{rel}: task id '{rid}' malformed")
|
||||
if fence == "task" and kind != "task":
|
||||
errors.append(
|
||||
f"{rel}: task fence id '{rid}' is registered as {kind}, "
|
||||
"not task"
|
||||
)
|
||||
continue
|
||||
if kind == "task":
|
||||
st = block.get("status")
|
||||
if st is not None and st not in TASK_STATUS:
|
||||
errors.append(f"{rel}: {rid}: bad task status '{st}'")
|
||||
|
|
|
|||
139
workplans/CUST-WP-0063-inbox-governance-packets.md
Normal file
139
workplans/CUST-WP-0063-inbox-governance-packets.md
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
---
|
||||
id: CUST-WP-0063
|
||||
type: workplan
|
||||
title: "Resolve legacy identifier and Risk Nexus governance packets"
|
||||
domain: infotech
|
||||
repo: the-custodian
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: custodian
|
||||
created: "2026-08-22"
|
||||
updated: "2026-08-22"
|
||||
origin: handoff
|
||||
origin_ref: "statehub-inbox:08067461-bb95-42e2-b8de-b492fb99f56e"
|
||||
---
|
||||
|
||||
# Resolve legacy identifier and Risk Nexus governance packets
|
||||
|
||||
Resolve the current Custodian inbox requests without renaming historical work
|
||||
records or inventing an external security contact. The packet covers the
|
||||
Ops Mason legacy `MASON-0001` scheme, Risk Nexus register species, the proposed
|
||||
production-transition definition, and the minimal external-report route.
|
||||
|
||||
The operator already ruled that Risk Nexus's lifecycle-bearing register
|
||||
records must join the work-record backbone. The remaining canon judgment is
|
||||
their placement under the existing `register-entry` kind and the exclusion of
|
||||
notes, which deliberately have no lifecycle and therefore do not meet the
|
||||
canon definition of a work record.
|
||||
|
||||
## Triage the coordination packet against current canon
|
||||
|
||||
```task
|
||||
id: CUST-WP-0063-T01
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Read the source residuals and proposals, current canon, validator behavior,
|
||||
relevant Repo Manager ownership decisions, and the source records themselves.
|
||||
Distinguish decisions that can be made from missing real-world inputs.
|
||||
|
||||
## Extend the work-record registry and validator coverage
|
||||
|
||||
```task
|
||||
id: CUST-WP-0063-T02
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Grandfather the exact `MASON-0001` workplan/task scheme. Register Risk Nexus
|
||||
findings and regulatory records as `register-entry` schemes. Keep `RISK-N-*`
|
||||
notes unregistered because they have no lifecycle. Make the validator consume
|
||||
the registry as its sole task-id authority and add regression coverage.
|
||||
|
||||
**Done (2026-08-22):** the machine registry and prose canon carry the exact
|
||||
Mason schemes and the two Risk register species. The validator no longer has a
|
||||
second hard-coded task-id grammar. Thirty-five focused tests pass; this repo is
|
||||
strict-clean at 412 records; the live Ops Mason files classify the legacy ids
|
||||
without a sidetrack warning.
|
||||
|
||||
## Resolve repeated historical source identity
|
||||
|
||||
```task
|
||||
id: CUST-WP-0063-T03
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Record that repeated source blocks carrying the same canonical id and same
|
||||
hub UUID are one record with duplicate source occurrences, not two records.
|
||||
Ask Repo Manager to index the UUID once, preserve both source locations as
|
||||
diagnostic provenance, and reject creation of a second identity.
|
||||
|
||||
**Done (2026-08-22):** canon and machine copy now distinguish a duplicate
|
||||
source occurrence (same id, same UUID) from an identity collision (same id,
|
||||
different UUID). Decision `3c487545-ee40-4049-89fa-34b41747a7eb` records the
|
||||
ruling. Handoffs went to Ops Mason (`8e65a254`) and Repo Manager (`48eff8d3`).
|
||||
The Ops Mason source intake also lacks its required `lane`; that exact local
|
||||
correction was returned to its owner rather than silently changed here.
|
||||
|
||||
## Resolve and route the Risk Nexus policy requests
|
||||
|
||||
```task
|
||||
id: CUST-WP-0063-T04
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
Adopt the proposed production-transition definition and Custodian declaration
|
||||
authority. Approve the minimal RFC 9116 route at Policy Nexus, routed to Risk
|
||||
Nexus, without adding a bounty, response-time promise, or safe-harbour policy.
|
||||
Keep selection and provisioning of a real monitored Contact URI as a live
|
||||
human-needed intake rather than publishing an invented address.
|
||||
|
||||
**Done (2026-08-22):** decisions `051de446-7ae9-4eca-a766-14345655ab35` and
|
||||
`937bf962-9297-40d5-a3e4-356532f179c7` adopt the production-transition
|
||||
definition and approve the bounded RFC 9116 route. Risk Nexus received the
|
||||
consolidated outcome in `477ec6f9`; Policy Nexus received its publication gate
|
||||
in `2d86983b`. The missing real Contact URI remains live as `CUST-IN-0011`.
|
||||
|
||||
## Close coordination and reconcile State Hub
|
||||
|
||||
```task
|
||||
id: CUST-WP-0063-T05
|
||||
status: done
|
||||
priority: medium
|
||||
```
|
||||
|
||||
Record decisions, send outcome messages, mark handled inbox messages read,
|
||||
hand off every residual as a live work record, run repository verification,
|
||||
and run `statehub fix-consistency`.
|
||||
|
||||
Five of six unread source messages were marked read. The sixth has malformed
|
||||
legacy id `0b8dd0bf-41d-47da-96ac-40e443c32e47`; the typed API rejects it
|
||||
before the read transition. That repair is live residual `CUST-IN-0012` rather
|
||||
than an invisible note.
|
||||
|
||||
**Done (2026-08-22):** all handled messages are read where the API permits;
|
||||
the malformed-id repair was routed to Hub Core in `ffc8d656`. The complete
|
||||
repository suite passes (72 tests), strict work-record validation passes with
|
||||
413 records, and `git diff --check` is clean. Final consistency reconciliation
|
||||
regenerates the work-record index; identifier write-back is correctly deferred
|
||||
to the single Repo Manager registrar after commit and push.
|
||||
|
||||
## Closure Review
|
||||
|
||||
The packet is resolved. Canon, machine registry, validator behavior, tests,
|
||||
State Hub decisions, and owner handoffs now agree. No historical identifier or
|
||||
UUID was rewritten.
|
||||
|
||||
Two actionable leftovers are live records before closure:
|
||||
|
||||
- `CUST-IN-0011` — select, provision, and receipt-test the monitored public
|
||||
security Contact URI before Policy Nexus publishes `security.txt`;
|
||||
- `CUST-IN-0012` — repair the malformed legacy message identity so its handled
|
||||
request can transition to read through the supported API.
|
||||
|
||||
Decision ids: `3c487545-ee40-4049-89fa-34b41747a7eb`,
|
||||
`051de446-7ae9-4eca-a766-14345655ab35`, and
|
||||
`937bf962-9297-40d5-a3e4-356532f179c7`.
|
||||
Loading…
Add table
Add a link
Reference in a new issue