Skip to content

M5 Phase 3: grow the fixture pack to what a boolean decision cannot reach - #61

Merged
kjpatel merged 1 commit into
mainfrom
m5-phase3-fixtures-demo-b2
Aug 6, 2026
Merged

M5 Phase 3: grow the fixture pack to what a boolean decision cannot reach#61
kjpatel merged 1 commit into
mainfrom
m5-phase3-fixtures-demo-b2

Conversation

@kjpatel

@kjpatel kjpatel commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Part 4b(ii)a. I started the four demo suites and stopped at the first one.

Why

test_api splits on a fixture the pack could not supply. Half its tests assert that verdict wording is pack dataphrasing: blocks, placeholders, tones — and fx:permitted is boolean, so it takes the kernel's Yes/No fallback and never reaches that machinery at all.

The entire phrasing path was untestable except through the teaching packs — precisely the dependency this phase exists to sever.

So the pack grew fx:assessedFee: a money decision with a phrasing block and a default/exception pair at differing priorities with an explicit overrides, the shape the IR is built around. The scenario grew a sensitivity: pii fact for the report renderer's redaction path — invented, naming nobody, because a fixture carrying real personal data to test PII handling is the joke that writes itself.

That is part 5's stated prerequisite, delivered early because 4b(ii) hit it first. The blocker was one artifact, not two suites' worth of work — the argument for measuring before estimating, again.

A rebuild, not an edit

pack.version is inside every receipt, so this moved all four receipts, the decision-digest vectors and the corpus aggregate. It found two literals that should always have been derived:

  • the "later pack version" vector hardcoded 2026.2.0, which the bump made the current version — collapsing that equivalence class into the base one;
  • a PROV-O test pinned the pack URN.

Both derive from the receipt now. The equivalence test caught the first, which is the whole reason it checks a relation rather than a table of constants.

Verification

975 passed, 7 skipped
verified 351 cases                    # byte-for-byte
1 pair PROVED-DISJOINT, 0 uncovered   # prove, over the grown pack
git diff -- golden/                   # empty

Also: spec/validate.py green; all fixture facts conform to the fixture ontology; every span re-verified against the rendition and the document hash against the PDF; both builders idempotent (re-run, diff unchanged).

Docs last, as asked

fixtures/README.md gains the phrasing rationale and a rule that growing the pack is a rebuild with a re-pinning checklist. docs/m5-plan.md records why 4b(ii) split and — the useful part — that no remaining conversion is blocked on a missing artifact, which was not true of any earlier part. The changelog carries what the boolean-decision gap taught.

🤖 Generated with Claude Code

…each

Part 4b(ii)a. I started the four demo suites and stopped at the first one,
because test_api splits on a fixture the pack could not supply.

Half its tests assert that verdict wording is *pack data* — phrasing blocks,
placeholders, tones — and fx:permitted is boolean, so it takes the kernel's
Yes/No fallback and never reaches that machinery at all. The whole phrasing
path was untestable except through the teaching packs, which is exactly the
dependency this phase exists to sever.

So the pack grew fx:assessedFee: a money decision with a phrasing block and a
default/exception rule pair at differing priorities with an explicit
overrides, the shape the IR is built around. The scenario grew a fact marked
sensitivity: pii for the report renderer's redaction path — invented, naming
nobody, because a fixture carrying real personal data to test PII handling is
the joke that writes itself.

That is part 5's stated prerequisite, delivered early because part 4b(ii) hit
it first. The blocker was one artifact, not two suites' worth of work, which
is the argument for measuring before estimating.

Growing the pack is a rebuild, not an edit: pack.version is inside every
receipt, so this moved all four receipts, the decision-digest vectors and the
corpus aggregate. It found two literals that should always have been derived.
The "later pack version" vector hardcoded 2026.2.0, which the bump made the
*current* version — collapsing that equivalence class into the base one — and
a PROV-O test pinned the pack URN. Both derive from the receipt now. The
equivalence test caught the first, which is the whole reason it checks a
relation rather than a table of constants.

Verification: 975 passed, 7 skipped; verify 351 byte-for-byte; spec/validate.py
green; all fixture facts conform; every span re-verified against the rendition
and the document hash against the PDF; prove proves the grown pack with no
uncovered decision attribute; both builders idempotent; golden/ untouched.

Docs last, as asked: fixtures/README gains the phrasing rationale and a rule
that growing the pack is a rebuild; the plan records why 4b(ii) split and that
no remaining conversion is blocked on a missing artifact; the changelog carries
what the boolean-decision gap taught.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@kjpatel
kjpatel merged commit c264d9c into main Aug 6, 2026
8 checks passed
@kjpatel
kjpatel deleted the m5-phase3-fixtures-demo-b2 branch August 6, 2026 14:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant