refactor(frame-wire): retire test_frame_wire.py; the Rust fold is normative #8
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/frame-wire-contract-crate"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Retires
test_frame_wire.pyand repoints the prose at the Rust fold, whichbecame normative in #7. Paired with ritual-engine's
frame-wire-contractcrate,which carries the 55 tests this file used to hold.
Scope
test_frame_wire.pywas 1,591 lines, but only ~120 of them (roughly 394-516)were
apply_stream, the fold. The other ~1,470 were 55 test functions.Diffing the two implementations for the first time found the Python wrong in
three places and the Rust right in all three — every one an unclassified
language-level exception escaping a fold whose entire design is classifying
failures as discard or abort:
/→tokens[-1]on[]→IndexError/fields/٠/value) → Python'sstr.isdigit()andint()both accept U+0660, so it silently writes index 0 — a differentpointer than the one addressed
text.text, or a rich_text missingelements→KeyErrorThe file contained a test named
test_no_unclassified_exception_escapes_the_foldthat caught none of them, because it never tried a slash-less pointer, a
malformed block, or a non-ASCII digit.
It had also fallen behind the contract it was supposed to be normative for: #7's
1.3.0 amendments added RFC 6901 leading-zero rejection and the
__proto__/constructor/prototypereceiver rule, and the Python implementedneither.
And no CI job in this repo has ever run it —
.forgejo/workflows/contains onlypr-policy-check.yml. So the three defects had no mechanism that would everhave surfaced them.
Porting deletes the bugs rather than repairing them. This PR:
test_frame_wire.pydocs/frame_wire.md— namesritual_core::frame_wire::apply_streamas thenormative fold, says where the suite now lives and how to run it, and records
the three defects that justified retiring the Python
openapi.yaml— same repointCHANGELOG.md— an[Unreleased] > Removedentry. The two mentions inside thereleased
[1.2.0]section are left alone as historical record.Testing
The 55 tests are not lost — they are ported 1:1 into
frame-wire-contractinritual-engine, with the Python name minus the
test_prefix so the two grepagainst each other, and a 55-row mapping table in the crate's README.
Baseline taken before the delete:
pytest test_frame_wire.py→ 126 items, 126passed (55 functions expanded by
@pytest.mark.parametrize). Every parametrisedcase survives as an in-test loop with the parameter interpolated into the failure
message, so a failure still names the case; no parametrised test collapsed to a
single case. Ported suite: 60 tests, all green, and unlike this file they run in
CI on every push.
The three defects above are now proved absent by construction rather than
asserted:
tests/bugs_absent_by_construction.rsdrives the real fold andrequires a classified discard, not merely the absence of a crash, and each was
mutation-tested — the bug reintroduced into the Rust, the matching test watched
to fail, the file restored.
Deleting this file also clears the
pytestduplicate-basename collision thatwas stopping collection in this repo.
Impact Statement
with no callers, run by no job.
which implementation the documents name as normative; #7 already made that
change in substance.
schemas/*.jsonis byte-identical to2e020e5.docs/frame_wire.mdare now pointedat
ritual_core::frame_wire::apply_streamand at the ritual-engine crate. Areader who wanted a Python reference no longer has one — stated plainly in the
doc rather than left to be discovered.
implementation that was wrong in three ways and behind the contract in two.
The file was 1,591 lines: about 120 of Python reference fold (apply_stream) and about 1,470 of the 55 test functions against it. All 55 are now the frame-wire-contract crate in ritual-engine (crates/frame-wire-contract), run with `cargo test -p frame-wire-contract`. That crate holds no fold of its own — it drives ritual_core::frame_wire::apply_stream, which 1.3.0 already made the normative one — so the contract has exactly one implementation rather than two that could disagree. It vendors this repo's schemas/, openapi.yaml and docs/frame_wire.md verbatim, so both documents and the prose are still checked together. The Python was retired rather than repaired because on three inputs it let an unclassified language-level exception escape a fold whose entire design is classifying failures as discard or abort: 1. a pointer with no leading "/" — IndexError for a single-token pointer, and for a multi-token one (a/fields) a SILENT resolution of the remainder against the block root, writing to a pointer the delta never addressed; 2. a Unicode decimal digit as an array index (/fields/<arabic-indic zero>/value) — str.isdigit() and int() both accept it, so it SILENTLY WROTE INDEX 0; 3. a section with no text.text, or a rich_text_section with no elements — KeyError. Its own test_no_unclassified_exception_escapes_the_fold caught none of the three: the sweep never tried a slash-less pointer, a Unicode digit, or a malformed block. It was also behind the contract — 1.3.0 added RFC 6901 leading-zero rejection and the __proto__/constructor/prototype receiver rule and it implemented neither — and no CI job had ever run it. docs/frame_wire.md and openapi.yaml now point implementers at ritual_core::frame_wire::apply_stream and at the frame-wire-contract crate. The 1.2.0 CHANGELOG entries that describe the file are left as written: they are the record of what shipped then.