diff --git a/docs/amendments/v0.8-amendment-set.md b/docs/amendments/v0.8-amendment-set.md index 686c8be..adbe38e 100644 --- a/docs/amendments/v0.8-amendment-set.md +++ b/docs/amendments/v0.8-amendment-set.md @@ -29,7 +29,7 @@ Assembly and circulation are `GH-WP-0003-T06`. | A4 | §9.5 | `GH-DEC-2026-007` | T04 | | A5 | §6.4, §8 | `GH-DEC-2026-005`, `GH-DEC-2026-008` | T05 | | A6 | §17 | `GH-DEC-2026-004` | T07 | -| A7 | §11, §12 | four observed instances; proposed by `approval-engine` | T08 | +| A7 | §11, §12 | six observed instances; proposed by `approval-engine` | T08 | | A8 | §6.4, §13.1 | `GH-DEC-2026-009` | T09 | --- @@ -285,58 +285,90 @@ statute is told the estate has not decided something it has. --- -## A7 — §11 and §12, derived summaries must be marked (T08) +## A7 — §11 and §12, derived artifacts (T08) -**Why.** Four instances in one week, in four repositories, each caught only by another -repository reading the authoritative body: +**Why.** Six instances in one week, in four repositories, each caught only because +another repository read the authoritative body: -- gate-house sourced a revisit trigger in `GH-DEC-2026-005` from a 2026-08-29 - alignment record rather than from `flex-auth`'s current schema; -- gate-house read a change log for what §3.4 contained, which is the defect - `kings-guard` raised against v0.6 and the reason - `docs/conformance/2026-09-06-v06-findings-audit.md` checked the body instead; -- `access-engine` published a dual-control rule written against its own assumption of - the approval claim rather than `approval-engine`'s published schema — it required a - status field and an approver list that do not exist, and every live destroy would - have denied regardless of the approval (failed closed, fixed in `68ad039`); -- `secrets-engine` read a fixture for its contract's prose, and separately carried two - workplans asserting that remaining authorization work was external, which kept an - unimplemented local stub invisible. +1. `secrets-engine` built a validator against a `flex-auth` fixture rather than its + prose, producing the `authority == "state-hub"` constant that + `GH-DEC-2026-005` struck — it would have failed closed against every correctly + issued claim. +2. `approval-engine` sourced a revisit trigger from a 2026-08-29 alignment table + rather than the current schema, and Gate House recorded the spent G3 trigger + verbatim. +3. Gate House read a change log for what §3.4 contained — the defect `kings-guard` + raised against v0.6, and the reason + `docs/conformance/2026-09-06-v06-findings-audit.md` checked the body instead. +4. `access-engine` published a dual-control rule written against an assumed claim + shape rather than `schemas/approval_claim.schema.json`: it required + `context.approval.status == "approved"` and counted + `context.approval.approvals[].subject_id`, neither of which exists. Every live + destroy would have denied `dual_control_required`. +5. The inner decision in that same fixture declared `flex-auth.decision-record.v1` + while omitting three provenance fields published since 2026-09-02. +6. `approval-engine`'s own published claim examples omitted `pdp_digest` and + contradicted its own schema — found while implementing `GH-DEC-2026-008`, by the + repository that had been making this point. -Different artifact classes — change log, alignment record, fixture, workplan summary — -one shape. As `approval-engine` put it, at four instances this is not coincidence but -**a property of how this estate publishes**: authoritative bodies with derived -summaries and examples alongside them, and no staleness marker on the derivatives. A -reader cannot tell from the artifact whether it is current, so the diligent and the -careless read it the same way. +**The shape is identical every time**: an authoritative body with a derived artifact +beside it — summary table, example fixture, change log, review record — where the +derivative carries no staleness marker and no mechanical tie to the body. Implementers +read the derivative because it is shorter and concrete. -Three of the four were reported by the repository that had made the error, against its -own interest. That is the loop working, and it is also the argument for a check: a -control that depends on four repositories volunteering corrections is not a control. +**Nobody in this list was careless.** Four of the six were reported by the repository +that made the error. Instance 4 was a good-faith rule written against a good-faith +model of another engine's schema; instance 6 was committed by the repository arguing +for the check. The publishing shape makes the error the default, which is what makes +it a conformance item rather than five more corrections. A control that depends on +repositories volunteering corrections is not a control. + +### The mechanical half — §11 + +Where the body is a schema and the derivative is an example, this is checkable and +nearly free. `approval-engine` reports fifteen lines +(`approval-engine/tests/test_examples.py`) validating every published example against +its published schema, and asserting that examples cover **both** shapes of an +optional-but-significant field rather than letting one be inferred from the other. It +would have caught instances 1, 5 and 6 outright, and 4 had the policy package's +fixtures been checked against the claim schema they consume. **Add to §11's "Mechanically checkable" list:** -> - every derived artifact in an estate repository — change log, review record, -> alignment note, example, fixture, or summary that restates a normative body — is -> marked as derived, names the authoritative artifact it derives from, and carries -> the version or commit it was derived at. +> - every published example, fixture, or sample document in an estate repository +> validates against the schema it exemplifies, and where a field is optional but +> load-bearing, the examples cover both its presence and its absence rather than +> leaving one shape to be inferred from the other. -**Add to §12, as a paragraph of the loop:** +The second clause is the non-obvious one and it is instance 6: an example set that +silently omits an optional field teaches every reader that the field does not exist. -> **A derived summary is not evidence of what the body says.** A repository acting on +### The convention half — §12 + +A test cannot tell a reader that a 2026-08-29 table is no longer current. That half is +doctrine, which is why `approval-engine` raised it here rather than solving it. + +**Add to §12:** + +> **A derived artifact is not evidence of what the body says.** A repository acting on > another repository's contract, schema, or standard MUST read the authoritative -> artifact, not a summary, example, or review record of it. This is not a counsel of -> care: the estate has produced four instances in a single week, in four repositories, -> each caught only because a second repository read the body. Diligence did not -> prevent any of them, and in three the erring repository reported itself. +> artifact. Where a derivative exists — a summary, example, change log, or review +> record — it MUST be marked as derived, name the artifact it derives from, and carry +> the version or commit it was derived at. A **dated review record** MUST carry an +> explicit marker that it states status as of that date and not current state. +> Where a derivative is unmarked, treat it as stale. > -> The obligation on the publishing side is §11's marking rule; this is its consumer -> half. Where a derivative is unmarked, treat it as stale. +> This is not a counsel of care. The estate produced six instances in a single week +> across four repositories; four were self-reported, and one was committed by the +> repository arguing for this rule. Diligence prevented none of them. -**Note on scope.** This is the cheap half. It does not detect a derivative that is -marked and *still* wrong, and it should not claim to — the marking makes staleness -visible, it does not measure it. Naming that limit here so the check is not later read -as stronger than it is, which would be the same defect one layer up. +**Note on scope.** The mechanical half catches example-versus-schema drift. The +convention half makes prose staleness visible but does not detect it: a marked +derivative can still be wrong, and marking does not measure how wrong. Naming that +limit here so the check is not later read as stronger than it is — which would be this +same defect one layer up. + +Proposed by `approval-engine`, which asked to own none of it. --- diff --git a/workplans/GH-WP-0003-statute-v08-amendment-set.md b/workplans/GH-WP-0003-statute-v08-amendment-set.md index 9db922e..8f2c215 100644 --- a/workplans/GH-WP-0003-statute-v08-amendment-set.md +++ b/workplans/GH-WP-0003-statute-v08-amendment-set.md @@ -180,9 +180,16 @@ the observation that at four instances it is a property of how the estate publis rather than four separate lapses: authoritative bodies with derived summaries beside them and no staleness marker on the derivatives. -Drafted as A7 — a §11 marking obligation on the publisher and a §12 paragraph on the -consumer. The limit is stated in the draft: marking makes staleness visible, it does -not detect a marked derivative that is still wrong. +Now six instances in four repositories, and A7 is drafted in two tiers on +`approval-engine`'s proposal: a §11 mechanical check (published examples validate +against the schema they exemplify, and cover both shapes of an optional load-bearing +field) and a §12 convention (derivatives marked with source and derivation version; +dated review records marked as status-as-of-date). Four of the six were self-reported +and one was committed by the repository arguing for the rule, which is the argument +that the publishing shape makes the error the default rather than that four +repositories were careless. The limit is stated in the draft: the mechanical half +catches example drift, the convention half makes prose staleness visible without +detecting it. ```task id: GH-WP-0003-T09