epiphany/crates
Levi Neuwirth ee18b71aca Text Projection 0.2.0: the gate was lossy, and the cause was one missing rule
A review found the 0.1.0 companion lossy for documents that are valid today. Its
claim to preserve the manifest's canonical roots was false three ways:

  A canonical blob had no representation at all. blob_roots referenced by
  canonical operations or reduced state ARE canonical roots, and the document
  structure had no blob line. An embedded image, font or recording would vanish
  from a projection silently -- the operations referencing it still there,
  pointing at a blob id the text no longer contained.

  An ExtensionDeclaration lost its semantic version and its affected_object_kinds
  outright, and left its preserved_chunk_roots undefined.

  ProfileId::Custom(ProfileRegistryId) was unrepresentable: a symbol was required
  where sixteen registry bytes are carried.

All three share one cause I had not named. A ChunkRef and a BlobRef are PHYSICAL
references -- offset, compressed length, compression -- which the projection may
not preserve; and they carry DERIVABLE identities -- ChunkId, ContentHash, BlobId
-- which it may not duplicate. Having no rule for either, I dropped the
references and took their contents with them.

req:textproj:derive-or-carry states it, and it is the same rule
req:textproj:reduced-state-derived already applied one level up: carry exactly
what the document does not determine, and nothing it does. Physical attributes
never appear; derivable identities never appear; content and semantic attributes
always do. The one non-derivable identity in schema major 0 is SnapshotId, which
the Binary Format companion pins as opaque and forbids readers to derive -- an
exception for a stated reason rather than an oversight. The grammar now visibly
contains no offset, no length, no compression, no chunk id, no hash, no blob id.

So: req:textproj:canonical-blobs (canonical blobs projected, non-canonical ones
not), req:textproj:profile-id ((custom #x...)), req:textproj:extension-declaration
(every field; chunks as kind + schema + payload, never as a ChunkRef -- the
projection has no file to point into), and req:textproj:base-snapshot-inline
extended to say what the inlined payload IS and that the root ChunkRef and the
SnapshotRef hash are re-derived from hash(Snapshot, schema, payload), never read.

The gap started upstream. core_spec's own list of what the projection preserves
omitted canonical blobs while classifying blob_roots as canonical roots -- an
inconsistency inside one document. Corrected there, along with withdrawing the
permission to reference a base snapshot "externally", which the inline
ratification had already made untenable.

Also: the generated PDF metadata and page header still said Operation Catalog,
inherited from the copied preamble.

The four 0.1.0 ratifications stand unchanged. Implementation stays deferred: a
gate that is lossy is not a gate.

Gate: clippy 0, 31 targets / 1031 passed / 0 failed, conformance 8/8, zero golden
churn; core_spec, binary_format, operation_catalog and text_projection all build
with no undefined references.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-09 21:34:36 -04:00
..
epiphany-bundle Text Projection 0.2.0: the gate was lossy, and the cause was one missing rule 2026-07-09 21:34:36 -04:00
epiphany-core P13-S3: the engraved spelling set is a shared undo key, not the transpose's 2026-07-09 17:29:05 -04:00
epiphany-determinism P12-I2: wire the ratified MUSCLOID layout-object id derivation 2026-06-27 12:46:19 -04:00
epiphany-editor-core TransposeInterval becomes undoable; the frozen Transpose stays un-undoable 2026-07-09 16:45:57 -04:00
epiphany-editor-gui TransposeInterval: the faithful transpose, and the frozen one it replaces 2026-07-09 15:46:43 -04:00
epiphany-engrave P13-I2: Staff::default_clef is the fallback, not decoration 2026-07-09 14:47:42 -04:00
epiphany-layout-ir One tag vocabulary the compiler owns, and ratify the corpus in the companion 2026-07-09 20:32:35 -04:00
epiphany-ops Push 5 / P5: the missing inverse -- bytes back to an operation envelope 2026-07-09 20:59:43 -04:00
epiphany-render-svg P13-I3: delete the hand-written notehead anchors; teach the extractor 2026-07-09 14:53:47 -04:00
epiphany-testkit Push 5 / P5: the missing inverse -- bytes back to an operation envelope 2026-07-09 20:59:43 -04:00