Graph invariant 10 reported Chapter 3 and Chapter 4 failures under its own
number, through a public API. `InvariantViolation` becomes
`WellFormednessViolation` carrying a two-armed `ViolationKind`: `Invariant` for
a numbered graph invariant, `Requirement` for a normative rule named by its
`req:` label. Invariant 10 keeps only reference resolution.
`check_invariants` stays comprehensive, so every broad caller keeps its rule
coverage; `check_invariant` narrows to the invariant arm and a symmetric
`check_requirement` is added. Both are projections of the aggregate. Four rules
move to their own labels, one of which this rung mints:
`req:time:tempo-segment-shape`, stating the enforced shape/end_tempo
compatibility without resolving P13-S8. `GraphInvariant` did not move: 21
variants, unchanged.
44 suites / 1606 passed / 0 failed / 0 ignored (1586 -> 1606, 43 -> 44)
clippy -D warnings clean; fmt -p epiphany-core -p epiphany-testkit clean
core_spec.pdf rebuilt, undefined references cleared
Gates 1-16 pass; evidence in spec/EVIDENCE_P13S29_EXECUTION.md. All 54 mutations
of §3 observed, none compile-only, none passing. Amendment 1 corrected M1·C6 and
M1·C7 from one observer to two after measurement contradicted the derived cell.
Six execution faults are recorded rather than left in the transcript, none a
contract defect. Three are worth naming here because no tool would have caught
them:
- Pin 10's eleventh row was read as a note, not a test, so
`reversed_aleatoric_bounds_stay_invariant_four` was never written. M11's cell
named it, and the omission surfaced only as a radius mismatch.
- `display_renders_each_arm_exactly` carried a comment stating its pinned
fixture correctly above code that built a different one. Pin 10 had foreclosed
the choice precisely because it moves radii; with the fixture repaired the
test entered M11's cell and left M17·C1's, both as pinned.
- Pin 9's `/// 10.` rider note was the one prose row left unmigrated, naming
three labels where four were required and still filing the multiplexing as
pending. Gate 16 states these outcomes have no machine observer; eight rows
were verified by their own stale phrase, and the ninth was not there.
Gate 10 rejected the ledger append over one character: the artifact read
2026-08-12 where pin 13 pins 2026-08-11. The artifact was corrected to the pin,
and the date question is flagged for the owner as a possible administrative
amendment rather than settled here.
CLAUDE.md's baseline still reads 43 suites / 1586 tests and is not in the touch
table; it follows in a separate reconciliation commit.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Ps1szk2mSfgp4Cz21eVH9x