Skip to content

Reorganize by stage: one memo-based Pass 2, Stage 1 finishes the memo, deployment inputs split by stage, asap-planner as the only entry point #958

Open

Description

@zzylol

Problem, by example

crates/logical-asap-optimization/src (Stage 1) is hard to navigate, and part of it is not Stage 1. All facts below are from main and the #952 branch head 7faad601.

1. Pass 2 is implemented twice.

Path Files Callers
(A) whole-workload: rewrite one chosen computation assignment, enumerate every non-empty subset of sharing choices asap_aware_cse.rs (4633 lines: identical_expression_pass2_candidates, summary_capability_pass2_candidates, window_composition_pass2_candidates, rollup_pass2_candidates, topk_reuse_pass2_candidates), workload_candidates.rs (Pass2Candidate) non-test: plan-selection/src/search/query_pruning.rs, search/pipeline.rs (type only), devtools candidate_labels.rs / planning_stages.rs, and the memo files memo/window_candidates.rs, memo/rules/{rollup,scan_labels,state_configurations,topk}.rs; test-only: plan-selection/src/lib.rs, costing/{direct_profile,lower_bounds,direct_price_options_tests,range_price_options_tests}.rs, physical-asap-optimization/src/lib.rs, memo/state_groups.rs and integration tests
(B) memo: each rule adds implementation candidates to memo groups memo/, memo/rules/* plan-selection/src/search/candidates/inventory.rs and the memo search

On main, plan-selection reaches (A) outside tests in only one place: prune_query_candidates (search/query_pruning.rs), called from route.rs, checks each query's own candidates alone before the joint search through stage1_candidates_of_choice. Every Stage 1 → 3 entry point (run_stage1_to_stage3, _with, _from_pass1) runs the memo search (run_with_initial_memo → candidate_connection_search). Pass2Candidate survives only as the type of LogicalCandidate::pass2, which the memo run leaves empty, and in devtools labels. The other plan-selection references (lib.rs, direct_profile.rs, lower_bounds.rs, direct_price_options_tests.rs, range_price_options_tests.rs), and physical-asap-optimization/src/lib.rs, are all in #[cfg(test)] code. So deleting (A) means giving per-query pruning a memo-based check.

(B) also calls (A) as a library, in five non-test memo files. memo/rules/rollup.rs builds a two-root workload and calls rollup_candidate_for and rollup_pass2_candidates. memo/window_candidates.rs calls pane_candidates and window_composition_pass2_candidates, so local pane candidates enumerate every subset of a candidate's pane builds (capped at MAX_PANE_CANDIDATES = 20). memo/rules/scan_labels.rs calls with_union_scan_labels, memo/rules/state_configurations.rs calls with_pane_chain and with_resized_build, and memo/rules/topk.rs calls topk_reuse_candidates. The full mapping is in the step 3 comment below. (A)'s subset enumeration is capped at MAX_REUSE_CANDIDATES = 20, about a million subsets. The memo is the intended search structure.

2. Stage 3 finishes Stage 1's output. memo/state_groups.rs ("opt-in concrete summary-state groups for the candidate-connection planner"), memo/state_configurations.rs, memo/window_candidates.rs and memo/rules/state_configurations.rs expand concrete sizes and pane grids into state groups. For example, readers needing KLL k ≥ 345 and k ≥ 200 get concrete KLL(345) and KLL(200) groups. Only plan-selection calls expand_concrete_summary_state_groups. So the memo that Stage 1 hands over is incomplete, and Stage 3 completes it with Stage 1 functions.

3. One deployment input serves three stages from the Stage 1 crate. deployment_capabilities.rs defines DeploymentCapabilities. Each field is read by a different stage:

  • supported_summaries: Stage 1, Pass 1;
  • query_time_results_retained: Stage 2;
  • raw_data_retained: Stage 3.

Stage 2 and Stage 3 import it from the Stage 1 crate.

4. The Stage 3 crate orchestrates the planner and defines its public API. asap-plan-selection holds four different things:

Content Where Belongs to
Stage 3 itself: search, cost models, accuracy check search/ (milp, refinement, costing, candidates), cost/, accuracy.rs plan-selection
The pluggable-pass API that ASAPQuery-backend and ASAPCollector read: OptimizationPass, optimize(), check_contract search/mod.rs the facade
Stage 1 → 3 orchestration: Stage1ToStage3Pass, run_stage1_to_stage3 search/pipeline.rs the facade
The bundle of deployment inputs: PlanningModels, including DeploymentCapabilities and the executor compile check search/mod.rs assembled by the facade; each stage receives only its own part

asap-planner, the facade, only runs the frontends and builds the installable plan (InstallablePlan, PlannerExecutorCompileCheck). Callers that already hold IR skip it and call asap_plan_selection::optimize directly.

5. There is no stage structure inside the crate.

  • Pass 1 is one 6154-line file (per_computation_candidates.rs), plus realization.rs and function_rules.rs. function_rules.rs is an accuracy composition rule.
  • Pass 2 is spread over asap_aware_cse.rs, workload_candidates.rs, memo/rules/* and a top-level finer_aggregate.rs.
  • Two files are named state_configurations.rs (memo/ and memo/rules/), and rollup exists both in memo/rules/rollup.rs and in asap_aware_cse.rs.

The layout approved in #572 (pass1/, pass2/, analytical accuracy/) was never applied to this crate.

Decisions (2026-10-27)

  1. One Pass 2. Map every capability of (A) to (B): delete what (B) already implements, port what it does not, then delete (A) (workload_candidates.rs, the *_pass2_candidates subset enumerations and their plan-selection callers). The mapping table goes in the PR body, so a capability is deleted only when it has a memo implementation or an issue.
  2. Stage 1 finishes the memo. Expanding concrete sizes and pane grids is Pass 2 output: the coupling sites and their thresholds, as the docs: propose workload-wide planning, summary sharing, and materialization #509 design doc describes. Stage 1 runs it, and Stage 3 receives a complete memo and only selects. The expansion API stops being called from plan-selection.
  3. Deployment inputs split by stage. Each stage crate owns the field it reads: Stage 1 the supported summaries, Stage 2 query-time result retention, Stage 3 raw-data retention (RawRetention in Retained raw data as concrete state groups per lookback: offsets, @ and a retention limit #955). The DeploymentCapabilities bundle, which parses --deployment-capabilities and dispatches the fields, moves to the asap-planner facade, which already depends on every stage. asap-types stays shared types only.
  4. asap-planner is the only entry point; asap-plan-selection is only Stage 3.
    • asap-planner owns:
      • the frontends;
      • OptimizationPass and optimize() with the output-contract check;
      • Stage 1 → 2 → 3 orchestration;
      • assembling the deployment inputs and dispatching them to the stages;
      • the installable plan and the executor compile check.
    • asap-plan-selection takes the complete memo from Stage 1 (decision 2) and only the inputs Stage 3 reads: cost settings, accuracy model, evidence, raw-data retention, and the compile-check trait. It returns the selection and no longer calls Stage 1.
    • It may still call Stage 2 per candidate. Lazy physicalization keeps the search scalable.
  5. No compatibility layer for the moved API. The PR that moves OptimizationPass / optimize() changes their import paths. It comes with a follow-up PR in ASAPQuery-backend and in ASAPCollector that updates their imports. No temporary re-export is left in asap-plan-selection.

Target layout

crates/logical-asap-optimization/src/
  lib.rs
  accuracy/                analytical rules (as today) + function_rules.rs
  pass1/                   per_computation_candidates.rs split by concern
                           (targets, candidates, composition/guarantees), realization.rs
  pass2/
    memo/                  groups.rs, candidates.rs
    rules/
      shared_producer.rs   identical expression, summary capability, top-k reuse, panes, ranks (#954)
      finer_aggregate.rs   rollup and compensating filters (#950)
      shared_scan.rs       replaces scan_labels.rs (#951)
      structural.rs        summary_inputs, summary_results (factor private nodes into groups)
    sites.rs               concrete sizes and pane grids (decision 2)

maintained_population.rs is deleted by the open population-rule PR (#681 tracks the capability). deployment_capabilities.rs leaves the crate (decision 3).

Plan (one concern per PR)

The first PR waits for #952, the #951 PR and the #954 PR to merge, because they edit these files. #572's rule holds: a move PR moves code and changes nothing else.

  1. Move only: pass1/, pass2/, accuracy/function_rules.rs, pass2/rules/finer_aggregate.rs. Rename the duplicate state_configurations.rs files by role.
  2. Split deployment inputs by stage; the bundle goes to asap-planner (decision 3).
  3. Map (A) → (B) in a table; port what is missing into memo rules, each with a failing-first test.
  4. Delete (A) and switch its plan-selection callers to the memo (decision 1).
  5. Stage 1 runs the state expansion; plan-selection takes the expanded memo (decision 2).
  6. Move orchestration and the public API to asap-planner (decision 4). This includes pipeline.rs, OptimizationPass / optimize() and the PlanningModels assembly, and switches stage_pipeline, devtools and tests that call asap_plan_selection::optimize to the facade. It comes with the follow-up PRs in ASAPQuery-backend and ASAPCollector (decision 5). It depends on steps 2, 4 and 5, after which plan-selection no longer calls Stage 1.
  7. Split per_computation_candidates.rs inside pass1/ (move only).

Acceptance for every PR:

  • the same selected plans and costs on the existing integration suites;
  • for move PRs, a diff that moves code and changes nothing else.

Related

#572 (crate layout by stage), #954 (shared-producer rule), #950 (finer-aggregate reuse), #951 (shared scan), #955 (raw horizon), #681 (maintained population), the design doc of #509.

Activity

  1. changed the title [-]Reorganize Stage 1 by pass: one memo-based Pass 2, Stage 1 finishes the memo, deployment inputs split by stage[/-] [+]Reorganize by stage: one memo-based Pass 2, Stage 1 finishes the memo, deployment inputs split by stage, asap-planner as the only entry point[/+] on Oct 27, 2026
  2. zzylol commented on Oct 27, 2026

    @zzylol
    ContributorAuthor

    Step 3: mapping of the whole-workload Pass 2 to memo rules

    All facts are from origin/main at 6a22ec49 (after #959), read from the code. (A) is asap_aware_cse.rs (4541 lines) plus workload_candidates.rs (556 lines). (B) is memo/ and memo/rules/*.

    Summary

    • Every (A) capability has a memo implementation. No capability was found missing; all five rules are covered. (A) differs from (B) in how it enumerates, not in what it can express. Code reading does not prove coverage, so the first step-4 PR adds a differential test (PR 1 below).
    • (B) still depends on (A) in non-test code in five memo files, not only rollup.rs:
      • memo/window_candidates.rs
      • memo/rules/rollup.rs
      • memo/rules/scan_labels.rs
      • memo/rules/state_configurations.rs
      • memo/rules/topk.rs
    • memo/window_candidates.rs reuses (A)'s subset enumeration. For each Pass 1 candidate it calls window_composition_pass2_candidates, which lists every non-empty subset of that candidate's pane candidates (2^n, capped at MAX_PANE_CANDIDATES = 20). This is the one place where the memo inherits (A)'s exponential enumeration and its cap.
    • Outside memo rules, (A) is reached in non-test code through three paths:
      • prune_query_candidates → alone_violation → stage1_candidates_of_choice (plan-selection/src/search/query_pruning.rs);
      • the type LogicalCandidate::pass2 (search/pipeline.rs), which production always sets to None (pipeline.rs:281, route.rs:936, route.rs:949);
      • devtools candidate_labels.rs / planning_stages.rs, which label pass2 and so only label test-built candidates.
    • References that are test-only: plan-selection/src/lib.rs, costing/direct_profile.rs, costing/lower_bounds.rs, physical-asap-optimization/src/lib.rs and the (A) uses in memo/state_groups.rs all sit in #[cfg(test)] modules.

    1. Inventory of (A)

    Classes:

    • (i) whole-workload enumeration, deleted in step 4;
    • (ii) a rewrite or helper that (B) uses, moved into pass2/rules/;
    • (iii) used only by tests, devtools or other (A) items.
    Item Class Used outside (A) by (non-test / test)
    workload_candidates::stage1_candidates_of_choice (+ private choice_candidates, pass2_candidates, Pass2List, Rules) (i) non-test: query_pruning.rs alone_violation. test: integration-tests/src/lib.rs explicit_assignment_plans
    Pass2Candidate (i) non-test: pipeline.rs (LogicalCandidate::pass2, always None in production), devtools candidate_labels.rs pass2_label, planning_stages.rs re-export. test: reuse_rules.rs. Docs: develop_docs/asap-aware-mapping-*.md, extend-asap-aware-mapping.md
    Stage1Candidate (i) docs only
    identical_expression_pass2_candidates, IdenticalExpressionPass2Candidate (i) none
    sharing_candidates, SharingCandidate, with_shared_candidates (i)/(iii) non-test: devtools candidate_labels.rs. test: direct_profile.rs, planner_layering_example1–3, reuse_rules, rollup_controlled, planner/tests/summary_sharing.rs, devtools/tests/stage_pipeline.rs
    summary_capability_pass2_candidates, capability_sharing_candidates, SummaryCapabilityPass2Candidate, CapabilitySharingCandidate, MAX_CAPABILITY_SHARING_MEMBERS (i) test: planner_layering_example2.rs
    window_composition_pass2_candidates, WindowCompositionPass2Candidate, MAX_PANE_CANDIDATES (i), but used by (B) non-test: memo/window_candidates.rs local_pane_candidates_delta. test: memo/state_groups.rs, plan-selection lib.rs, direct_profile.rs, lower_bounds.rs, direct_price_options_tests.rs, range_price_options_tests.rs, physical-asap-optimization/src/lib.rs, nine integration test files (deployment_capabilities, planner_layering_*, range_evaluation, sql_trailing_window, sql_two_percentiles, tumbling_pane_merge)
    window_composition_shared_chain_candidates, SharedPaneChain (ii)/(iii) test: memo/rules/rollup.rs tests, tumbling_pane_merge.rs
    pane_candidates, PaneCandidate (+ window_ms) (ii) non-test: memo/window_candidates.rs, devtools candidate_labels.rs. test: same list as window_composition_pass2_candidates, plus memo/rules/rollup.rs tests
    with_pane_chain (ii) non-test: memo/rules/state_configurations.rs
    with_resized_build (ii) non-test: memo/rules/state_configurations.rs. test: memo/state_groups.rs
    with_union_scan_labels (ii) non-test: memo/rules/scan_labels.rs. test: devtools/tests/stage_pipeline.rs
    topk_reuse_candidates, TopKReuseCandidate (ii) non-test: memo/rules/topk.rs, devtools candidate_labels.rs. test: reuse_rules.rs
    topk_reuse_pass2_candidates, TopKReusePass2Candidate (i) none
    rollup_candidate_for, RollupCandidate (ii) non-test: memo/rules/rollup.rs
    rollup_pass2_candidates, RollupPass2Candidate (i), but used by (B) with one rule non-test: memo/rules/rollup.rs (a two-root workload, one rule, so one subset). test: rollup_controlled.rs
    rollup_candidates (iii) non-test: devtools candidate_labels.rs. test: reuse_rules, rollup_controlled, sketch_rollup_planning
    rollup_choices, rollup_kind, may_change_rollup_candidate, MAX_REUSE_CANDIDATES (i), internal none

    2. Capability mapping

    (A) capability (A) entry Memo implementation Memo-path evidence Differences
    Identical expression identical_expression_pass2_candidates, sharing_candidates Memo group identity: LogicalMemo::from_roots interns equal nodes as one group (memo/groups.rs); ir::cse groups.rs test identical_sub_expressions_of_two_queries_are_one_group (A) lists each subset of shared nodes as a candidate; the memo always shares, and plan selection picks per group
    Union scan labels with_union_scan_labels, in Pass2List::identical_expression (widened) memo/rules/scan_labels.rs add_scan_label_candidates (calls with_union_scan_labels) state_groups.rs tests disjoint_scan_labels_share_a_union_pane_state_with_typed_readers, general_source_groups_offer_typed_union_scan_readers, scan_label_widening_keeps_different_filters_separate (A) lists widened candidates last for tie-breaking; the memo adds widened readers as extra candidates
    Summary capability (shared sizes) summary_capability_pass2_candidates (subsets of ≤ 20 members) memo/rules/state_configurations.rs SummaryStates, StateCovering::Size, via shared_producer.rs shared_producer_snapshot.rs shared_size_candidates_are_unchanged; state_groups.rs quantile_readers_share_concrete_state_and_retain_local_candidates, distinct_sizes_gain_compatible_shared_configurations; integration sql_two_percentiles (A) enumerates subsets of builds; the memo gives each reader one candidate per covering size (state_size_configurations), so partial sharing comes from per-reader choice. No member cap
    Window composition, local panes pane_candidates + window_composition_pass2_candidates memo/window_candidates.rs add_local_window_composition → local_pane_candidates_delta, which calls the (A) functions window_candidates.rs tests incremental_local_widths_match_one_complete_pass, reader_grids_include_subsets_instead_of_only_full_union; integration tumbling_pane_merge Same code. The memo inherits the 2^n subsets of one candidate's pane builds and the MAX_PANE_CANDIDATES cap; when it is exceeded, Err is silently skipped (let Ok(..) else continue)
    Window composition, shared chains push_every_shared_chain inside window_composition_pass2_candidates (nested and gcd grids) state_configurations.rs StateCovering::Panes (pane_configurations_before, with_pane_chain) shared_producer_snapshot.rs shared_pane_candidates_are_unchanged; state_groups.rs different_pane_grids_and_horizons_gain_explicit_newest_pane_readers, identical_local_pane_chains_share_state_without_removing_local_choices (A) offers only "every build of the subset on one grid"; the memo offers each reader every serving configuration of a PaneWidthDomain
    Rollup (exact values, sketch states) rollup_candidates + rollup_pass2_candidates (subsets of choices, ≤ 20) memo/rules/rollup.rs add_rollup_candidates (pairs of groups; calls rollup_candidate_for + rollup_pass2_candidates with one rule); add_window_rollup_candidates; filtered_group.rs (being replaced by #952) state_groups.rs exact_rollup_exposes_shared_finalized_values, sketch_rollup_exposes_shared_finer_state, grouped_window_rollup_exposes_one_finer_chain; integration production_rollup_workloads The memo checks pairs, one rule at a time; a coarse group can gain several finer producers
    Exact top-k reuse topk_reuse_candidates + topk_reuse_pass2_candidates (subsets) memo/rules/topk.rs TopKRankings via shared_producer.rs state_groups.rs topk_outputs_share_explicit_exact_ranking; shared_producer_snapshot.rs top-k tests (A) enumerates subsets of readers; the memo adds one derivation per reader
    Rule combinations (capability, then panes, then reuse, then identical) pass2_candidates applies the rules in sequence to one assignment Rules run in sequence over one memo (state_groups.rs:102–109: scan labels → summary inputs → top-k → filtered group → rollup → window rollup → summary results → state configurations); combinations arise from per-group choices state_groups.rs multiple_private_states_can_share_only_the_common_producer Not one-to-one; covered by the differential test below

    (B) only: summary_inputs.rs and summary_results.rs (factoring private nodes into groups), filtered_group.rs.

    Integration tests that exercise (A), not (B):

    • through explicit_assignment_plans / explicit_rule_plans: reuse_rules, rollup_controlled, sketch_rollup_planning, promql_to_post_asap;
    • by calling the (A) functions directly: planner_layering_example1–3 and the window tests above.

    Their assertions are about rule semantics: a reused plan answers like the original. Before deletion they need to read the candidate from the memo instead.

    3. Callers outside (A) and their replacement

    Caller What it uses After deletion
    plan-selection/src/search/query_pruning.rs alone_violation (from prune_query_candidates ← route.rs:767) stage1_candidates_of_choice on a one-query inventory: the composed candidate and its single-query Pass 2 candidates ("the rules a single query can apply, such as window composition"), each through Stage 2 and the checks Build the one-query memo (LogicalMemo::from_roots → try_populate_pass1 → add_local_window_composition, plus the memo rules if needed) and check the candidates of the root group's closure for that choice. The pruning question is "does any implementation of this choice pass alone", so the memo's local candidates are the right set
    search/pipeline.rs LogicalCandidate::pass2: Option<Pass2Candidate> type only; production writes None Delete the field and its readers (devtools labels, integration-tests/src/lib.rs, reuse_rules.rs)
    devtools candidate_labels.rs (pass2_label, same_pane_chain), planning_stages.rs re-export labels pass2; PaneCandidate Delete with the field; memo candidates are labeled by CandidateOrigin
    memo/window_candidates.rs local_pane_candidates_delta pane_candidates, window_composition_pass2_candidates (all subsets) Move pane_candidates and the rewrite of one chosen set (in_panes, push_every_shared_chain) into pass2/rules/. Decide whether local candidates need every subset or one per pane candidate (behavior change: own PR, failing-first test)
    memo/rules/rollup.rs add_rollup_candidates rollup_candidate_for, rollup_pass2_candidates with one rule Move both; reduce rollup_pass2_candidates to the single-rule rewrite it is used as. #952 also edits this file, so this waits for it
    memo/rules/scan_labels.rs with_union_scan_labels Move
    memo/rules/state_configurations.rs with_pane_chain, with_resized_build Move
    memo/rules/topk.rs topk_reuse_candidates Move
    integration-tests/src/lib.rs explicit_assignment_plans and its tests stage1_candidates_of_choice Port the assertions to memo candidates (select by CandidateOrigin), or delete the tests whose behavior the memo-path tests already cover
    Test-only modules: plan-selection lib.rs, direct_profile.rs, lower_bounds.rs, direct_price_options_tests.rs, range_price_options_tests.rs, physical-asap-optimization/src/lib.rs, memo/state_groups.rs, nine integration test files, planner/tests/summary_sharing.rs, devtools/tests/stage_pipeline.rs rewrite helpers to build fixtures Switch to the moved helpers (the paths change, the functions stay). Where a test needs a whole-workload rewrite, build it from the memo
    Docs: develop_docs/asap-aware-mapping-architecture.md, asap-aware-mapping-contracts.md, extend-asap-aware-mapping.md describe (A) Update with the deletion

    4. Proposed PRs for steps 3–4 (one concern each)

    1. Differential test (test only). For each workload in reuse_rules, rollup_controlled, sketch_rollup_planning, planner_layering_example1–3 and tumbling_pane_merge: the memo search's selected cost is ≤ the cheapest (A) plan from explicit_assignment_plans. Any failure is a missing port and becomes its own failing-first PR.
    2. Move the (ii) helpers (move only). Move with_pane_chain, with_resized_build, with_union_scan_labels, topk_reuse_candidates, rollup_candidate_for, pane_candidates and the one-set pane rewrite into pass2/rules/ next to their memo rule. Switch the test fixtures' imports. Best done after step 1 (refactor(optimizer): move Stage 1 modules into pass1/ and pass2/ (#958 step 1) #960) and after feat(optimizer): reuse a finer aggregate through a compensating filter and a rollup of values or states #952 merges, since feat(optimizer): reuse a finer aggregate through a compensating filter and a rollup of values or states #952 edits rollup.rs.
    3. Memo-based per-query pruning. Replace stage1_candidates_of_choice in alone_violation with a one-query memo, using a failing-first test that compares pruned sets on the existing pruning tests. This is the only production use of (A).
    4. Port the (A)-path integration tests to memo candidates. Port reuse_rules, rollup_controlled, sketch_rollup_planning, promql_to_post_asap and explicit_assignment_plans.
    5. Delete (A).
      • Delete workload_candidates.rs, the *_pass2_candidates enumerations, rollup_choices, the MAX_* caps, LogicalCandidate::pass2, devtools pass2_label, and the docs sections.
      • The PR body carries the table above as the deletion map (each row: deleted, or moved to pass2/rules/<file>).
    6. (Optional, behavior change) Local pane candidates without subset enumeration. window_candidates.rs stops listing all 2^n subsets per candidate if per-group choice already covers them. This needs a failing-first or equal-cost test, so it is kept out of the deletion.
  3. zzylol commented on Oct 27, 2026

    @zzylol
    ContributorAuthor

    Correction to the step 3 comment above. It said every whole-workload capability has a memo implementation. That came from reading code only. Running both paths on the same workloads (PR #975) shows three cases where the memo search's plan costs more:

    Case Whole-workload cost/s Memo cost/s Cause
    shared sizes 2.4145834 3.2787667 Search miss. The memo holds the plan, but its query-time KLL has lower bound 0 (#963).
    rollup 0.0126783 0.0137854 Coverage gap. Two identical finalize nodes, so the shared finalized rows cannot be stored once (#979).
    exact top-k reuse 0.7756417 0.7800940 Coverage gap, same pattern. Two identical Limit(10) nodes instead of one shared Limit(10) ▸ Sort (#979).

    Identical expression, union scan labels, local panes, shared pane chains and Example 1 match.

    Step 4 (deleting the whole-workload path) waits for #979 and for the shared-sizes case. Each is pinned as an ignored test in memo_covers_whole_workload_pass2.rs.

  4. zzylol commented on Oct 29, 2026

    @zzylol
    ContributorAuthor

    Stage-boundary types and renames decided 2026-10-29: #1047 (Pass 2 ends with shared summary-state groups; the Stage 2 inventory moves out of plan-selection).

  5. zzylol commented on Oct 29, 2026

    @zzylol
    ContributorAuthor

    Decided 2026-10-29 in #1047: stages and passes never call each other's functions; each reads only the previous step's output type, and the asap-planner facade runs the stages in order (including pane-width rounds and rebuilding the selected DAG). This overrides decision 4's "plan selection may call Stage 2 per candidate". The code moves out of asap-plan-selection are tracked here.

  6. zzylol commented on Oct 29, 2026

    @zzylol
    ContributorAuthor

    Crate organization across all crates is now tracked in #1054, decided 2026-10-29:

    • Stage crates never depend on each other; stage-boundary types live in asap_types::stages.
    • New shared crates asap-accuracy and asap-cost.
    • All sizing is done in Stage 1.
    • Stage 3 reaches Stage 2 only through a realizer trait injected by the facade.
    • A CI cargo metadata graph check, and visibility rules per crate.

    #1054 extends this issue's decisions 3–4. This issue's Stage 1-internal layout and steps still apply inside asap-logical-asap-optimization.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    optimizerWorkload optimization and plan selectionrefactor

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions