epiphany/crates/epiphany-testkit/tests
Levi Neuwirth 50ad97a31b Text Projection 0.7.0: single-version headers, and blob lines are rejected
Scoping the document layer found that no blob can be canonical. A blob is
canonical iff referenced by a canonical operation or by canonical reduced state
(`req:textproj:canonical-blobs`; core_spec §"Canonical and Non-Canonical Manifest
Roots"), and nothing in epiphany-core or epiphany-ops references a `BlobId` --
there is no mechanism by which one can be reached. So today every real bundle
projects to zero blob lines.

The first instinct was to let a parser accept blob lines anyway, for forward
compatibility. That is wrong twice over. Forward compatibility is owned by header
gating -- a future writer's text carries a future version, which this parser
rejects at line one -- and a blob line accepted today would be staged into a
bundle that the next projection silently drops, losing data *and* falsifying
`project(serialize(parse(T))) == T` for that text.
`req:textproj:reject-unreferenced-blobs` therefore requires rejection, and the
conformance equation holds unconditionally over parse-accepted texts rather than
only over texts in the image of `project`.

`req:textproj:header-version` pins the other half: a parser accepts exactly one
header version, the companion's own. Multi-version acceptance and text
migrate-on-read are deferred in the same posture as op-payload migrate-on-read
rather than improvised.

Auditing the worked example against its own grammar found three defects in it: it
carried a blob line, which is now by construction an example of an *invalid*
document; its byte strings used literal ellipses, which `bytes ::= "#x" hexdigit*`
cannot derive; and its header still claimed 0.3.0. All three fixed, and the
preamble no longer promises elisions it does not contain -- an example that cannot
be parsed teaches the wrong lesson.

The version now appears in six places here. Two were locked; the two dangerous
ones were not, because they are *normative* -- a bump that updated the title and
missed them would leave the companion requiring parsers to accept a version it no
longer is. `requirements_name_only_this_companion_version` scans every requirement
block and holds any version literal to the title, deliberately exempting the
revision history, where old versions are the point.

Twelve grammar-gate tests, all mutation-verified.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-21 15:04:43 -04:00
..
acceptance.rs Agent I Phase 2-3: engrave recognizable notation from Score to SVG 2026-06-26 20:46:33 -04:00
bundle_reopen.rs Push 5 / P5: the missing inverse -- bytes back to an operation envelope 2026-07-09 20:59:43 -04:00
multisystem_click.rs Phase 3 tranche 2: quality conformance companions, real metrics, multi-system click fix 2026-07-03 10:39:05 -04:00
prepass.rs Phase 2: spelling + decomposition pre-passes (Agent H) with F merge gate 2026-06-23 16:33:39 -04:00
reference_suite.rs Phase 3 tranche 2: quality conformance companions, real metrics, multi-system click fix 2026-07-03 10:39:05 -04:00
text_projection_grammar.rs Text Projection 0.7.0: single-version headers, and blob lines are rejected 2026-07-21 15:04:43 -04:00