Skip to content

Carry the grammar digest and production index on the prepared grammar; share the parse-witness fixture trees warm - #11032

Merged
briansrls merged 1 commit into
mainfrom
session/bold-crane-426
Sep 11, 2026
Merged

briansrls merged 1 commit into
mainfrom
session/bold-crane-426

Conversation

@gunbai-bot

@gunbai-bot gunbai-bot Bot commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Symptom (so a symptom search lands here)

Main's required floor is red: ten identities refused INTERRUPTED-BEFORE-VERDICT at the 500ms per-claim CPU ceiling (cpu_at_least=506-610ms, right-censored) on every main head since #10946 / #10961 (runs 34556215902, 34556223550, 34560949186):

  • v2.test.parse.d1_declaration_grammar_parse.* (7)
  • v2.test.parse.where_refinement_clause_parse.where_refinement_clause_parses_and_is_carried_holds, …survives_normalize_graft_holds
  • v2.test.claim.body_lowering.declaration_structure_preserved.where_refinement_clause_interior_is_not_retained_holds
  • v2.test.parse.expression_bodied_fn_decl_parse.braced_fn_decl_survives_normalize_holds

claims_failed=0: no floor run has ever reached their verdict. (Run 34560218821 at the same sha is the fleet-desired workflow, not the floor — there is no flipping head.)

Cost, measured (the interrupted figure is a censored lower bound)

