Strengthen A7 to two tiers on approval-engine's proposal

The summary-for-body pattern reached six instances in four repositories
in one week. approval-engine escalated it with a concrete split: the half
that is mechanically checkable and the half that is doctrine.

§11 gains an example-validates-against-schema check, with the clause that
matters most — where a field is optional but load-bearing, examples must
cover both its presence and its absence. That clause is instance six:
approval-engine's own claim examples omitted pdp_digest and contradicted
its schema, found while implementing GH-DEC-2026-008, by the repository
making the argument. An example set that silently omits an optional field
teaches every reader the field does not exist.

§12 gains the convention half, which no test can cover: derivatives
marked with source and derivation version, and dated review records
marked as status-as-of-date rather than current state.

The tally is recorded in full because it is the argument. Four of six
were self-reported and one was committed by the proposer, so the case is
that the publishing shape makes the error the default — not that four
repositories were careless. A control depending on repositories
volunteering corrections is not a control.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WtJBr77gMFLrN93iEevqQJ

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 425128@bnt-lap001
Assistant-Session: f5944d8b-dac4-4e1a-87eb-8b3d8f314a63
This commit is contained in:
tegwick 2026-09-06 14:21:29 +02:00
parent 4d8b0f6775
commit 3b828586fc
2 changed files with 83 additions and 44 deletions

View file

@ -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.
---

View file

@ -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