Repository navigation
t27o: a fn returning Vec<T> built by push converts in the out-buffer form -- a last out: []T, the result the count, the oracle checks the written prefix (Closes #11073, Closes #11112) - #11109
Merged
Conversation
…form -- a last out: []T, the result the count, the oracle checks the written prefix (Closes #11073) Step 2 of #10546. A fn whose result is Vec<T> (T an integer, float or bool type), made as one local by Vec::new() / Vec::with_capacity(n) / vec![], changed only by push(e) and extend_from_slice(s) and handed back, takes the caller's buffer as a last out: []T and returns how many elements the Rust fn returns. An element past out.len is counted, not written, as the String form counts bytes; with_capacity(n) is a hint, read and dropped. A read of the Vec, any other change, a second Vec, any other result and a call of a fn in this form refuse, each with a reason that names the use (R_VECOUT, R_VECCALL). The oracle records the count and every element of the written prefix in a 256-element buffer and the same count in a zero-length one. Tests first (nine failed on the merge base), a negative control per rule, a direct test for every new fn (coverage 100 %). gen/rust/tools/t27o/rust_convert.rs is t27c gen-rust of the spec. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…16 MiB, a Vec that never stops growing is skipped; a fn with no parameter takes the buffer without a comma; a body that says out for something else is not the form (Closes #11073) Found by the first replay of --check on a real file: crates/trios-phd regex_lite_global (s[i..].find(needle) with the sampled needle "") pushes for ever, and its harness ate the memory of the machine. A Vec result is an input-dependent allocation, so the harness now carries t27o_guard (VEC_GUARD) when some fn is in the Vec out-buffer form: the original runs on a thread with 3 seconds and a counting global allocator that parks the thread at 16 MiB; the sample is skipped like one on which Rust panics, two such samples end the sampling of that fn, and the cost of a skipped sample is a bounded 16 MiB. The same replay found padding_length_distribution_guard uniform_lengths() written as uniform_lengths(, t27o_o0[0 .. 256]) -- the comma was written before the buffer even with no argument (the String form had the same latent defect). And a body that says out for something else (not the Vec local, not a field) would meet the buffer parameter of that name: it is not the form, the old refusal stands. Tests first (each failed before its fix): a zero-parameter call, the guard in the harness and its absence for a String result, has_vecfn, three out-name rows. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ust takes the state by &mut and compiles (Closes #11073) The read-only form of the previous commit made t27c gen-rust type the state as impl AsRef<[usize]>, which moves the &mut [usize] of oracle() (E0382). The generated file is now compiled with rustc (the driver of cmd_t27o's calls) before every commit. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…er -- 350 of 350 tests, vacuous 0 (Closes #11073) t27c seal --save of specs/tools/t27o/rust_convert.t27; --verify MATCHes on rust_convert, rust_std, zig_convert, spice_convert, zig_std, ledger, golden, install and service, so no dependent seal was re-saved. gen/rust/tools/t27o/rust_convert.rs is byte-identical to t27c gen-rust of the spec. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 19, 2026
Closed
Contributor
This was referenced Oct 19, 2026
…ming the list, and one whose binding is pushed to the Vec result takes the Vec's element type (Closes #11112) let classes = [64, 128, 256, 512]; for &c in &classes { lengths.push(c); } converted to an untyped array constant, which t27c reads as a tuple and a for cannot walk: padding_length_distribution_guard.rs went from a vacuous pass to BLOCKED once uniform_lengths started to convert (#11073). The merge base writes the same untyped constant for any fn with that pattern. - let_array: when the element type is unknown and the list is written into or looped over (array_iterated: by name, by reference, .iter()), the fn is refused (R_VECTYPE), the token now the list's name, not its bracket. A list only indexed by number or handed to a call stays what it was. - put_vec_elem has a new rung, array_push_elem: in a fn in the Vec out-buffer form, a list whose loop binding is pushed as it is to the result Vec (loop_pushes) has the Vec's element type -- what is pushed has it. v.push(c * 2) tells nothing and is not guessed. Tests first (four failed on the previous head): the pinned array-local test, the padding shape, the negative controls (by reference, .iter(), by value, c * 2 refused; a suffixed list typed; a list only indexed by number unchanged), and a direct test of the three new fns. The spec t27o writes for the padding file now passes t27c test-report (1 of 1, 10 runtime asserts, vacuous 0) instead of BLOCKED. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Contributor
PR DashboardGenerated at: 2026-10-19 17:38:46 UTC
Summary
Seal Status
|
gHashTag
marked this pull request as ready for review
October 19, 2026 17:50
9 of 12 tasks
gHashTag
pushed a commit
that referenced
this pull request
Oct 19, 2026
…stack, in both orders, and each body literal beside a sample that holds it -- regex_lite_global records a match (Closes #11113) The oracle calls a fn with parameter i taking sample j + i. regex_lite_global(s, needle) of trios-phd was called with ("", "a"), ("a", "abc"), ("abc", "0") ... : the needle was never inside the haystack, so every count the harness recorded was 0, the oracle test asserted only the empty case, and a conversion that returned nothing for every input would have passed it. Its body has no string literal, so the literal samples of #9102 could not help. vectors now counts the direct texts of the fn (text_count, kept in the new PAIRS slot and cleared at the end). With two or more, derived_at gives each text parameter three fixed samples first, a text, a text inside it and the first text again (put_pair_sample: "abcabc", "abc", "abcabc"), so one call has the needle inside the haystack, the next the haystack second, and "abc" occurs twice in "abcabc" (offsets 0 and 3, the second ending at the end). Each string literal of the body then comes alone, wrapped in one space, alone, so the wrapped sample sits next to the literal in both orders. The sampler stays bounded: three fixed 6-byte texts, the DCAP of 64 samples a parameter (a test with thirty literals), and the guard of 3 s and 16 MiB of #11109, which still skips the empty needle. A fn with one text, or a text and a number, is sampled as before (negative control); a number never reads the count of texts. Evidence: the harness of crates/trios-phd/src/main.rs now records count 2 and the offsets 0 and 3 for regex_lite_global (rustc, run), the zero-length buffer answers 2, and t27b test of the converted spec passes 4 of 4 as before. Over the 1,388 files of the five repositories the converted specs are byte for byte the same; 5 oracle harnesses change (compiler.rs, gates.rs, ring-090 lib.rs, trios-phd main.rs, defense_gate lib.rs); the three that t27b judges (ring-090 25 of 25, trios-phd 4 of 4, defense_gate 4 of 4) pass before and after, the two it cannot judge (unsupported construct, @max) stay so. Tests first (the two oracle tests failed on the merge base, the negative control passed), a direct test for each new fn (is_text_kind, text_count, put_pair_sample), derived_at with the count set, the cap of 64 with pairs. Three tests that give the name table exactly one slot got one more: the state vector has one more slot (PAIRS). t27b test 362 of 362, t27c coverage 100 % (420 of 420), seal --save 362 of 362 vacuous 0, --verify MATCH on rust_convert, rust_std, zig_convert, spice_convert, zig_std, ledger, golden, install, service. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
gHashTag
added a commit
that referenced
this pull request
Oct 19, 2026
… match in the oracle of a two-text fn, refused receivers named (#11130) * t27o: a caller of an out-buffer String fn is refused with a reason that names the form -- R_STRCALL, as the Vec form does with R_VECCALL (Closes #11111) A fn whose result is an owned String lowers to the out-buffer form: a last out: []u8, the result the byte count. The Rust source calls it without that argument, so a caller came out as tag(n).len or const t = tag(n); -- a call with the buffer missing, which t27c rejects at best and at worst reads as another meaning of the same arity. The converter must emit valid output or refuse (#10976). deps now treats a fn in the String form (K_STRFN, registered before its body is read) the way it treats one in the Vec form: a free fn is hit by a call, a method by a call after a dot or a path through its owner or Self, and the caller is refused with R_STRCALL, whose reason names the form and whose token is the callee. The buffer is not guessed: a caller that owned one would have to state a length the source never states. A fn outside the form keeps its old reason (uses refused), the split chain, which names the fn it calls on each piece without calling it, still converts. Tests first (two of the three new convert tests failed on the merge base, the third is the negative control and passed): a free fn in either declaration order, a method called as x.m() and S::m(x), a caller of a String fn outside the form, and a direct deps test with K_STRFN names (call, bare name, declaration, method, path, wrong owner, Self). The reason table test has the new row. Evidence: t27b test 357 of 357; t27c coverage 100 % (417 of 417); t27c seal --save 357 of 357, vacuous 0, --verify MATCH on rust_convert, rust_std, zig_convert, spice_convert, zig_std, ledger, golden, install, service. The converter over all 1,388 tracked Rust files of the five repositories changes no output: 13 fns in 9 files are in the String form and none is called in its own file. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * t27o: the oracle of a fn with two texts samples a needle inside a haystack, in both orders, and each body literal beside a sample that holds it -- regex_lite_global records a match (Closes #11113) The oracle calls a fn with parameter i taking sample j + i. regex_lite_global(s, needle) of trios-phd was called with ("", "a"), ("a", "abc"), ("abc", "0") ... : the needle was never inside the haystack, so every count the harness recorded was 0, the oracle test asserted only the empty case, and a conversion that returned nothing for every input would have passed it. Its body has no string literal, so the literal samples of #9102 could not help. vectors now counts the direct texts of the fn (text_count, kept in the new PAIRS slot and cleared at the end). With two or more, derived_at gives each text parameter three fixed samples first, a text, a text inside it and the first text again (put_pair_sample: "abcabc", "abc", "abcabc"), so one call has the needle inside the haystack, the next the haystack second, and "abc" occurs twice in "abcabc" (offsets 0 and 3, the second ending at the end). Each string literal of the body then comes alone, wrapped in one space, alone, so the wrapped sample sits next to the literal in both orders. The sampler stays bounded: three fixed 6-byte texts, the DCAP of 64 samples a parameter (a test with thirty literals), and the guard of 3 s and 16 MiB of #11109, which still skips the empty needle. A fn with one text, or a text and a number, is sampled as before (negative control); a number never reads the count of texts. Evidence: the harness of crates/trios-phd/src/main.rs now records count 2 and the offsets 0 and 3 for regex_lite_global (rustc, run), the zero-length buffer answers 2, and t27b test of the converted spec passes 4 of 4 as before. Over the 1,388 files of the five repositories the converted specs are byte for byte the same; 5 oracle harnesses change (compiler.rs, gates.rs, ring-090 lib.rs, trios-phd main.rs, defense_gate lib.rs); the three that t27b judges (ring-090 25 of 25, trios-phd 4 of 4, defense_gate 4 of 4) pass before and after, the two it cannot judge (unsupported construct, @max) stay so. Tests first (the two oracle tests failed on the merge base, the negative control passed), a direct test for each new fn (is_text_kind, text_count, put_pair_sample), derived_at with the count set, the cap of 64 with pairs. Three tests that give the name table exactly one slot got one more: the state vector has one more slot (PAIRS). t27b test 362 of 362, t27c coverage 100 % (420 of 420), seal --save 362 of 362 vacuous 0, --verify MATCH on rust_convert, rust_std, zig_convert, spice_convert, zig_std, ledger, golden, install, service. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> * t27o: a refusal caused by a refused receiver names the receiver type, not `self` or `Self` -- 649 fns of the sweep can be followed to the type's own reason (Closes #11128) A method of a type the converter refuses (a struct with a heap field, an enum with data, a refused item) is refused with it, and its refusal line said "uses refused `self`" or "uses refused `Self`". Neither is the name of any refusal in the file, so a lookup by name found nothing and the sweep, which follows a named callee to its root (#11122), had to leave the cascade as it was: 696 fn of the 4,468 cascades. deps now refuses at the receiver (the `self` of the signature, or the `Self` of a body) with the impl type as the token, the line staying the receiver's: "uses refused `Foo` at line 3", and `Foo` has its own line, "refused struct Foo (line 1): type `String`". Nothing else changes: a static fn of the same impl that names neither the type nor `self` converts, the methods of a type that converts convert, a method that uses a refused method still names that method, and an impl of a type declared nowhere in the file stays "undeclared" (that check comes first). Tests first (the new convert test and the two new asserts of the direct deps test failed on the merge base): `&self`, a `Self` constructor, a method calling another, a refused enum, the free fn that takes the type, and the controls; one pinned line of an older test, `uses refused `Self``, now names the type. Measured on the 1,388 tracked Rust files of the five repositories (19,392 fn): the sweep's root attribution of #11127, replayed on the converted text (its numbers reproduced on the merge base: 4,531 cascade lines, 3,824 attributed, 696 fn and 707 items left, 570 + 86 of them self and Self), leaves 58 fn and 69 items unattributed after this change, none of them a receiver. Fns converted 1,824 before and after; none converted becomes refused, none refused becomes converted; 649 first refusals change their token and nothing else. What is left are names the file's own refusal lines do not carry: the type aliases the generic item refusal prints as "refused type" (47 fn), extern fns and an assert. t27b test 363 of 363, t27c coverage 100 % (420 of 420), seal --save 363 of 363 vacuous 0, --verify MATCH on rust_convert, rust_std, zig_convert, spice_convert, zig_std, ledger, golden, install, service. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude <claude@anthropic.com> Co-authored-by: Claude Sonnet 5.5 <noreply@anthropic.com>
This was referenced Oct 19, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #11073
Closes #11112
Step 2 of #10546 (part of #10522; step 1 is #10648). A fn that returns
Vec<T>and builds it bypush/extend_from_sliceconverts in the out-buffer form, the move #9098 made for an ownedString. The last commit fixes #11112, which this form exposed (see "#11112" below).The rule, and where it lives
specs/tools/t27o/rust_convert.t27(header paragraph "The Vec out-buffer form", the section "the Vec out-buffer form (#11073)",vectors/put_vec_recordfor the oracle).gen/rust/tools/t27o/rust_convert.rsist27c gen-rustof it; no hand-written Rust, nocli/change.A fn whose result is
Vec<T>, T an integer, float or bool type, whose body makes the Vec as one local (Vec::new(),Vec::with_capacity(n),vec![]), changes it only bypush(e)andextend_from_slice(s)and hands it back (return v, the tailv, an empty Vec in an early return), takes a lastout: []Tand returnsusize, the number of elements the Rust fn returns:out.lenis counted and not written (the String form's convention), so the count is the same whatever room the buffer has.with_capacity(n)is a hint: read for what reading it does, then dropped.R_VECOUT): a read of the Vec (len, an index), any other change (insert,pop,sort, an index assignment), a borrow, a rebinding, a second Vec local, a result made another way (a vec! literal, a clone). A Vec that grows without a bound the caller states has no t27 form; the reason says so.R_VECCALL): the caller would own a buffer of no stated length. (The String form leaves its callers to call it without the buffer, see "Found, not fixed".)Measure (the five repositories at the commits of step 1: t27 7496ed2, trios 483dd9ee, trinity 0770abb9, trinity-fpga 20bf4c418, 999-multibots-telegraf 6e5512881; 1,388 tracked
.rsfiles,gen/andtarget/left out; the converter built from the generated Rust, one file per process, 60 s cap)How the 626 fns that return a bare
Vec<T>(360 outside#[cfg(test)]modules; 123 more return anOption/Resultof a Vec) make the result:vec![..]literal as the tailcollect()sort,insert, ..)Of the 91 push / extend fns the element type is an integer, float or bool in 19, a struct or enum of the file in 32, a tuple in 21, a text in 15, other in 4. This form takes the 19 (the oracle can record only scalars).
bootstrap/src/compiler.rs,service.rs,cli/t27b/src/lower.rs,cli/tri/src/fpga.rs,gates.rsleft out, as in step 1)Vecvec, a vec! the fn changes / hands on, element type or length unknown, pathVec::newAll files: converted 1,820 to 1,824 of 19,392. The 18 fns that left type
Vec(outside the five files): 4 convert (from_bits,to_bytes,uniform_lengths,regex_lite_global), 3 are R_VECOUT (they read the Vec:crc32(&buf)in bothencode,iterinself_attention), and 11 pass the Vec and stop at the next refusal. Over all files the first refusal of 25 fns moved: 4 convert, 4 are R_VECOUT, 1 is R_VECCALL, and 16 stop at the next refusal (to_le_bytes/to_be_bytes5,lines4, a refusedself2, five others). So this form reaches 4 fns of 626 today, and the numbers say why: the Vec-returning fns are mostly literals andcollects, not pushes.Measured and not shipped: allowing struct, enum and
&strelements converts 8 more fns, but the oracle cannot record them element by element yet, so the form stays at scalars.Per-file outputs: 1,368 of 1,388 are byte-identical to the merge base; the 20 that differ are exactly the files of the fns above and their callers. Dogfood, as in #11064:
firmware.rs, a refusal reason).rsof t27 at 7496ed2 (481 files,gen/included;compiler.rstimed out at 60 s under load in both runs): fns seen / converted.rsof trios, trinity, trinity-fpga, 999-multibots-telegraf (1,006 files,gen/left out)Replay of
--check(rustc harness, run,t27b testof spec plus samples), measured on 46b3eff, the head before the rebase (the t27o files did not change on master since; the rebasedgenfile is byte-identical tot27c gen-rustof the spec)bitstream.rs+5 sample calls,padding_length_distribution_guard.rs+1,trios-phd/src/main.rs+8,jepa_t_ingest/src/lib.rsthe converted item text only). Four because of the comma fix below (5 zero-parameter String fns).compiler.rsdiffered only because the 60 s cap hit under load; alone, its harness is byte-identical.jepa_t_ingestfails the sameoracle_token_to_q15u16 as i16before and after),bitstream.rsPASS with 0 tests to PASS with 1,trios-phd/src/main.rsPASS with 3 to PASS with 4, and one file went the wrong way at that head:padding_length_distribution_guard.rsPASS with 0 tests (vacuous) tot27b"unsupported" andt27c test-reportBLOCKED (tuple field index must be comptime-known). That was the untyped array constant of [bug] t27o: a read-only integer array local iterated by reference converts to an untyped array that t27c rejects #11112, below; after the last commit the file is a PASS with 1 test. Files that go from pass to not pass: 0.Found by the replay, fixed here (each test written first and failing)
regex_lite_global(s[i..].find(needle)with the sampled needle""pushes for ever) ate the memory of the machine. A Vec result is an input-dependent allocation, so the harness now carriest27o_guardwhen some fn is in this form: the original runs on a thread with 3 s and a counting global allocator that parks the thread at 16 MiB; the sample is skipped like one on which Rust panics, two such samples end the sampling of that fn. Verified on a small program: a runaway is skipped in 3 s and costs 16 MiB.uniform_lengths()was writtenuniform_lengths(, t27o_o0[0 .. 256]): the comma before the buffer was written even with no argument. The String form had the same latent defect (chrono_now_iso(, t27o_o0[..]); 5 fns in 4 files of the five repositories), fixed by the same line.outfor something else (not the Vec local, not a field) would meet the buffer parameter of that name: it is not the form, the old refusal stands.#11112 (the last commit): a list that is looped over gets its element type, or the fn is refused
let classes = [64, 128, 256, 512]; for &c in &classes { lengths.push(c); }converted toconst classes = [64, 128, 256, 512];, an untyped array that t27c reads as a tuple and aforcannot walk. The merge base writes the same constant for any fn with that pattern (fn total() -> u32 { let classes = [64, 128, 256]; .. for &c in &classes .. });uniform_lengthswas the first fn to reach it from a refusal, which is whypadding_length_distribution_guard.rsflipped from a vacuous pass to BLOCKED.let_array: when the element type is unknown and the list is written into or looped over (array_iterated: by name, by reference,.iter()), the fn is refused (R_VECTYPE, "a vec! or array literal whose element type or length t27o cannot tell"), and the token is now the list's name (classes, not its bracket). A list only indexed by number, or handed to a call, stays what it was.put_vec_elemhas a new rung,array_push_elem: in a fn in the Vec out-buffer form, a list whose loop binding is pushed as it is to the result Vec (loop_pushes:v.push(c), v the result local) has the Vec's element type, because what is pushed has it.v.push(c * 2)tells t27o nothing aboutcand is not guessed: it is refused.const classes : [4]usize = [64, 128, 256, 512];andfor c in classes. The spec t27o writes forpadding_length_distribution_guard.rspassest27b test(1 passed) andt27c test-report(1 of 1, 10 runtime asserts, vacuous 0) instead of BLOCKED.numsloop now refuses; the old comment said such a list "is left as it was"), the padding shape, the negative controls (a list looped over by reference, by.iter()and by value is refused naming the list;c * 2is refused; a suffixed list is typed by its first element; a list only indexed by number is unchanged), and a direct test offn_params_open,loop_pushesandarray_push_elem. The refusal of a written list had named[; it names the list now.Found, not fixed (filed as #11111 and #11113)
fn caller(n: u32) -> usize { tag(n).len() }becomesreturn tag(n).len;whiletagtakes(n, out). Reproduced on the merge base. This form refuses its callers instead.regex_lite_globalis weak: its samples never make the needle match, so every recorded count is 0.Checks
t27b test specs/tools/t27o/rust_convert.t27: 353 passed (333 before: 9 body and oracle tests and 8 direct tests for the Vec form, 2 body tests and 1 direct test for [bug] t27o: a read-only integer array local iterated by reference converts to an untyped array that t27c rejects #11112; every group failed first on the head before it).t27c test-report:vacuous passes 0 of 353.t27c coverage: 417 of 417 fns (149 of 149 forrust_std.t27, untouched, 51 of 51 pass).len), inserted into, assigned into by index, sorted, popped, borrowed or rebound; a second Vec; a returnedvec![n]or clone; a push whose own argument reads the Vec; a parameter already namedoutor a body that saysout; elements that are String, tuple or char;collect, a vec! literal,vec![0u8; 4]andOption<Vec<u8>>results; a scratch Vec that is not returned; a call by name, by method and by path.t27c gen-rustof the spec is byte-identical to the committedgen/rust/tools/t27o/rust_convert.rs, which compiles with rustc;zig_convert.t27andspice_convert.t27generate byte-identical Rust.t27c seal --saveforrust_convert(353 of 353 under Zig);--verifyMATCH on rust_convert, rust_std, zig_convert, spice_convert, zig_std, ledger, golden, install, service (no dependent seal re-saved;spice_convert.t27untouched).python3 -I tools/dupe_scan.py: 738 of 15,920 bodies in 218 groups at the merge base, 738 of 15,941 at the head, the same 15 findings (none new);t27c dupes --namefor each new helper: found only in this spec. The spec has 0 non-ASCII bytes and 0 home-directory literals.Not run
bootstrap/src/compiler.rs,service.rs,cli/tri/src/gates.rs(three of the five big files; their conversion changed) and of the four zero-parameter String files of the comma fix (trios-ui/rings/UR-04/src/lib.rs,archive/vibee-browser/src-tauri/src/main.rsin trinity and trinity-fpga,999-multibots-telegraf/rust/rings/GOLD-RING-PR00/src/replicate.rs).cargo build -p triwith the realtri t27o --check(the driver I compiled with rustc makes the same calls ascmd_t27o; no hand Rust was added).t27c suite,./scripts/tri test, the CI workflows beyond the gates listed,tools/check_devhome_paths.pyon a full tree (this checkout is sparse; the three changed files hold none),docs/reports/t27b_expectations.jsonand every ledger.Closes #11073and the co-author line.Draft; not set to auto-merge.
🤖 Generated with Claude Code
Whole-corpus sweep (added before merge)
All 1,388 tracked Rust files of the five repositories, merge-base converter against this head, one job at a time, 30 s cap per file, both ran every file to completion (rc 0, no timeouts), five big files included. Not the real
tribinary: both converters compiled withrustc -O2into the same per-file driver.type Vec30 of 1,388 output specs differ; 4 differ in code (all gains:
bitstream.rs,jepa_t_ingest/src/lib.rs,padding_length_distribution_guard.rs,trios-phd/src/main.rs), 26 only in a refusal comment line. Fns that dropped from converted to refused: 0. Files from pass to not-pass: 0 (end-to-end replay of the four code-changing files:bitstream.rs0 -> 1 tests,padding_length_distribution_guard.rs0 -> 1 test,trios-phd3 -> 4 tests,jepa_t_ingestthe same existing failureoracle_token_to_q15). The 11 fns now refused by the array rule were already refused for a later reason. The payoff is small, as the measurement above says: 4 fns.