where method the ten, per claim
uncontended amd64 EPYC (BuildBuddy runner, load ~1), main bf56299d claim_batch --entry <file> --functions … --eval-budget-ms 60000 318–523ms
the lane's GH runner, same run 34556223550 the 8 file-mate rows that DID complete: 353–482ms there vs 187–292ms on the EPYC → 1.4–2.1× (median ~1.6×) extrapolated ~510–840ms
arm64 session host, load 60–78 (contended by other sessions' builds) same claim_batch 266–705ms

Structurally over, not marginal.

What they spend it on — required_floor_cross_claim_demand.tsv of run 34556223550 names it:

  • parse_grammar_digest keyed, claims=19 evals=19 total_ms=2424 → ~128ms per claim, plus grammar_to_node ×2 per claim (~68ms each) — a content hash over the whole grammar node tree and an O(P) production index, rebuilt on every parse_module_prepared call although the grammar was already the warm-shared dag_prepared_grammar. This is exactly the finding Share the native_decl_selection fixture at the resolved seam so its four witnesses fit the 500ms floor #10992's write-up flagged for a separate lane.
  • Under it, one module-constant source tokenized+parsed by 2–4 claims of one file, once per claim frame (d1_tokenize_parse ~480ms inclusive per call on the runner; lex_try_rules ~97ms per claim).

Cost shape answer for root: the same class as #10992 — a shared precondition re-derived per isolated claim frame — third instance (native four → these ten). #11015 filed that failure-mode row and was closed unmerged by the operator at 02:52Z; not re-minted here, flagged to sunny-tern-813.

Repair (both homes; the line is untouched)

  1. v2.compiler.parse — GrammarFirstAnalysis now carries grammar_digest and productions_by_name, computed once in compute_grammar_first_analysis_given (so once per prepare_grammar) and read by parse_table_for_production_analyzed. The grammar's own locus, read only by the rejection arm that carries no diagnostic of its own, is derived on that arm alone. Same digest value, paid once; every claim corpus-wide that parses .dag text inherits it. Not a parser shortcut — no production, no table, no acceptance changes.
  2. The three parse-witness files share each multi-consumer source at the parse tree through nullary producers (d1_where_reproducer_parsed ×4 consumers, d1_where_bare_parsed ×3, d1_where_control_parsed ×2, d1_cache_identity_where_parsed ×2, where_refinement_bare_parsed ×2, expression_bodied_fn_parsed / expression_bodied_literal_fn_parsed / braced_fn_control_parsed ×2 each), enrolled warm in v2.workflow.floor_pure_producer_share with the rationale beside the row. Normalize stays per claim so every normalize claim still executes the stage it names. Single-consumer sources (the refusal probes) are not shared — a single-consumer warm row is a budget relocated, not a recurrence removed — and the one three-source conjunction where_refinement_clause_parses_and_is_carried_holds is split into three rows (…brand_clause_parses_holds, …range_clause_parses_holds added; nothing removed).

declaration_structure_preserved is not edited: its row parses one source in one claim and is repaired by (1) alone (363 → 239ms on the EPYC).

Evidence

  • After (1) alone, same EPYC host: the ten at 101–460ms, all under the line (d1: 343/279/207/242/385/339/352; wr: 460/264; eb braced-normalize 183; ds where 239). (2) then removes the remaining ~130–170ms tokenize+parse from each multi-consumer row.
  • All 37 claims across the four files + pure_producer_share_refusal_test (the live-roster collision witnesses) PASS under claim_batch on this branch.
  • Positive control, one per family, by execution: with the where_refinement_clause optional removed from type_variant and the = expr arm removed from fn_decl (grammar then restored byte-identical to HEAD): d1 cause_a_where_clause_parse_tree_carries_holds FAIL (control …where_control_normalizes_holds PASS, …empty_where_clause_refuses_holds PASS); wr where_refinement_clause_parses_and_is_carried_holds FAIL (…empty_clause_is_refused_holds PASS); eb expression_bodied_fn_decl_parses_holds FAIL (braced_fn_decl_still_parses_holds PASS); ds where_refinement_clause_interior_is_not_retained_holds FAIL (its three siblings PASS).
  • The instrument that decides it is this PR's own required-witnesses-floor run: [floor-shared-fill] showing the eight fills landing at preparation with disposition=Stored, joined against required_floor_claim_cost.tsv showing the ten identities at verdict_reached=true with an observed cost under 500ms.

Foreclosed / not done

No ceiling change, no floor_cost_debt row, no expected-red or quarantine, no narrowing of any assertion, no D1 / where-grammar extension.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YApoxsmnC96ad2nWpRJdja

…, and share the parse-witness fixture trees warm

SYMPTOM: main's required floor is red -- ten identities INTERRUPTED-BEFORE-VERDICT at
the 500ms per-claim CPU ceiling (cpu_at_least=506-610ms, right-censored) since #10946
and #10961 landed: the seven where-clause rows of
v2.test.parse.d1_declaration_grammar_parse, the two carried/graft rows of
v2.test.parse.where_refinement_clause_parse,
v2.test.claim.body_lowering.declaration_structure_preserved
.where_refinement_clause_interior_is_not_retained_holds, and
v2.test.parse.expression_bodied_fn_decl_parse.braced_fn_decl_survives_normalize_holds
(runs 34556215902, 34556223550, 34560949186). No floor run has ever reached their
verdict.

COST SHAPE, measured not inferred. Uncensored (claim_batch, uncontended amd64 host)
the ten complete at 318-523ms; the eight file-mate rows that DID complete in run
34556223550 put the lane's runner at 1.4-2.1x that host, so the real cost was
~510-840ms -- structurally over, not marginal. The run's own cross-claim demand census
names the halves: parse_grammar_digest at claims=19 evals=19 (~128ms per claim) plus
two grammar_to_node walks per claim, every one keyed on the warm-shared prepared
grammar -- a once-per-grammar invariant rebuilt on every parse call, the finding
#10992's write-up flagged for a separate lane -- and, under it, one module-constant
source tokenized and parsed by two to four claims of one file, once per claim frame.
Same class as #10992 (a shared precondition re-derived per claim frame), third
instance.

REPAIR, at both homes, never the line:
- v2.compiler.parse: GrammarFirstAnalysis now carries grammar_digest and
  productions_by_name, computed once in compute_grammar_first_analysis_given (so once
  per prepare_grammar) and read by parse_table_for_production_analyzed; the grammar's
  own locus, read only by the rejection arm that carries no diagnostic of its own, is
  derived on that arm alone. Every claim that parses .dag text inherits this.
- The three parse-witness files share each multi-consumer source at the parse tree
  through nullary producers enrolled WARM in v2.workflow.floor_pure_producer_share
  (eight rows); normalize stays per claim. Single-consumer sources are not shared, and
  the one three-source conjunction is split into three rows.

Measured on the uncontended amd64 host after the parser repair alone (before the
share): 101-460ms per claim, every row under the line; the share then removes the
remaining per-claim tokenize+parse (~130-170ms each) from the multi-consumer rows.
Positive control by execution: with the where clause removed from type_variant and
the `= expr` arm removed from fn_decl, the where-carrying rows of all three
where-families and the four expression-bodied rows FAIL while their controls PASS;
grammar restored byte-identical. No assertion deleted or weakened; no ceiling change.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01YApoxsmnC96ad2nWpRJdja
@briansrls
briansrls merged commit d94bcf6 into main Sep 11, 2026
1 of 3 checks passed
@briansrls
briansrls deleted the session/bold-crane-426 branch September 11, 2026 06:34
@briansrls
briansrls restored the session/bold-crane-426 branch September 11, 2026 06:48
gunbai-bot Bot pushed a commit that referenced this pull request Sep 11, 2026
Bring in #11032 (d94bcf6 parse-cost root) so the floor deadline is the post-fix one. Merge commit, not rebase.
gunbai-bot Bot pushed a commit that referenced this pull request Sep 11, 2026
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BwUh3dg6xfnDGy4PoikpUV
gunbai-bot Bot pushed a commit that referenced this pull request Sep 11, 2026
…or red this branch inherited

The floor red on 45bb5a7 was main's D1 witness budget defect, verified
by comparing identity sets against main's own floor job. #11032 fixed it
and main's floor is green with 0 budget-refused. Merging so this branch
can produce an honest verdict about ITSELF rather than re-reporting a
defect that no longer exists.
gunbai-bot Bot pushed a commit that referenced this pull request Sep 11, 2026
…USED them.

Required-floor job 103370532596 on run 34631915615 refused the three identities at 508/512/517ms. #11032 did not put this tokenize/parse/normalize shape under the 500ms line; withholding again is the censored-class fact, not a failed restore to hide.

Co-authored-by: Cursor <cursoragent@cursor.com>
briansrls pushed a commit that referenced this pull request Sep 11, 2026
DESIGN 4b: a newly discovered error class files a row. This one was
discovered by being walked into -- twice, in one morning, by me.

an_unreached_measurement_renders_as_a_failed_one.

A required lane that never reached its subject -- instrument would not
build, runner died, checkout refused -- reports at the decision surface
identically to a lane that reached its subject and refused it. Both are
one red. One carries a verdict about every identity it adjudicated; the
other carries a verdict about NOTHING, and the surface does not say
which.

THE HARM IS MISDIRECTED WORK, NOT AN ADMITTED BREAK, which is what keeps
it distinct from required_evidence_absent_reads_as_evidence_of_pass. That
class fails OPEN -- a gate admits because nothing reported. This one
admits nothing, but every reader attributes the red to the subject named
on the lane. The two are opposite directions out of the same missing
distinction.

WHERE IT LANDED TODAY, which is why the row is worth its keep: main run
34570523344 IS #11032, the repair for a separate witness-budget defect
that had main red. Its floor reported FAILURE with
standing=measurement_unreached and adjudicated ZERO identities -- so the
one run that could have told that lane whether their repair worked said
nothing, while reading as "still red after the fix". Three lanes were
downstream of that misreading.

THE DISTINGUISHING FACTS ARE MECHANICAL, which is the part worth having.
The standing already names it: measurement_unreached with cause=instrument
could not be built, against measurement_completed blockers=N. And volume:
an unreached lane emits no per-identity adjudication, so ZERO identity=
lines against one per blocker -- ~86-88 KB versus ~1.19 MB on the
specimens. Either test separates them in one grep. The surface that
decides merges applies neither.

RUNG 1, mitigatable: the standing is typed and present in the log, so a
reader who opens it can always recover the case. What is lost is that the
DECIDING surface does not carry it, so recovery depends on a human
knowing to look -- which is what a mitigation is.

CEILING 3, reachable with no new language capability: the lane already
computes the standing and the conclusion simply is not derived from it.
NOT 4, because a runner losing its filesystem is external reality.

NEXT-RUNG TRIGGER names the capability, not the artifact: a required-lane
conclusion DERIVED FROM the adjudication standing, sufficient for an
unreached measurement to present as its own state. Emitting the standing
into the log is explicitly not the trigger -- it is already there, and
this row exists because that was not enough.

No roster edit: roster.dag is gitignored and host-derived from the
directory listing, so a new row file is the append.


Claude-Session: https://claude.ai/code/session_01GPjYNDmV8FK6wYLXj4de1S

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Sep 11, 2026
…d_once_per_claim_frame (#11037)

Same recognition rule, same repair, found by a lane that had not read the row.
Per-parse-call is narrower than the claim frame; it widens the row's reach
rather than founding a neighbour. Replaces the duplicate row proposed in #11034.


Claude-Session: https://claude.ai/code/session_01Cktxi7eTQyoxpVtqGNqHRB

Co-authored-by: gunbc-ci-auto-heal <gunbc-ci-auto-heal@users.noreply.github.com>
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant