Skip to content

Grammar backward selection resolves each emitted tree once (stage 2 of #11741's rewire program) - #11835

Merged
briansrls merged 2 commits into
mainfrom
session/merry-fox-260-stage2
Sep 20, 2026
Merged

briansrls merged 2 commits into
mainfrom
session/merry-fox-260-stage2

Conversation

@gunbai-bot

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

Copy link
Copy Markdown
Contributor

What

Stage 2 of the rewire program behind #11741 (option-A ruling; stage 1 is #11784, independent — this branches off main). The formal_production_* grammar lookup family in src/v2/std/grammar.dag was ranks 2–10 of the required floor's within-claim recurrence census with the eval-frame memo retired, and the whole budget_interrupted population (effect_plan_bash_materialize_test, runner_slot_provision, witness_floor_workflow_consolidation, build_artifact_verification).

Selecting a production for an emitted node asks, for every candidate, whether its rhs matches the node; a nonterminal slot asks the same of the slot's child. As a recursion from the root, a child's answer was re-derived once per candidate at every ancestor, and again when the token edges were derived after selection — exponential in depth; the memo made it look linear. std.materialization_ladder rule 1: AuthoredDuplication, prescribed Share.

Now: one EmittedProductionResolution per emitted tree — resolved top-down against the set of left-hand sides the parents' candidates place at each child's slot (exactly the population the old recursion explored), each child visited once; matched per node is the set the old formal_production_matches_emitted_child accepted, slots are the conj positional children's resolutions in order. The unique-match selection, the per-lhs exact selection and the token-edge derivation read the carried resolution. Every existing entry point (formal_production_for_lhs_exact, formal_production_unique_lhs_exact_match, formal_production_unique_emitted_match, derive_grammar_relation_row_node, grammar_relation_row_derived_from_productions, formal_production_matches_lhs_exact_child) keeps its signature and its diagnostics (grammar_relation_production_not_found / …_backward_selection_ambiguous / …_emitted_not_conj / …_conj_slot_missing / …_conj_slot_surplus at the same loci).

Semantics-preserving on its face

By structural induction on the emitted tree: for an atom node the singleton checks are the old code verbatim; for a conj node the rhs walk is the old formal_production_rhs_matches_emitted_conj_step with the nonterminal arm reading resolution_production_for_lhs_exact(slot, lhs) where it read formal_production_for_lhs_exact(productions, lhs, child) — equal by the inductive hypothesis, because the slot is that child's resolution and its matched set is filtered by the same lhs and slot-count test the old fold applied. The root selection and the per-lhs selection then fold identical sets with identical None/One/Many arms. The asked restriction loses nothing: a production whose lhs no parent candidate places at a slot was never a candidate in the old recursion either, and the root and the per-lhs entries ask for all lhs / the one lhs respectively. Executed receipts: every grammar-relation witness in the language modules holds on both trees — typescript_derive_grammar_relation_row_round_trip, verilog_interlock_emission (byte-equality of emitted output through the generic fold, token-spine read-back, production-order invariance), typescript_record_task_translate — and the 110 claims below: 110/110 PASS before and after under both realizations.

Matched before/after on the claims it names — BOTH realizations, per claim

claim_batch --claim-run, six modules (the floor's interrupted population plus the bash fold witnesses), same host; "before" is origin/main, "after" is this head. Memo-on is the required floor's live realization and is the landing condition; memo-retired is the #11741 head.

claim tier memo-on before → after (eval_steps) memo-retired before → after (eval_steps) base floor run steps (memo-on)
an_active_authorized_required_retiree_is_masked_and_not_deleted new-witness 93,346 → 113,378 442,059,024 → 1,026,190 23886
an_inactive_slot_with_a_populated_cgroup_is_not_deleted new-witness 87,039 → 107,071 442,042,190 → 1,009,356 15947
a_permitted_surplus_slot_is_masked_and_not_deleted_on_the_first_pass new-witness 86,929 → 106,961 442,041,942 → 1,009,108 15797
witness_existence_check_no_mtime grandfathered 138,149 → 175,986 126,363,815 → 2,439,089 2020
bash_serialization_is_total_at_8_distinct_commands grandfathered 164,940 → 174,013 14,350,440 → 2,578,136 1753
bash_fold_pipe_three_stage_holds grandfathered 99,298 → 114,335 10,586,564 → 1,160,356 512
bash_serialization_is_total_at_4_distinct_commands grandfathered 100,064 → 106,129 7,175,236 → 1,289,084 917
bash_fold_command_arbitrary_grep_triple_holds grandfathered 55,244 → 67,200 6,974,615 → 487,233 292
bash_build_round_trip_pipe_holds grandfathered 67,478 → 89,063 4,567,246 → 1,050,502 29434
bash_fold_if_then_pipe_soundness_holds grandfathered 99,470 → 106,417 4,114,088 → 915,004 341
bash_fold_with_redir_pipe_soundness_holds grandfathered 83,000 → 89,167 3,612,734 → 673,908 252
bash_fold_pipe_echo_hi_wc_holds grandfathered 75,725 → 81,347 3,598,616 → 657,665 222
bash_serialization_is_total_at_2_distinct_commands grandfathered 67,626 → 72,187 3,587,634 → 644,558 499
bash_fold_pipe_and_then_left_holds grandfathered 95,286 → 101,932 2,817,237 → 830,314 259
bash_fold_if_multi_then_holds grandfathered 87,593 → 93,461 2,803,003 → 812,922 371
bash_fold_if_true_then_echo_holds grandfathered 73,863 → 78,997 2,307,950 → 578,279 227
bash_fold_and_or_negation_preserves_posix_grouping_holds grandfathered 85,479 → 89,286 2,095,823 → 1,069,065 240
bash_serialization_is_total_at_1_distinct_command grandfathered 51,417 → 55,226 1,793,843 → 322,305 290
bash_fold_command_multi_lit_echo_hi_holds grandfathered 49,826 → 53,635 1,792,205 → 320,667 138
bash_build_round_trip_command_tier_holds grandfathered 49,818 → 53,627 1,792,192 → 320,654 21108
bash_fold_direct_serialize_multi_lit_echo_hi_holds grandfathered 49,452 → 53,261 1,791,823 → 320,285 21338
bash_build_round_trip_and_then_holds grandfathered 57,232 → 68,646 1,196,063 → 609,227 23265
bash_fold_subshell_nested_and_then_holds grandfathered 75,838 → 79,302 1,024,688 → 508,430 212
bash_fold_and_then_true_false_holds grandfathered 69,086 → 72,194 1,011,296 → 493,786 146
bash_fold_or_else_true_false_holds grandfathered 68,958 → 72,066 1,011,155 → 493,645 180
bash_fold_subshell_multi_stmt_holds grandfathered 65,011 → 67,651 1,003,690 → 484,122 280
bash_fold_with_redir_redir_to_file_var_holds grandfathered 62,955 → 65,887 634,351 → 389,922 128
bash_fold_negation_subshell_false_holds grandfathered 57,148 → 59,397 519,477 → 261,515 182
bash_fold_with_redir_stderr_null_holds grandfathered 51,881 → 53,976 509,403 → 251,118 100
bash_fold_with_redir_stdout_to_stderr_holds grandfathered 51,773 → 53,868 509,286 → 251,001 100
bash_fold_with_redir_stdout_and_stderr_null_holds grandfathered 51,769 → 53,864 509,282 → 250,997 100
bash_fold_subshell_true_holds grandfathered 51,137 → 53,043 508,492 → 249,334 136
bash_fold_command_arbitrary_lit_quote_escape_holds grandfathered 44,139 → 45,689 494,900 → 234,490 105
bash_fold_command_single_lit_true_holds grandfathered 44,089 → 45,639 494,849 → 234,439 70
bash_fold_wrong_production_rejects_oracle_holds grandfathered 46,285 → 48,448 494,713 → 234,303 17504
bash_fold_direct_serialize_single_lit_true_holds grandfathered 43,898 → 45,448 494,650 → 234,240 17603
bash_fold_command_arbitrary_var_home_holds grandfathered 43,853 → 45,409 494,614 → 234,204 111
bash_fold_command_var_ref_x_holds grandfathered 43,813 → 45,369 494,573 → 234,163 70
bash_fold_direct_serialize_var_ref_x_holds grandfathered 43,578 → 45,134 494,330 → 233,920 17283
bash_build_round_trip_assign_foo_bar_holds grandfathered 44,810 → 46,400 194,891 → 256,365 21289
bash_fold_assign_wrong_production_rejects_oracle_holds grandfathered 44,301 → 47,222 151,816 → 202,700 20186
bash_fold_assign_lit_foo_bar_holds grandfathered 42,629 → 43,732 139,853 → 155,834 67
bash_fold_assign_lit_quote_escape_holds grandfathered 42,551 → 43,654 139,766 → 155,747 72
bash_fold_assign_var_x_home_holds grandfathered 42,266 → 43,369 139,478 → 155,459 72
bash_fold_exit_wrong_production_rejects_oracle_holds grandfathered 36,191 → 36,860 127,680 → 141,644 17048
bash_build_round_trip_exit_42_holds grandfathered 35,928 → 36,508 127,678 → 141,642 17023
bash_fold_relation_row_true_witness_holds grandfathered 10,738 → 12,209 127,027 → 39,472 59
an_unobserved_required_retiree_outside_membership_is_named_as_withheld new-witness 21,393 → 21,393 37,333 → 37,333 23342
an_observed_host_plans_the_missing_slots new-witness 15,809 → 15,809 24,003 → 24,003 17829
an_active_surplus_slot_is_never_deleted new-witness 15,001 → 15,001 21,695 → 21,695 15064
bash_fold_with_redir_wrong_spellings_rejects_oracle_holds grandfathered 7,751 → 8,300 14,242 → 16,367 6877
bash_fold_exit_code_42_holds grandfathered 6,030 → 6,377 10,709 → 11,905 41
bash_fold_exit_code_0_holds grandfathered 5,954 → 6,301 10,627 → 11,823 40
bash_fold_negation_wrong_spellings_rejects_oracle_holds grandfathered 5,822 → 6,169 10,470 → 11,666 5100
bash_fold_negation_subshell_rawline_holds grandfathered 5,816 → 6,163 10,464 → 11,660 5093
bash_fold_raw_line_orch_emit_holds grandfathered 4,299 → 4,633 7,648 → 8,788 3665
bash_fold_raw_line_wrong_spellings_rejects_oracle_holds grandfathered 4,237 → 4,571 7,582 → 8,722 3671
bash_fold_raw_line_x_eq_holds grandfathered 4,232 → 4,566 7,577 → 8,717 3665
bash_fold_raw_line_cmdsubst_holds grandfathered 4,232 → 4,566 7,577 → 8,717 3659
bash_fold_raw_line_paren_holds grandfathered 4,232 → 4,566 7,577 → 8,717 3665
bash_fold_raw_line_quoted_holds grandfathered 4,232 → 4,566 7,577 → 8,717 3665
bash_fold_raw_line_mktemp_holds grandfathered 4,232 → 4,566 7,577 → 8,717 3665
bash_fold_raw_line_trailing_nl_holds grandfathered 4,232 → 4,566 7,577 → 8,717 3665
the_registration_file_decodes_its_ephemeral_member new-witness 6,423 → 6,423 7,220 → 7,220 6423
only_the_fabric_host_loses_a_provisioning_target new-witness 4,265 → 4,265 6,041 → 6,041 7436
a_retired_incarnation_is_owned_and_plans_removal new-witness 3,572 → 3,572 4,903 → 4,903 3816
the_plan_realizes_removal_through_the_privileged_seam new-witness 3,531 → 3,531 4,862 → 4,862 3599
witness_provision_plan_extracts_only_upserts new-witness 2,998 → 2,998 4,180 → 4,180 3042
bash_fold_if_wrong_production_rejects_oracle_holds grandfathered 2,451 → 9,966 3,452 → 22,898 216
bash_fold_subshell_wrong_production_rejects_oracle_holds grandfathered 2,447 → 6,327 3,435 → 13,156 125
bash_fold_heredoc_wrong_production_rejects_oracle_holds grandfathered 2,380 → 3,999 3,393 → 7,071 159
bash_fold_delegated_bundle_fail_closed_holds grandfathered 2,380 → 3,999 3,393 → 7,071 159
bash_fold_and_then_wrong_production_rejects_oracle_holds grandfathered 2,378 → 28,396 3,381 → 79,537 135
bash_fold_pipe_wrong_production_rejects_oracle_holds grandfathered 2,378 → 42,679 3,381 → 150,161 211
bash_fold_env_prefixed_wrong_production_rejects_oracle_holds grandfathered 2,355 → 3,885 3,355 → 6,323 114
bash_fold_heredoc_wrong_spellings_rejects_oracle_holds grandfathered 2,777 → 3,357 3,342 → 5,383 2781
bash_fold_with_redir_wrong_production_rejects_oracle_holds grandfathered 2,330 → 3,771 3,317 → 5,575 79
bash_fold_negation_wrong_production_rejects_oracle_holds grandfathered 2,331 → 2,638 3,305 → 4,082 54
bash_fold_raw_line_wrong_production_rejects_oracle_holds grandfathered 2,305 → 2,612 3,279 → 4,056 44
bash_fold_env_prefixed_wrong_spellings_rejects_oracle_holds grandfathered 1,976 → 2,367 2,374 → 3,768 1980
witness_single_artifact_produces_two_checks grandfathered 2,088 → 2,088 2,290 → 2,290 2086
witness_srv3_deploy_row_names_its_declared_slots new-witness 1,851 → 1,851 2,050 → 2,050 5353
witness_membership_reconcile_adds_delta_slots new-witness 1,625 → 1,625 2,025 → 2,025 1644
witness_srv4_instance_roster_matches_its_declared_count new-witness 1,860 → 1,860 2,016 → 2,016 5355
the_fabric_slot_is_not_a_provisioning_target new-witness 1,665 → 1,665 1,745 → 1,745 5399
a_registered_or_active_or_enabled_tree_still_refuses_removal new-witness 1,012 → 1,012 1,134 → 1,134 1013
witness_floor_covers_both_release_bins grandfathered 818 → 818 818 → 818 818
witness_runner_count_not_in_installer_argv new-witness 647 → 647 653 → 653 4569
every_enrolled_host_resolves_and_none_is_unmodeled new-witness 478 → 478 577 → 577 4684
srv2_resolves_as_refused_and_the_others_as_rows new-witness 455 → 455 554 → 554 4668
no_deploy_row_out_commits_the_memory_budget new-witness 399 → 399 549 → 549 4612
host_grammar_round_trips_through_the_allocation_renderer new-witness 333 → 333 353 → 353 333
a_dead_ephemeral_registration_is_a_retired_incarnation new-witness 313 → 313 334 → 334 314
an_authored_count_enumerates_exactly_that_many_indexed_names new-witness 222 → 222 222 → 222 240
witness_enumeration_postcondition_red_on_under_count new-witness 127 → 127 213 → 213 4263
an_unobserved_host_refuses_instead_of_planning new-witness 170 → 170 170 → 170 4335
an_active_ephemeral_registration_and_an_unreadable_one_still_refuse new-witness 104 → 104 105 → 105 105
witness_actions_runner_release_cites_github_digest new-witness 64 → 64 64 → 64 64
a_name_outside_the_host_grammar_refuses_even_when_dead new-witness 52 → 52 52 → 52 53
an_unmodeled_host_has_no_deploy_row new-witness 34 → 34 34 → 34 38
bash_fold_heredoc_holds grandfathered 30 → 30 30 → 30 30
bash_fold_env_prefixed_lit_t_holds grandfathered 24 → 24 24 → 24 24
bash_fold_emitted_tree_differs_on_wrong_fixture_holds grandfathered 3 → 3 3 → 3 105
a_pending_unmasked_standing_still_emits_the_inhibitor new-witness 93,327 → 113,359 0 → 1,024,766 24047
a_completed_retirement_authorizes_exactly_that_tree_removal new-witness 15,138 → 15,138 0 → 22,013 15278
a_completed_srv1_surplus_retirement_emits_the_teardown_argv new-witness 21,424 → 21,424 0 → 37,418 23373
an_unobserved_cgroup_withholds_the_removal_by_name new-witness 15,090 → 15,090 0 → 21,912 15245
a_completed_receipt_for_another_slot_authorizes_nothing new-witness 86,967 → 106,999 0 → 1,009,284 15875
a_surplus_slot_outside_the_authorized_scope_is_neither_masked_nor_deleted new-witness 15,118 → 15,118 0 → 21,875 15233
absent_evidence_emits_neither_mask_nor_removal new-witness 14,787 → 14,787 0 → 21,071 14730
totals (110 claims) 3,475,905 → 3,886,850 1,541,599,084 → 29,373,304

(a) Memo-on, the live path: 74 of 110 claims do more eval steps, +12% in total (3,475,905 → 3,886,850); the largest single increase is +38k (witness_existence_check_no_mtime, 138k → 176k in claim_batch). No claim approaches its ceiling: the floor's own numbers for these claims are far below claim_batch's (the last column: the floor's cross-claim warm tier serves the bash productions, claim_batch installs no roster), and scaling each claim's base floor cost by its measured ratio puts the highest at ~40% of its line (bash_build_round_trip_pipe_holds, 29,434 → ~39k of 361,500 grandfathered; the new-witness-tier runner_slot_provision claims 15.8–23.9k → ~19–29k of 72,300). The CI floor run on this PR is the authoritative reading of that.

(b) Memo-retired, the win: 1,541,599,084 → 29,373,304 eval steps in total (52×); the runner_slot_provision claims 442M → 1.0M; witness_existence_check_no_mtime 126M → 2.4M; the seven memo-retired claims that timed out on the before run (not in the table) all complete after.

What the +12% memo-on is: the resolution bookkeeping (asked-lhs sets per slot) the old recursion did not carry. A first bottom-up draft (match all productions at every node) measured +64% memo-on and was reworked into this asked-lhs form for that reason. The remaining caller-side duplication — language folds deriving a row per subtree, each re-resolving its subtree (bash_fold_relation_row_witness demanded 3× per row in the trace) — is a consumer carry and is not attempted here.

🤖 Generated with Claude Code

Brian Searls and others added 2 commits September 20, 2026 10:33
… top-down, instead of re-matching per candidate at every ancestor

Selecting a production for an emitted node asks, for every candidate,
whether its rhs matches the node, and a nonterminal slot asks the same of
the slot's child. Written as a recursion from the root, a child's answer
was re-derived once per candidate at every ancestor and again when the
token edges were derived after selection -- exponential in depth, and
only the eval-frame result memo made it look linear. On the required
floor with that memo retired (run 35466872753) the formal_production_*
family was ranks 2-10 of the within-claim recurrence census and the
whole budget_interrupted population.

std.materialization_ladder rule 1 names that AuthoredDuplication and
prescribes Share: one EmittedProductionResolution per tree, resolved
top-down against the set of left-hand sides the parents' candidates ask
of each child (the population the old recursion explored), each child
visited once; the unique-match selection, the per-lhs exact selection
and the token-edge derivation read the carried resolution. Every
existing entry point keeps its signature and diagnostics; the
formal_production_matches_lhs_exact_child single-candidate reading is
kept for its verilog consumer.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@gunbai-bot

gunbai-bot Bot commented Sep 20, 2026

Copy link
Copy Markdown
Contributor Author

Additional receipt, measured after opening: the docs-projection regen — the production route that never completed on the memo-retired binary (#11741, >48 min, killed) — completes on this branch with the memo-retired binary in 295 s wall (gunbc run … docs_projection_gate --function regen; base memo-on: ~300 s), and the three projections it writes are byte-identical to the committed ones (git status clean afterwards). The eager data environment's one non-completing declaration, data witness_floor_workflow, was this family: its bash-fold serialization derives grammar-relation rows per subtree, and the memo-retired eager env now adds ~0 s over resolve (265 s with --claim-run, 265 s without). So this stage discharges the regen blocker on #11741's list outright.

@briansrls
briansrls added this pull request to the merge queue Sep 20, 2026
Merged via the queue into main with commit 6e06d72 Sep 20, 2026
4 checks passed
@briansrls
briansrls deleted the session/merry-fox-260-stage2 branch September 20, 2026 16:26
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