epiphany/spec
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
..
vectors One tag vocabulary the compiler owns, and ratify the corpus in the companion 2026-07-09 20:32:35 -04:00
CONTRACT_TEXTPROJ_OPS.md Text Projection: the operation layer, and the tests that can see it fail 2026-07-21 13:43:09 -04:00
PASS11_RATIFICATION_LOG.md P12-I2: wire the ratified MUSCLOID layout-object id derivation 2026-06-27 12:46:19 -04:00
PASS11_WORKLIST.md Pass 11: ratify provisional byte choices into normative spec text 2026-06-21 22:30:06 -04:00
PASS12_BATCH.md Pass 12 G-pass: ratify the full batch (28 rows) — spec tranche 2026-07-07 10:23:30 -04:00
PASS12_RATIFICATION_LOG.md Two-sided inter-staff renegotiation, and the cascade defect it uncovered 2026-07-09 13:32:37 -04:00
PASS12_WORKLIST.md Pass 12 G-pass: ratify the full batch (28 rows) — spec tranche 2026-07-07 10:23:30 -04:00
PASS13_CANDIDATES.md P13-S3: the engraved spelling set is a shared undo key, not the transpose's 2026-07-09 17:29:05 -04:00
PHASE2_F_WEEK0_WORKLIST.md Phase 2: spelling + decomposition pre-passes (Agent H) with F merge gate 2026-06-23 16:33:39 -04:00
PHASE2_QUICKSTART.md Phase 2: spelling + decomposition pre-passes (Agent H) with F merge gate 2026-06-23 16:33:39 -04:00
PLAN_TEXTPROJ_OPS.md Text Projection: the operation layer, and the tests that can see it fail 2026-07-21 13:43:09 -04:00
QUICKSTART.md Pass 11: ratify provisional byte choices into normative spec text 2026-06-21 22:30:06 -04:00
binary_format.pdf Text Projection design gate: the companion the core spec delegates to 2026-07-09 21:13:40 -04:00
binary_format.tex Text Projection design gate: the companion the core spec delegates to 2026-07-09 21:13:40 -04:00
core_spec.pdf Text Projection 0.2.0: the gate was lossy, and the cause was one missing rule 2026-07-09 21:34:36 -04:00
core_spec.tex Text Projection 0.2.0: the gate was lossy, and the cause was one missing rule 2026-07-09 21:34:36 -04:00
operation_catalog.pdf The pitch/spelling undo unit is broader than the transpose, on purpose 2026-07-09 18:15:43 -04:00
operation_catalog.tex The pitch/spelling undo unit is broader than the transpose, on purpose 2026-07-09 18:15:43 -04:00
quality_metric_catalog.pdf Two-sided inter-staff renegotiation, and the cascade defect it uncovered 2026-07-09 13:32:37 -04:00
quality_metric_catalog.tex Two-sided inter-staff renegotiation, and the cascade defect it uncovered 2026-07-09 13:32:37 -04:00
reference_suite.pdf Schema major 1 Phase A: ratify the v1 wire form + migration (spec only) 2026-07-05 18:05:38 -04:00
reference_suite.tex Schema major 1 Phase A: ratify the v1 wire form + migration (spec only) 2026-07-05 18:05:38 -04:00
text_projection.pdf Text Projection 0.7.0: single-version headers, and blob lines are rejected 2026-07-21 15:04:43 -04:00
text_projection.tex Text Projection 0.7.0: single-version headers, and blob lines are rejected 2026-07-21 15:04:43 -04:00