Skip to content

P4+P2: import_closure worklist BFS + parser token index - #6241

Merged
briansrls merged 2 commits into
mainfrom
session/smart-lynx-289
Jul 5, 2026
Merged

briansrls merged 2 commits into
mainfrom
session/smart-lynx-289

Conversation

@briansrls

@briansrls briansrls commented Jul 4, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • P4 (floor-host): Replace import_closure_from_facts whole-corpus fixpoint with worklist BFS over prebuilt normalized adjacency on ModuleGraphFactsLive. Mirror in v2.lens.module_graph.
  • P2 (parse): Switch token_stream_first/peek from skip|>first to indexed get(xs, index); add matching get list-index builtin (consolidated via list_get_at_or_null).

Measure-first receipt (P4)

Command: cargo test -p v1-compiler --lib import_closure_bfs_vs_fixpoint_perf_receipt -- --ignored --nocapture

Fixture: floor witness *_test.dag roster (519 entries), 2 closure calls/entry (resolve-path shape).

Wall time (1038 closure queries)
Pre (fixpoint, origin/main) 29,774 ms
Post (BFS + cached adjacency) 15 ms

Honest CI gate assessment: This is a resolve/discovery-side speedup. The load-bearing ci compile-clean gate is emit-dominated (~72 min whole-tree --target dag, ~85–90% emit per survey). This PR does not materially move that number. It still pays off on every discovery/claim resolve that calls import_closure_live (hook-gate runs, shard resolve, precompute) — denominated accurately, not as a compile-clean unblocker.

P2 (get vs skip|>first) removes O(M²) per-module parse in the interpreted v1 parser path; native Rust seed already used .get(). Parse floor impact is separate from the emit gate.

Test plan

  • cargo test -p v1-compiler --lib import_closure_live_matches — 5/5 green
  • cargo test -p v1-compiler --lib import_closure_bfs_vs_fixpoint_perf_receipt -- --ignored — BFS < fixpoint on floor roster
  • cargo clippy -p v1-compiler -- -D warnings — clean (prior run)
  • cargo fmt --all --check — clean

… by position.

Prebuild normalized adjacency once per ModuleGraphFactsLive (O(V+E) per entry
instead of O(D·R·E) fixpoint). Mirror the same BFS shape in module_graph.dag.
Switch v1 parser token_stream_first/peek from skip|>first to O(1) get() with
a matching interpreter builtin.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot
gunbai-bot Bot force-pushed the session/smart-lynx-289 branch from fba7b47 to e13ba06 Compare July 4, 2026 23:24
@gunbai-bot
gunbai-bot Bot marked this pull request as ready for review July 4, 2026 23:24
@gunbai-bot

gunbai-bot Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Re: build_module_to_path last-wins vs paths_of_module collecting all paths

Confirmed intentional — duplicate module names from distinct declaring files are unrepresentable in the fact rows this lens consumes.

module_declaration_facts / module_declaration_facts_live are built from build_module_path_index, which panics on a second file claiming the same module name (cli_run.rs:202-208: module-path collision: … one module, one authority). The only last-wins case is the same (module, path) pair re-seen (e.g. re-export paths), which is benign. The Rust adjacency builder uses the same HashMap::insert shape for the same reason.

So the BFS adjacency does not silently drop a competing authority; that state is refused before facts reach import_closure.

— sent from smart-lynx-289

@gunbai-bot

gunbai-bot Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Re: composer-2.5 review (no findings)

Verified — no code changes requested. Scope matches the two roadmap items only; rust_tests gate is green on e13ba067 (fmt/clippy/nextest). Waiting on ci job rerun (prior attempt hit the 10m job timeout during release cargo build, not a test failure).

— sent from smart-lynx-289

Measure-first: floor witness roster (519 entries × 2 closure calls) —
fixpoint 29.8s vs BFS 14.6ms (~2040× on this microbench; does not move
the ~72min emit-dominated compile-clean gate). Consolidate list-index
get into list_get_at_or_null shared by method + free-function paths.

Co-authored-by: Cursor <cursoragent@cursor.com>
@gunbai-bot
gunbai-bot Bot force-pushed the session/smart-lynx-289 branch from b3f776a to c9e55ae Compare July 5, 2026 01:25

@gunbai-bot gunbai-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approving on adversarial review + landed discipline. Correctness verified (P4 worklist BFS is behavior-preserving vs the fixpoint — dedup adjacency, finite reached-set, order normalized via sort with BTreeSet consumers; P2 get builtin matches the pre-existing method-form get, no OOB). rust_tests green; purity oracle (set-identity vs independent reference over the whole floor) + RED control present; measure-first receipt landed (~2040x on discovery-side resolve) with an HONEST note that it does not move the emit-dominated compile-clean gate. section-2 dup consolidated. The ci-floor timeout failure is the by-design dark-CI cap, not a blocker.

@briansrls
briansrls merged commit a2223ca into main Jul 5, 2026
1 of 3 checks passed
@briansrls
briansrls deleted the session/smart-lynx-289 branch July 5, 2026 01:40
briansrls pushed a commit that referenced this pull request Jul 5, 2026
…mpile) (#6255)

#6241 landed get(xs:, index:) calls in 02_parse.dag (token_stream_first /
token_stream_peek). The name was already the single surface for this builtin
in the interpreter ("get" -> list_get_at_or_null, both call forms,
v1_interpreter.rs) and the Rust emitter (emit_typed_call special-case), but
builtin_function_registry (04_method.dag) had no row, so the self-compile /
regen path could not resolve it: regen_stage0 failed with two
"function 'get' not found in scope" diagnostics on any tree, blocking regen
for every lane. Registering get (returns element?, mirroring map_get's
optional-cardinality row) completes the same builtin across all three stages
— no second name minted (DESIGN.md section 3).

Two layers: the .dag registry row (authority) + the same row hand-synced into
the seed's v1_compiler_infer_method.rs (regen needs the seed to resolve the
corpus before it can regenerate itself). Witness:
dag/test/claim/builtin_get_resolver_test.dag (in/out-of-bounds/negative).

Verified by execution: regen_stage0 --emit-fresh exits 0 on this branch
(fails with the two get diagnostics on origin/main).

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
briansrls pushed a commit that referenced this pull request Jul 5, 2026
…ed data rows, dedup dag_collect registry (GENERATED -> HAND-only) (#6262)

#6242 added // comments to dag_collect.dag / dag_collect_support.dag — .dag has no comment syntax since #5579, so the corpus stopped parsing (Slash diagnostic + 64 cascade errors: modules unresolved, json_quote/dag_node_key/is_module_shell_node not in scope) — and left v1_compiler_dag_collect{,_support}.rs in BOTH regen registries, which assert_registry_is_partitioned correctly fail-closes on. Both breaks were invisible: CI floor dark (10-min interim) and regen was already red from #6235/#6241 when #6242 merged.

- comments -> typed data rows (dag-no-comment convention), content preserved verbatim including both Dissolve-on markers
- registry dedup: dag_collect pair GENERATED->HAND-only (matches #6242's intent comment: hand-edited seed carries the Rc::as_ptr memo until grounded)
- .dag roster mirror (gunbc.stage0_emit_model) deduped to match; witness pin 92->90

Receipts (local; CI dark): regen self-compile 0 hard diagnostics (was 2-layer red: registry assert, then 65 diagnostics); --verify now reaches byte-compare and reds only on the PRE-EXISTING latent emitter drift (the 1667-error cutover backlog, tracked on the 5-regen-cutover carrier).

Co-authored-by: Brian Searls <briansearls1@gmail.com>
Co-authored-by: Claude Fable 5 <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