From 1a7df12b0c6930d20bd5e429f13a1a318b7aca35 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Wed, 29 Jul 2026 10:09:49 -0400 Subject: [PATCH] G2b: unconflate the corpus version domains, unscope t10, and sign the mutations The corpus fixture stamped the manifest at {0,10} because SetTuningContext needs an operation block at {3,10}. Those are separate domains: the document line carries the manifest's aggregate SchemaVersion and projection discards the block's schema by design. With no edit barriers the manifest stays baseline V0, so the fixture was locking an over-stamped manifest into the corpus while appearing to prove the operation epoch - the exact inference text_projection.tex tells readers not to make. The block's stamp is proven where it lives, by the staged-and-reopened roundtrip test. t10 still read only bundle.rs. Correcting ids.rs and adding a prose cross-reference did not make the pair travel together; sharing one guard does. It now iterates both sources. Two incidental discoveries while extending it: include_str! pulls in the test's own text, so both the needle and the assertion message must avoid the phrase they search for - which is why the original split its needles with concat(). Four stale comments: manifest.rs's barrier-tag range 24-33, payload.rs's "ten events"/"thirty-four payloads", and the 30..=33 ranges in generators.rs and layout_stub.rs. Mutation sweep, each run and observed: - t1 kind space 34->35, and tag space 34->35, separately. Both kill t1. - t2/t3 schema_major 3->0: kills t3 and the staged/reopened test ({0,10} vs {3,10}). - t6 predecessor restore dropped: kills t6 (442 vs 441). - t8 kind epoch 10->9 and tag epoch 10->9, separately. Both kill t8; the tag mutation additionally kills s1's tag table, the kind mutation does not, which is why both tables needed the entry. - t10 stale claim reinjected into bundle.rs and into ids.rs, separately. Each kills the guard, naming the offending file. t5 and t7 were signed earlier; t4 by the cap-to-2 run. Gate: 1410 tests, clippy 0, fmt clean, git diff --check clean, 14 textproj vectors, 105 decode vectors. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01QjsEnYhm1gPpf6ii2iFxFV --- crates/epiphany-bundle/src/bundle.rs | 27 ++++++++++++++-------- crates/epiphany-bundle/src/manifest.rs | 2 +- crates/epiphany-ops/src/payload.rs | 2 +- crates/epiphany-testkit/src/generators.rs | 2 +- crates/epiphany-testkit/src/layout_stub.rs | 2 +- crates/epiphany-textproj/src/vectors.rs | 17 +++++++++++--- spec/vectors/textproj_document_vectors.txt | 2 +- 7 files changed, 37 insertions(+), 17 deletions(-) diff --git a/crates/epiphany-bundle/src/bundle.rs b/crates/epiphany-bundle/src/bundle.rs index ae14249..37fe0c6 100644 --- a/crates/epiphany-bundle/src/bundle.rs +++ b/crates/epiphany-bundle/src/bundle.rs @@ -1418,17 +1418,26 @@ mod tests { /// fail. #[test] fn accept_set_doc_no_longer_claims_no_payload_embeds_the_tuning_context() { - let source = include_str!("bundle.rs"); + // BOTH sources, not just this one. The first version of this guard + // read only `bundle.rs`, and an identical falsehood survived in + // `ids.rs`'s `V3` doc comment precisely because a file-scoped grep can + // only ever prove the file it greps. A sibling cross-reference in prose + // does not make the pair travel together; sharing one guard does. let stale_claim: String = ["no operation payload ", "embeds the tuning context"].concat(); let stale_consequence: String = ["no op block is ever ", "born at v3"].concat(); - assert!( - !source.contains(&stale_claim), - "the doc comment above max_supported_major must not assert the falsified claim anymore" - ); - assert!( - !source.contains(&stale_consequence), - "the doc comment above max_supported_major must not assert the falsified consequence anymore" - ); + for (name, source) in [ + ("bundle.rs", include_str!("bundle.rs")), + ("ids.rs", include_str!("ids.rs")), + ] { + assert!( + !source.contains(&stale_claim), + "{name} still asserts the falsified claim about which payloads carry the tuning context" + ); + assert!( + !source.contains(&stale_consequence), + "{name} still asserts the falsified consequence about op blocks and major 3" + ); + } } #[test] diff --git a/crates/epiphany-bundle/src/manifest.rs b/crates/epiphany-bundle/src/manifest.rs index bd14fb9..c89ba0d 100644 --- a/crates/epiphany-bundle/src/manifest.rs +++ b/crates/epiphany-bundle/src/manifest.rs @@ -591,7 +591,7 @@ impl Manifest { /// crate. Not the universally-emitted version (G-minor, /// `spec/PLAN_GMINOR_SCHEMA_MINOR.md` §4, pin 7): a manifest naming an /// edit barrier that prohibits a post-baseline `OperationKindTag` - /// (24–33) must stamp that tag's epoch instead — see + /// (24–34) must stamp that tag's epoch instead — see /// `epiphany_layout_ir::barrier::edit_barriers_introduced_minor` for the /// aggregate derivation, and `Bundle::create_versioned` / /// `Bundle::commit_versioned` for the producer-supplied seam. This diff --git a/crates/epiphany-ops/src/payload.rs b/crates/epiphany-ops/src/payload.rs index d73e75a..85412c9 100644 --- a/crates/epiphany-ops/src/payload.rs +++ b/crates/epiphany-ops/src/payload.rs @@ -2485,7 +2485,7 @@ mod tests { #[test] fn s1_operation_kind_epochs_match_tag_epochs_across_every_generated_kind() { // `OperationKind`'s own epoch table mirrors `OperationKindTag`'s (same - // ten events); rather than hand-build all thirty-four payloads, this + // eleven events); rather than hand-build all thirty-five payloads, this // checks every kind the corpus generator reaches agrees with its own // tag's already pin-1-verified epoch (s1 above) — so a divergence in // either table is caught. diff --git a/crates/epiphany-testkit/src/generators.rs b/crates/epiphany-testkit/src/generators.rs index 3bf90ed..7d46adb 100644 --- a/crates/epiphany-testkit/src/generators.rs +++ b/crates/epiphany-testkit/src/generators.rs @@ -1905,7 +1905,7 @@ mod tests { /// Push-4a debt) and `CreateInstrument` (kind 31, G1 debt) went missing /// from every corpus this generator feeds despite every downstream suite /// staying green. Assert a bounded draw actually reaches every kind - /// appended past the historically-tested range (discriminants 30..=33), + /// appended past the historically-tested range (discriminants 30..=34), /// not just that the function does not panic. #[test] fn operation_payload_emits_every_appended_kind() { diff --git a/crates/epiphany-testkit/src/layout_stub.rs b/crates/epiphany-testkit/src/layout_stub.rs index 96f75a5..a376121 100644 --- a/crates/epiphany-testkit/src/layout_stub.rs +++ b/crates/epiphany-testkit/src/layout_stub.rs @@ -1372,7 +1372,7 @@ mod tests { /// (s10, row 29) `gen_operation_kind_tag`'s draw must cover exactly /// `PAYLOAD_FREE` ∪ `{Registered}` — **not** merely the appended - /// discriminants 30..=33, which would pass even if the `Registered` + /// discriminants 30..=34, which would pass even if the `Registered` /// append (structurally different from every built-in: it is the one /// variant `PAYLOAD_FREE` excludes by design, `payload.rs:469`) were /// deleted from the generator entirely. diff --git a/crates/epiphany-textproj/src/vectors.rs b/crates/epiphany-textproj/src/vectors.rs index 2f4cca0..c10b864 100644 --- a/crates/epiphany-textproj/src/vectors.rs +++ b/crates/epiphany-textproj/src/vectors.rs @@ -267,11 +267,22 @@ fn accept_documents() -> Vec<(&'static str, String)> { ], }; - // Genesis G2b: kind 34 in the committed corpus, carried at minor 10 — - // the epoch a block containing this operation actually requires. + // Genesis G2b: kind 34 in the committed corpus. + // + // The manifest version stays **baseline `V0`**, and that is the point. The + // `document` line carries the *manifest's* aggregate `SchemaVersion` + // (`req:textproj:manifest-schema-carried`), and this document declares no + // edit barriers, so an aware producer leaves it at baseline. The + // *operation block* serialized underneath independently stamps `{3, 10}` — + // a separate version domain that projection discards by design. Stamping + // the manifest at `{0, 10}` here would lock an over-stamped manifest into + // the corpus while appearing to prove the operation epoch, which is + // exactly the inference `text_projection.tex` §changelog forbids. The + // block's own stamp is proven where it lives, by + // `roundtrip::tests::a_set_tuning_context_block_stamps_3_10_and_reopens_read_write`. let tuning_context = TextDocument { document_id: DocumentId([5; 16]), - manifest_schema_version: SchemaVersion::new(0, 10), + manifest_schema_version: SchemaVersion::V0, lineage_id: None, profiles: profiles(false), extensions: Vec::new(), diff --git a/spec/vectors/textproj_document_vectors.txt b/spec/vectors/textproj_document_vectors.txt index 6b7f00e..6fe91a7 100644 --- a/spec/vectors/textproj_document_vectors.txt +++ b/spec/vectors/textproj_document_vectors.txt @@ -23,7 +23,7 @@ # textproj.document textproj.document accept - minimal 28746578742d70726f6a656374696f6e202830203131203029290a28646f63756d656e7420237830313031303130313031303130313031303130313031303130313031303130312028736368656d612030203129290a2870726f66696c652066756c6c20283020312030292028636f6e73747261696e74732036373130383836342028726574656e74696f6e203120282920747275652929290a -textproj.document accept - set_tuning_context 28746578742d70726f6a656374696f6e202830203131203029290a28646f63756d656e7420237830353035303530353035303530353035303530353035303530353035303530352028736368656d61203020313029290a2870726f66696c652066756c6c20283020312030292028636f6e73747261696e74732036373130383836342028726574656e74696f6e203120282920747275652929290a28656e76656c6f70652023783030303030303030303030303030303130303030303030303030303030303037202378303030303030303030303030303030303030303030303030303030303030616220287374616d70203730302030202378303030303030303030303030303030313030303030303030303030303030303729202863617573616c2028292028292920282920287072696d697469766520287365742d74756e696e672d636f6e74657874202874756e696e672d636f6e746578742d73657474696e67732022636d6e2d31322220227465742d31322220287265666572656e63652d70697463682028636d6e2061203020342920237830303030303030303030663037623430292028736d75666c2d76657273696f6e2d726571756972656d656e742028736d75666c2d76657273696f6e2031203430292028736d75666c2d76657273696f6e20312034302929202829292929290a +textproj.document accept - set_tuning_context 28746578742d70726f6a656374696f6e202830203131203029290a28646f63756d656e7420237830353035303530353035303530353035303530353035303530353035303530352028736368656d612030203129290a2870726f66696c652066756c6c20283020312030292028636f6e73747261696e74732036373130383836342028726574656e74696f6e203120282920747275652929290a28656e76656c6f70652023783030303030303030303030303030303130303030303030303030303030303037202378303030303030303030303030303030303030303030303030303030303030616220287374616d70203730302030202378303030303030303030303030303030313030303030303030303030303030303729202863617573616c2028292028292920282920287072696d697469766520287365742d74756e696e672d636f6e74657874202874756e696e672d636f6e746578742d73657474696e67732022636d6e2d31322220227465742d31322220287265666572656e63652d70697463682028636d6e2061203020342920237830303030303030303030663037623430292028736d75666c2d76657273696f6e2d726571756972656d656e742028736d75666c2d76657273696f6e2031203430292028736d75666c2d76657273696f6e20312034302929202829292929290a textproj.document accept - lineage_custom_profile 28746578742d70726f6a656374696f6e202830203131203029290a28646f63756d656e7420237830323032303230323032303230323032303230323032303230323032303230322028736368656d612030203129290a286c696e656167652023783132313231323132313231323132313231323132313231323132313231323132290a2870726f66696c652066756c6c20283020312030292028636f6e73747261696e74732036373130383836342028726574656e74696f6e203120282920747275652929290a2870726f66696c652028637573746f6d20237863636363636363636363636363636363636363636363636363636363636363632920283120322033292028636f6e73747261696e74732036373130383836342028726574656e74696f6e203120282920747275652929290a28656e76656c6f70652023783030303030303030303030303030303130303030303030303030303030303031202378303030303030303030303030303030303030303030303030303030303030616220287374616d70203130302030202378303030303030303030303030303030313030303030303030303030303030303129202863617573616c2028292028292920282920287072696d6974697665202864656c6574652d726567696f6e20237830303030303030303030303030303031303030303030303030303030303030312929290a textproj.document accept - extension_base_two_envelopes 28746578742d70726f6a656374696f6e202830203131203029290a28646f63756d656e7420237830333033303330333033303330333033303330333033303330333033303330332028736368656d612030203829290a2870726f66696c652066756c6c20283020312030292028636f6e73747261696e74732036373130383836342028726574656e74696f6e203120282920747275652929290a28657874656e73696f6e202378303130313031303130313031303130313031303130313031303130313031303120283120302031292066616c73652028286368756e6b20657874656e73696f6e2d646174612028736368656d61203020312920237830312920286368756e6b20657874656e73696f6e2d646174612028736368656d61203020312920237830322929202378303120237830313032290a2863616e6f6e6963616c2d62617365202378303330333033303330333033303330333033303330333033303330333033303320237830313032303320312066756c6c2028736368656d61203020312920237861303033290a28656e76656c6f70652023783030303030303030303030303030303130303030303030303030303030303032202378303030303030303030303030303030303030303030303030303030303030616220287374616d70203230302030202378303030303030303030303030303030313030303030303030303030303030303229202863617573616c2028292028292920282920287072696d6974697665202864656c6574652d726567696f6e20237830303030303030303030303030303031303030303030303030303030303030322929290a28656e76656c6f70652023783030303030303030303030303030303130303030303030303030303030303033202378303030303030303030303030303030303030303030303030303030303030616220287374616d70203330302030202378303030303030303030303030303030313030303030303030303030303030303329202863617573616c2028292028292920282920287072696d6974697665202864656c6574652d726567696f6e20237830303030303030303030303030303031303030303030303030303030303030332929290a textproj.document accept - rich_document 28746578742d70726f6a656374696f6e202830203131203029290a28646f63756d656e7420237830343034303430343034303430343034303430343034303430343034303430342028736368656d612030203129290a286c696e656167652023783134313431343134313431343134313431343134313431343134313431343134290a2870726f66696c652066756c6c20283020312030292028636f6e73747261696e74732036373130383836342028726574656e74696f6e203120282920747275652929290a2870726f66696c652028637573746f6d20237863636363636363636363636363636363636363636363636363636363636363632920283120322033292028636f6e73747261696e74732036373130383836342028726574656e74696f6e203120282920747275652929290a28657874656e73696f6e202378303130313031303130313031303130313031303130313031303130313031303120283120302031292066616c73652028286368756e6b20657874656e73696f6e2d646174612028736368656d61203020312920237830312920286368756e6b20657874656e73696f6e2d646174612028736368656d61203020312920237830322929202378303120237830313032290a28657874656e73696f6e202378303230323032303230323032303230323032303230323032303230323032303220283120302032292066616c73652028286368756e6b20657874656e73696f6e2d646174612028736368656d61203020312920237830332929202378303220237830323033290a2863616e6f6e6963616c2d62617365202378303430343034303430343034303430343034303430343034303430343034303420237830313032303420312066756c6c2028736368656d61203020312920237861303034290a28656e76656c6f70652023783030303030303030303030303030303130303030303030303030303030303034202378303030303030303030303030303030303030303030303030303030303030616220287374616d70203430302030202378303030303030303030303030303030313030303030303030303030303030303429202863617573616c2028292028292920282920287072696d6974697665202864656c6574652d726567696f6e20237830303030303030303030303030303031303030303030303030303030303030342929290a28656e76656c6f70652023783030303030303030303030303030303130303030303030303030303030303035202378303030303030303030303030303030303030303030303030303030303030616220287374616d70203530302030202378303030303030303030303030303030313030303030303030303030303030303529202863617573616c2028292028292920282920287072696d6974697665202864656c6574652d726567696f6e20237830303030303030303030303030303031303030303030303030303030303030352929290a28656e76656c6f70652023783030303030303030303030303030303130303030303030303030303030303036202378303030303030303030303030303030303030303030303030303030303030616220287374616d70203630302030202378303030303030303030303030303030313030303030303030303030303030303629202863617573616c2028292028292920282920287072696d6974697665202864656c6574652d726567696f6e20237830303030303030303030303030303031303030303030303030303030303030362929290a