Conversation
…crate split Stage 1 no longer imports `plan_selection::candidate_selection`, and the legacy selection code no longer adds inherent methods to Stage 1 types, so Stage 1 can move into its own crate (#572 B2, decision Q42 (a)). - `GlobalSelection` and `TargetSubDAGSelection` move back into `replacement` with the DAG assembly (`assemble_*`): building a DAG from given choices is Stage 1 composition and needs no cost. Exact-composition plans are passed in by `GlobalSelection::new`. - `global_selection*` returns `CostedGlobalSelection`, which derefs to `GlobalSelection` and keeps the cost comparison behind each exact composition (`composition(target)`), formerly the `TargetSubDAGSelection::composition` field. - The `impl ReplacementSubDAG` / `impl CandidateLogicalASAPDAGs` blocks in `candidate_selection` become free functions (`cost_sorted`, `cost_sorted_with_recurrence`, `recurrence_profiles`, `global_selection`, `global_selection_with_recurrence`, `runtime_support_evidence`); callers across the workspace and docs are updated. - Stage 1 exposes what they need: read accessors `groups()`, `order()` and `composition_plans()`, and public `PreparedComposition`, `cse_candidate_pair`, `direct_child_counts`, `realize_child` and `ExactComposition::same_as`. - Selection assertions in Stage 1 test modules move to `candidate_selection` tests: four reconciliation tests and `global_selection_can_choose_nested_summaries` move whole; five mixed tests are split, adding three selection tests. Assembly tests move to `replacement`. Behavior is unchanged; the Example 1 fixture regenerates byte for byte. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Stage 1 of #509 (logical candidate generation) moves out of asap-aware-mapping into the new crate `asap-logical-optimizer` (`crates/logical-optimizer`), so Cargo enforces that Stage 1 depends on no later stage (#572, step B2). This is a pure move plus import updates. Layout: - `pass1/`: replacement, rewrite, rollup, grouping, exact_composition, function_rules, maintained_population, explanation, logical_candidates. - `pass2/`: topk_reuse, reconciliation (was `accuracy::reconciliation`). - `accuracy/`: the analytical model (mod, composition, allocation, evidence, estimators). `AccuracyModel` stays here for now; moving its pluggability to plan selection (Q22) is a later step. The new crate depends only on asap-types (plus asap_sketchlib, thiserror and serde_json); asap-aware-mapping, which keeps Stage 2, Stage 3 and the facade, depends on it. asap-aware-mapping no longer re-exports any Stage 1 item: every import across the workspace and docs now names `asap_logical_optimizer`. Files move with `git mv`, together with their tests (`tests/logical_candidates.rs`, the Stage 1 guard) and `test_support`; asap-aware-mapping keeps a trimmed copy of `test_support` for its own tests. The Stage 1 guard now scans every production file of the new crate and also checks that its manifest names neither asap-aware-mapping nor asap-physical-operators. Two candidate_selection tests build their fixture through public Stage 1 API instead of crate-private constructors. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 4, 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.
Why
#572 puts each #509 stage in its own crate so that Cargo enforces the one-way stage flow. This PR is step B2. Stage 1 (logical candidate generation) moves out of
asap-aware-mappinginto a new crate,asap-logical-optimizer. #582 left four blockers: Stage 1 importedplan_selection::candidate_selection, inherent impls on Stage 1 types lived in Stage 3, and the code relied onpub(crate)items. User decision Q42 (a) removes these first.What
Before this PR
After this PR
asap-logical-optimizerdepends only onasap-types,asap_sketchlib,thiserrorandserde_json. The PromQL front end is a dev-dependency used only by tests.cargo tree -p asap-logical-optimizer -e normal,dev,buildfinds neitherasap-aware-mapping,asap-physical-operatorsnorasap-planner. An import ofasap_aware_mappingfrom the new crate fails withE0433.How
Commit 1: remove the blockers inside
asap-aware-mapping(behavior unchanged)GlobalSelectionandTargetSubDAGSelectionmove back intoreplacement, together withassemble_*. Building a DAG from given choices is Stage 1 composition. Exact-composition plans are passed toGlobalSelection::new.CostedGlobalSelection.global_selection*now returns it. It derefs toGlobalSelectionand keeps the cost comparison behind each chosen exact composition incomposition(target). This replaces theTargetSubDAGSelection::compositionfield, which carried cost types.impl ReplacementSubDAG/impl CandidateLogicalASAPDAGsblocks incandidate_selectionbecome free functions:cost_sorted,cost_sorted_with_recurrence,recurrence_profiles,global_selection,global_selection_with_recurrenceandruntime_support_evidence. Callers are updated, for examplespace.global_selection(&m)becomesglobal_selection(&space, &m).groups(),order()andcomposition_plans();PreparedComposition, a record read by Stage 3, with public fields;cse_candidate_pair,direct_child_counts,realize_child(used bycost_model.rs) andExactComposition::same_as.candidate_selection: four reconciliation tests andglobal_selection_can_choose_nested_summaries.candidate_selectiontests.replacement.candidate_selectionmodule doc records that it is deleted under Pass 2 sharing and Stage 1 coverage parity with the retired MajorPass #580.Commit 2: create the crate (pure move)
git mv. 26 files move withgit mv, includingtests/logical_candidates.rs, the Stage 1 guard andtest_support.asap-aware-mappingkeeps a trimmedtest_support:lower_promql,agg,metric_scanandscan.cargo check, rewrote every import across the workspace toasap_logical_optimizer::…:asap-aware-mapping,asap-physical-operators, devtools, integration-tests, planner, the PromQL and SQL frontend tests, and docs.cost_model::/recurrence::. A new test checks that the manifest names neitherasap-aware-mappingnorasap-physical-operators.candidate_selectiontests now build their fixtures through public Stage 1 API (aTargetSubDAGCandidatesliteral,search_workload) instead of crate-private constructors.asap_aware_mapping::…now name the new path. They do not occur in any fixture.Moved files
asap-aware-mapping/logical-optimizer/src/{replacement, rewrite, rollup, grouping, exact_composition, function_rules, maintained_population, explanation, logical_candidates}.rssrc/pass1/*.rssrc/topk_reuse.rssrc/pass2/topk_reuse.rssrc/accuracy/reconciliation.rssrc/pass2/reconciliation.rssrc/accuracy/{mod, composition, allocation, evidence}.rs,src/accuracy/estimators/*(8 files)src/accuracy/…src/test_support.rssrc/test_support.rs(trimmed copy kept)tests/logical_candidates.rs,tests/stage1_cost_independence.rstests/…Volume
git mvand 5 new:Cargo.toml,lib.rs,pass1/mod.rs,pass2/mod.rsand the trimmedtest_supportcopyusestatements rewritten (131 after splitting mixed groups); 321 changed lines that cite old paths, including docsGate (at the tip)
cargo fmt --all --check: passes.cargo clippy --workspace --all-targets --all-features -- -D warnings: passes.cargo test --workspace: 1,528 passed, 12 ignored. refactor(planner): Stage 1 no longer depends on the cost model #582 had 1,524. Commit 1 adds 3 tests by splitting mixed Stage 1 and selection tests (1,527). Commit 2 adds the manifest guard.python3 -m unittest discover -s tools/dag-viewer -p test_render.py: 29 tests OK, 6 skipped.stage_pipeline --example planner-layering-1regeneratestools/dag-viewer/examples/planner-layering-example1.jsonbyte for byte, at both commits.Remaining items (B3–B5)
Q22: move
AccuracyModelpluggability to plan-selection. The trait stays inlogical-optimizer/src/accuracy/mod.rs:37for this pure move. Stage 1's legacy search still takes it:replacement.rs:1173,:1223,:1238and:4943(search_workload_with_targets);grouping.rs:141;exact_composition.rs:217.The stage pipeline's Stage 1 entry,
enumerate_local_logical_candidates(logical_candidates.rs:100), does not take it.PlanningModels.accuracy(plan_selection/mod.rs:83) imports the trait from Stage 1, which is a legal direction.Legacy selection (Pass 2 sharing and Stage 1 coverage parity with the retired MajorPass #580).
candidate_selectionuses the raw-pointer accessors andPreparedComposition. Deleting it under Pass 2 sharing and Stage 1 coverage parity with the retired MajorPass #580 lets B4 avoid moving it.B3 (physical-optimizer).
physical_candidatesimports onlyasap-typesand Stage 1. Its test uses thetest_supportcopy (physical_candidates.rs:156), so B3 needs its owntest_supportcopy and a frontend-promql dev-dependency. Stage 3 imports Stage 2 atplan_selection/mod.rs:45, which is a legal direction.B4 (plan-selection). Its tests use the same
test_supportcopy (plan_selection/mod.rs:1014,candidate_selection.rs:1359).pane_sharing,erpandempirical_comparisonare still present, although Reorganize crates and modules by #509 stages and the #511 unified IR #572 marks them for deletion.B5 (executor). The
asap-physical-operatorsunit test atphysical_planner/candidates.rs:367-370and four integration tests call the legacyglobal_selectionthrough dev-dependencies. They follow Pass 2 sharing and Stage 1 coverage parity with the retired MajorPass #580.Part of #509 and #572 (B2). Follows #582. Related: #580.
🤖 Generated with Claude Code