Repository navigation
v2_compiler_parse.rs was never flat: 19 of 21 diagnostics are two roots, and three were plain .dag type defects - #8833
Merged
Merged
Conversation
…ts, and three were plain .dag type defects
The file was dispatched as a FILE lane on a scale-free property — 28 diagnostics
over seven rustc codes, top-class share 21%, five classes within 1.5x of the top.
Read at mechanism grain instead of code grain it is not flat at all: 90% of the
surviving diagnostics are TWO corpus-wide roots, and the seven-class spread is an
artifact of one mechanism wearing three codes and another wearing two.
T3 (Set modeled as a function-record, realized as OrdSet) 11 diagnostics, 7 sites
one construction yields E0560 (no field `member` on the PointwisePower it
built), E0308 (PointwisePower where OrdSet was expected) and E0609 at every
read — so a class lane keyed on any one code sees a third of it.
RT-builtin (bare-name interception of `contains`) 8 diagnostics, 4 sites
02_parse.dag imports v2.std.algebra.contains explicitly and the emitter
routes to the host builtin v1_rt::contains(String, String) anyway; the arity
mismatch is E0061 and the `eq` closure left with nowhere to land is E0282 at
the same call. An import is evidence of visibility; the emitter overrode it.
Neither is fixable from inside this file, and neither is patched here — dodging
`Set` by hand or renaming `contains` would be the unmarked workaround DESIGN §5
names as a line-stop signal, and would delete the cleanest specimens either root
has.
What IS fixed is three genuine type defects in src/v2/compiler/02_parse.dag, all
inside parse_expr_terminal, none of them emitter behaviour: a VARIANT (StampClass)
declared as a parameter TYPE where its coproduct TerminalStampMode belongs and
where the sibling declaration already spells it correctly; a spurious
node_occurrence_minted wrap handing a NodeOccurrenceId to a callee declaring
OccurrenceId; and Outcome's NonEmptyDiagnostics bound to a List<Diagnostic> field
when the module already declares the converter and uses it elsewhere.
Evidence, two arms in ONE remote dispatch so they share the ambient tree (the
runner mirrors a different checkout than the requesting worktree, which silently
confounded a first attempt):
ARM=BASE TOTAL 431 v2_compiler_parse.rs 24
ARM=HEAD TOTAL 428 v2_compiler_parse.rs 21
Joined at SITE identity rather than by count: the removed set is exactly
{E0573@1664, E0308@1675, E0308@1684}. Nothing was added, in this file or any
other, and every other file's count is identical across the arms — so the -3
total is the -3 here and not a class moved upstream. Independently, a clean
worktree at 531a107 produced the same 24 with a byte-identical site list.
The brief's board was also one class stale: its E0597:4 column is zero live,
closed by #8799 after that measurement. No delta is claimed on the other columns.
Reported in the coordination surface as section 22, including the observation the
lane ends on: the surviving board's top-class share RISES from 21% to 24%, so
fixing the singletons makes the file flatter by the code-grain metric while making
it more concentrated by the mechanism-grain one. A code-grain histogram is not a
root census, and a lane picked off one should re-partition before it plans.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
… board figures smart-ram-730's fleet board on the same ref ba63edc is 399, reproduced independently twice site-for-site. The 32-diagnostic gap is the 61 ambient dirty files this lane's runner mirrored — a dirty src/v1/05_emit_rust.dag changes what is emitted, which changes what rustc sees. So 431 and 428 are internally consistent with each other and with nothing else, and differencing 428 against 399 would render this lane's -3 as a fiction. Marked as such at the point of use, with the two strings (OBSERVED ON / CLAIM ABOUT) written on the section so the difference is legible before a sentence quotes them rather than after. The -3 delta is untouched by this: both arms ran in ONE dispatch against the SAME contaminated tree, so the contamination is common-mode, and the join is at site identity rather than by count. Also corrects one of this section's own sentences. It described the 531a107 characterization run as a 'clean worktree', which was a claim about the REQUESTING worktree — that run never echoed git status, so the runner's dirtiness is unmeasured there too. Two runs agreed at 24 with a byte-identical site list; two TREES did not. Same conflation the section exists to warn about, made one paragraph above the warning. And names the owning lanes for the two roots left unpatched: T3 is royal-dove-436's cluster (blocked on an identity question, renderers not to be touched from here), RT-builtin contains is the callee-resolution class. States plainly that being the cleanest unpatched specimen of both is the deliverable those lanes should take from this file. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Aug 22, 2026
Merged
Closed
The dissolution census asserted over an empty population, so its headline green could not fail
#8834
Merged
Closed
Merged
extdeps dissolve-on census: 35 rows read by hand — 4 convertible, 3 already fired, 28 judgment
#8861
Merged
briansrls
pushed a commit
that referenced
this pull request
Aug 22, 2026
…ad ever obeyed until one did (#8854) * The declaration was the lie: two OccurrenceId params that no caller had ever obeyed until one did MAIN IS RED at 67437fc — 16 witnesses (12 fold_lowering, 4 body_lowering.statement_let_bind) fail with `non-exhaustive pattern match on: OccurrenceId { value: 79 }`. Green PR, green base, red union: #8833's branch did not contain #8828, and neither head ever existed in the combination that fails. The mechanism is one layer below the obvious one. #8833 changed one call in `02_parse` `parse_expr_terminal` from `node_occurrence_minted(id: minted.id)` to `minted.id` — and it did that to OBEY the signature it was calling. `v2.extdeps.languages.dag` declares fn dag_int_literal_node_from_lexeme(lexeme: String, occurrence_id: OccurrenceId) fn dag_int_literal_node_from_magnitude(magnitude: DecimalMagnitude, occurrence_id: OccurrenceId) and stores that parameter straight into `Node.occurrence_id`, which is declared `NodeOccurrenceId`. Both signatures have said `OccurrenceId` since #6558. Every caller in the tree contradicted them by passing `SyntheticOccurrence`, which is why it stayed invisible. #8833's author was the first person to take the signature at its word. So the wrap is correct and the declaration is the defect. Fixed at the declaration, not just at the call site — repairing only the caller leaves the lie standing for the next caller to obey: - dag.dag: both parameters redeclared `NodeOccurrenceId`; the now-unused `import std.occurrence_identity { OccurrenceId }` dropped, `NodeOccurrenceId` added to the existing `v2.std.node` import. - 02_parse.dag: `node_occurrence_minted(id: minted.id)` restored. Caller census, read at call grain rather than by same-line grep — 17 sites across the two functions: 15 pass `SyntheticOccurrence`, 1 passes `node.occurrence_id`, 1 is dag.dag's own internal pass-through, and 1 passes the raw `minted.id`. Exactly one obedient caller existed and it is the one that reddened main, so no second detonation is waiting. Changing the declared type inverts which callers are correct, and by the finding below the typechecker cannot verify that for us — hence reading, not building. Green by execution, not by reasoning that the types now match: all 16 fold_lowering witnesses and all 4 statement_let_bind witnesses PASS. The discriminating RED is main itself. Also files one guarantee row, deliberately not fixed here. `v1.compiler.04_infer` gates `arg_compat_diags` on `module_skips_direct_call_arg_check`, which is true for every module named `v2.*`, keyed on the CALLER's module — so the direct-call argument-TYPE judgment is switched off across the entire active v2 corpus. That is why nothing complained in EITHER direction for two months. The row records the inversion that makes this class hard to see: a declaration that lies is inert while every caller contradicts it in the same direction, and detonates on the first caller who obeys it, so the at-risk population is callers who might get it right. * The row is a correction to DESIGN §4b, not an observation beside it: confinement was measured and then treated as safety DESIGN §4b names module_skips_direct_call_arg_check and reports it scoped entirely to the direct-call argument-type judgment, not reaching sole_constructor — a positive finding, axis retired. That finding is correct. It asked whether the exemption LEAKS; it never asked what the exemption COSTS inside the judgment it is scoped to, and that judgment is the argument-type check for the whole active v2 corpus. A reader who finds DESIGN's sentence and this row separately would conclude the question was already answered, so the row now says which half it is. Also records, against my own case: the arm is NOT unreasoned. direct_call_shape_wall_note states the TYPE judgment's false-positive classes are representation gaps (brand aliases, optionality's two forms, anonymous literals, expansion depth). That is a real stated reason, and it is why this row asks for a measurement rather than a deletion. What is unmeasured is whether those classes still fire in v2 and at what rate. * The corrected declaration is TRUE but INERT: the judgment that would enforce it is the one switched off Two changes, neither to the repair. RUNG HONESTY, and it is the point. Correcting the parameter to NodeOccurrenceId reads like the §5 construction move -- fix the type and the wrong call stops compiling -- but the judgment that would refuse the wrong call is `module_skips_direct_call_arg_check`, which exempts every `v2.*` caller from the direct-call argument-TYPE check. So this PR lands a wall that CANNOT FIRE. The declaration is now true, which is worth having on its own terms, but as enforcement it is inert, and shipping it while believing the class is closed is exactly the rung inflation §4b calls worse than sitting low. The class stays at its old rung; the next-rung trigger is the exemption's deletion, which the guarantee row already names. (Product-direction ruling, swift-badger-524.) ANNOTATIONS, grafted from gunbc#8856 (author's wording kept) with two additions of my own. With the type wall inert, a §4c annotation is the only thing standing at these two sites -- it is not evidence, and nothing mechanical reads it, which is precisely why it has to say why the shape is what it is. Added to the callee: a bare OccurrenceId is the PAYLOAD INSIDE one of NodeOccurrenceId's arms, never a member of the coproduct -- the modeling error in one line (smart-ram-730's phrasing, the clearest statement of it anyone produced). Added to the caller: that the exemption is why no mechanism stands there. Green by execution after the annotations: 16/16 fold_lowering witnesses PASS, 0 FAIL. --------- Co-authored-by: Brian Searls <briansearls1@gmail.com>
briansrls
added a commit
that referenced
this pull request
Aug 25, 2026
…uted flag names an RcStr carrier that does not exist (#9212) * char_at's ascii-aware split has no producer on main: delete it and bound the ASCII test by pos `v1_rt::char_at_ascii_aware` / `string_length_ascii_aware` / `substring_ascii_aware` take a precomputed `is_ascii` flag, and their doc comment names the producer of that flag as "the `RcStr` carrier fact". No `RcStr` exists in this tree: `Value::Str` is `Rc<str>`, and every caller -- `char_at`, `string_length`, `substring`, and the one interpreter call site -- supplies `s.is_ascii()`, an O(n) whole-string rescan computed fresh per call. The split is therefore unroutable: it is three public functions whose parameter has no producer, plus a comment asserting a carrier that does not exist. Provenance, because the obvious reading (someone deleted RcStr) is wrong: b1775d8 (#8360) landed BOTH halves and is NOT an ancestor of main. main's history is rooted at 67437fc (#8833), a wholesale seed re-import whose tree already carries the runtime split (`src/v1/runtime_rust.dag` +826) beside an interpreter with no `RcStr` (+16717, zero occurrences). The flag has never had a producer anywhere in main's reachable history, and #8360's O(1) claim has never been true of this tree. The repair, at the single authority `src/v1/runtime_rust.dag` (mirrors `v1_rt.rs` / `v1_compiler_runtime_rust.rs` follow by regen): - Delete the `_ascii_aware` triplet. Nothing supplies a flag other than `s.is_ascii()`, so the parameter is a second representation of a fact the function can read itself (DESIGN §2/§3), and the comment on it is the §4b inflation case -- a carrier named for a rung the tree does not occupy. - Bound the ASCII test by the requested position instead of by the whole string. A leading run of ASCII bytes makes the byte offset equal the code-point offset, so `char_at` examines `bytes[..=pos]` and `substring` examines `bytes[..end]`, never the tail. Cost drops from O(n) + O(pos) to O(min(pos, n)) -- the fallback's own cost. Semantics are unchanged: where the old form fell back to `chars()` because the STRING contained a multibyte char, the new form takes the byte path only when the PREFIX up to the requested index is ASCII, which is exactly the condition under which byte index equals code-point index. - Route the interpreter's `native_len` `Value::Str` arm through `v1_rt::string_length` and fix its doc comment, which named the deleted helper. - Delete `gunbc.char_at_scaling_probe_support`. Its `DissolutionCondition` names `src/v1/stage0/src/bin/char_at_scaling_probe.rs`, deleted by #9160, and its trigger is "when char_at's O(1) property is floor-enrolled" -- a property this tree does not have. It is unconsumed (census row in docs/plans/unconsumed-module-residue-disposition.md) and its subject is gone. RESIDUAL, DECLARED RATHER THAN CLAIMED CLOSED: a left-to-right walk of a string is still O(n^2), now with a smaller constant rather than a different shape. A single call cannot be O(1) without the whole-string ASCII fact, which needs a carrier on the string value; that carrier -- or a cursor surface that does not re-index from zero -- is this class's next-rung trigger, and it is recorded in the `char_at` doc comment rather than left to be rediscovered. This change lowers no rung: the deleted split was inert, so nothing it guaranteed is lost. Evidence: dag/test/claim/char_at_unicode_witness_test.dag (SubstrateInputsOnly, floor-routed) gains the discriminating control for the prefix-bounded path -- "ab" + U+00E9 + "c" is 5 bytes and 4 code points, so a byte-offset implementation returns U+00A9 at index 3 and "c" at index 4 where code-point indexing returns "c" at 3 and "" at 4, with the same split applied to `substring`. * Regen: converge v1_compiler_runtime_rust.rs with the edited runtime_rust.dag authority (pass 1) Pass 1 of the stage0 two-pass convergence. `--required-regen` regenerated `v1_compiler_runtime_rust.rs` -- the stage0 transliteration of `src/v1/runtime_rust.dag` -- from the edited authority; this installs that candidate byte-for-byte. `v1_rt.rs` is emitted BY this mirror, so its pass-1 candidate was still the old `_ascii_aware` text and converges only on pass 2, after a rebuild against the mirror installed here. * Drop the substring assertion: its RED was never observed, so it is not coverage The witness gained three assertions for the prefix-bounded fast path. Two of them are demonstrated discriminating: with `char_at`'s prefix check removed and the binary rebuilt from scratch (perturbation confirmed present in source), `char_at_agrees_across_the_ascii_prefix_boundary`, `char_at_past_the_multibyte_char_is_not_a_byte_offset` and the pre-existing `char_at_indexes_code_points_on_multibyte_text` all go RED. The third, `substring_agrees_across_the_ascii_prefix_boundary`, does not. Its own perturbation -- `if bytes[..out_end].is_ascii()` replaced by `if true`, so the byte-slice path is taken unconditionally -- left it GREEN, twice, the second time with the binary deleted first, the build failure-checked rather than piped through `tail`, and the edit grep-proven in source. A follow-up probe that would have printed the returned values panicked in `cli_run.rs` on BOTH arms, so it measured nothing: identical output across arms is the signature of an instrument that did not run, not of agreement. So the mechanism is unexplained. What is NOT in doubt is the assertion's status: a check whose RED has never been observed is not evidence, and shipping it would put it in the worst class DESIGN §4b names -- permanently green as far as anyone can show, and cited as coverage precisely because it is named after the thing it does not test. It is removed rather than kept with a caveat, because a caveat in a PR body does not travel with the test. The `substring` code change stands: it is the same prefix-bounding as `char_at`, semantics-preserving by the same argument (the byte path is taken only when the prefix up to the requested index is ASCII, which is exactly when byte index equals code-point index), and substring is exercised heavily by the existing corpus. What it does not have is a discriminating control of its own, and the witness note now says so in the module rather than leaving a reader to infer coverage from the file's name. OPEN QUESTION, recorded rather than routed around: `substring(s, 0, 3)` on "ab" + U+00E9 + "c" under the unconditional byte path slices `s[0..3]`, which lands inside the two-byte U+00E9 and should panic on a non-char-boundary. It did not. Either that path is not reached by a named-argument `.dag` call, or the panic is absorbed somewhere between the interpreter arm and the claim runner's exit status. The second would be the more serious finding -- a witness that cannot go red because failures are swallowed would affect every witness, not this one -- and it is worth its own lane. --------- Co-authored-by: Brian Searls <briansearls1@gmail.com>
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.
The file was dispatched as a FILE lane on a scale-free property — 28 diagnostics over seven rustc
codes, top-class share 21%, five classes within 1.5x of the top. Read at MECHANISM grain instead of
code grain it is not flat at all: 19 of the surviving 21 diagnostics are TWO corpus-wide roots, and
the seven-class spread is an artifact of one mechanism wearing three codes and another wearing two.
Neither is reachable from inside this file and neither is patched here. Both have owners — T3 is
royal-dove-436's cluster (blocked on an identity question; its renderers are not to be touched from
here), RT-builtin
containsis the callee-resolution class. DodgingSetby hand or renamingcontainswould be the unmarked workaround DESIGN §5 names as a line-stop signal, and would deletethe cleanest specimen either root has. Being that unpatched specimen is the deliverable those two
lanes should take from this file — seven
Setsites where one construction's three codes can beread side by side, and four
containssites where an explicit import is demonstrably overridden.What this PR changes
Three genuine type defects in
src/v2/compiler/02_parse.dag, all insideparse_expr_terminal,none of them emitter behaviour:
stamp: StampClassdeclared a VARIANT as a parameter TYPE.StampClassis a variant ofTerminalStampMode, the value is passed straight toparse_stamp_terminal(stamp: TerminalStampMode), and the sibling declaration already spells it correctly. (E0573)occurrence_id: node_occurrence_minted(id: minted.id)wrapped anOccurrenceIdinto aNodeOccurrenceIdfor a callee declaringOccurrenceId. The wrapper is spurious at thisposition. (E0308)
ParseExprRejected { diagnostics: d }boundOutcome'sNonEmptyDiagnosticsto aList<Diagnostic>field, where the module already declares the converter and uses itelsewhere. (E0308)
Evidence — the delta is sound, the absolutes are NOT board figures
Two arms in ONE remote dispatch, so the ambient contamination is common-mode and cancels:
Joined at SITE identity rather than by count: the removed set is exactly
{E0573@1664, E0308@1675, E0308@1684}. Nothing was added, in this file or any other, and everyother file's count is identical across the arms — so the -3 total is the -3 here, not a class moved
upstream.
431 and 428 must not be differenced against the fleet board. That board on the same ref is 399,
reproduced independently twice site-for-site; the 32-diagnostic gap is the ambient dirty emitter
this lane's runner mirrored. 431/428 are internally consistent with each other and with nothing
else. The -3 is unaffected — one dispatch, one tree, site-identity join.
The instrument gap that produced it is general and is being propagated: a single-arm remote probe
cannot be trusted to be measuring your tree unless it echoes its own HEAD and its
git status --porcelaincount.MARKER_REFalone proves the commit and says nothing about what isdirty on top of it.
Also
The brief's board was one class stale: its
E0597:4column is zero live, closed by #8799 after the6c3fbeb960measurement. No delta is claimed on the other columns.Written up as §22 of
docs/plans/self-host-cargo-refusal-root-partition.md, ending on the thingthat generalizes: the surviving board's top-class share RISES from 21% to 24%, so fixing the
singletons makes the file flatter by the code-grain metric while making it more concentrated by the
mechanism-grain one. A code-grain histogram is not a root census, and a lane picked off one should
re-partition before it plans.
🤖 Generated with Claude Code