Skip to content

test: #509 Examples 2–4 acceptance specs and end-to-end tests - #590

Closed
zzylol wants to merge 76 commits into
stack/509-e2-keyed-additive-topkfrom
stack/509-acceptance-examples-2-4
Closed

zzylol wants to merge 76 commits into
stack/509-e2-keyed-additive-topkfrom
stack/509-acceptance-examples-2-4

Conversation

@zzylol

@zzylol zzylol commented Oct 4, 2026

Copy link
Copy Markdown
Contributor

Why

#509 defines four end-to-end examples. Only Example 1 had an acceptance spec and tests. AGENTS.md asks for acceptance behavior to be defined before implementation, and by someone other than the implementer. This PR does that for Examples 2–4, ahead of the Stage 2 materialization and #580 work (window composition, the summary-capability rule, Hydra).

What

  • Acceptance specs: docs/design_docs/proposals/planner-layering-example{2,3,4}-acceptance.md. Each lists the per-stage candidate expectations taken from docs: propose workload-wide planning, summary sharing, and materialization #509, the invariants under test, and the places where the doc is ambiguous or conflicts with today's planner.
  • Tests: crates/integration-tests/tests/planner_layering_example{2,3,4}.rs, using the real plan_stages.
  • Shared adapters in tests/planner_layering_common/mod.rs (window_form, materialization, retention_ms) return today's only possible answer. The implementer of each feature fills them in.
  • Devtool examples --example planner-layering-3a / 3b. Example 1's output is byte-identical.

Before / After

Findings for the implementers

These are also listed in the specs.

Written as an independent test design; the agent implemented no planner features. Base: #589. Links: #509, #580, #572.

🤖 Generated with Claude Code

zzylol and others added 30 commits October 3, 2026 15:59
…ts fields

Name the metadata coverage to match #560 and the docs; drop the single-variant
multiplicity and deployment-specific revision; rename grouping to reduction to
match SummaryAgg; report failures through SchemaDerivationError::Coverage; revert
the unrelated PaneCoverageError rename.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…me bounds

validate_structure rejects a SummaryAgg without coverage (CoverageError::Missing).
CoverageRegion time bounds become optional so tabular sources without a time
column can declare coverage. Population stays trusted; #570 tracks checking it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Given required coverage on summary nodes, input and reduction duplicated the
producing SummaryAgg fields; drop them along with ProducerMismatch. Type source
as Source, matching Scan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SourceCoverage names the rows a physical scan reads for cost comparison, not
which observations a summary state holds; rename it so it is not confused with
SummaryCoverage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move it to docs/design_docs/proposals with problem and motivation,
requirements, design, alternatives and key code interfaces.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…tive schema design

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The design document and the docs it consolidates are reviewed separately on
main. This PR keeps code, tests and the ScanSelection rename in docs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…coverage examples

SummaryCoverage no longer repeats input/reduction, so SummaryMerge compares
them through OperatorNode::summary_update. summary_coverage_examples.rs builds
each example in docs/develop_docs/summary-coverage.md as a SummaryAgg ->
SummaryMerge plan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… doc

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A workload DAG has one root per batch query; queries that share a sub-DAG
reference the same exported nodes. Single-query export is a batch of one.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The logical export is phase-free. Physical planning still needs the lifecycle
timing expansion; bring it back unchanged except for carrying coverage.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
zzylol and others added 14 commits October 4, 2026 01:29
Move the cost- and recurrence-dependent selection over
`CandidateLogicalASAPDAGs` (cost ranking, recurrence profiles, global
selection, selected-DAG assembly, runtime support evidence) and its tests
from `replacement` into `plan_selection::candidate_selection`. The code
is unchanged; only visibility and imports were adjusted.
`plan_selection.rs` becomes `plan_selection/mod.rs`.

`recurrence_profiles_from_workload` is deleted rather than moved: it has
no caller anywhere in the workspace.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…t model

`realizations_for_intent` lists sketch candidates in `summary_candidates`
order and sizes them with the analytical `accuracy::estimators::size_params`,
which is what `CostModel::size_params` defaulted to. Extension intents stay
PassThrough, the previous default.

- `CandidatePlanningInputs` drops its `cost` field; `realize_child` drops its
  cost argument.
- `ASAPStrategies` and `HydraGroupingStrategy` are built with `default()`
  or `new_with_planning_inputs*` without a cost model; `ASAPStrategies::new`,
  the `default_cost_model` constructors and `default_strategies_with` are
  removed, and `default_strategies_with_evidence` takes only the evidence.
- `ExactCompositionStrategy` is a unit struct and no longer checks runtime
  support; selection already requires positive support evidence.
- `CostModel` loses `size_params`, `realize_extension` and
  `evaluation_extension`.

Tests that exercised only the removed hooks are deleted; call sites across
the workspace use the new constructors.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Scans the Stage 1 modules' non-test code and fails on any import of
`cost_model` or `recurrence`, including names `lib.rs` re-exports from them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Update the developer docs and the `CostModel` trait doc: strategies take no
cost model, sketch sizing is analytical, extension intents stay
pass-through, and the cost model is consulted only at selection.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…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>
Move asap-aware-mapping's physical_candidates into the new
asap-physical-optimizer crate (implementation/physical_candidates.rs), with
a trimmed test_support copy. Production code depends only on asap-types; a
new manifest guard rejects plan-selection, aware-mapping and
physical-operators. Imports are rewritten without compatibility
re-exports. Pure move (#572, B3).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move asap-aware-mapping's Stage 3 modules into the new asap-plan-selection
crate: the cost model and its inputs under cost/, plan_selection/mod.rs as
the crate root (select_plan, PlanningModels) and candidate_selection, with
their tests and the test_support copy. Delete pane_sharing, erp and
empirical_comparison, which have no callers (#572), and the
snapshot_prepare_cpu helper only empirical_comparison used. A manifest
guard rejects the facade and executor. Imports are rewritten without
compatibility re-exports (#572, B4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…asap-aware-mapping

Move asap-aware-mapping's pass/ (OptimizationPass, StagePipeline,
PassRegistry, optimize) into crates/planner, the facade per #572, and
remove the now-empty asap-aware-mapping crate from the workspace.
PlanningModels is re-exported by the planner from asap-plan-selection.
The stage manifest guards now name asap-planner instead of the deleted
crate. Docs and comments that cited asap-aware-mapping as a crate now
name the stage crate that owns the code (#572, B4b).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…-executor crate

Rename crates/asap-physical-operators to crates/executor (package
asap-executor), keeping plan/ and physical_planner/ in it as #572's
2026-10-03 update decides. Imports are rewritten without compatibility
re-exports. The three stage manifest guards now reject asap-executor;
only integration-tests depends on it (#572, B5).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…variant

Stage 1 now keeps two forms of the workload (#509 Pass 2): the queries as
written, and, when CSE merges something, the queries with identical
sub-DAGs shared. Stage 3 treats the variant as an outer choice: the
per-target dynamic program runs once per variant (the coupling guard also
checks targets reading a common input in the shared variant) and the
cheapest result wins.

plan_selection::plan_stages runs Stage 1 -> 2 -> 3; the facade and the
stage_pipeline devtool both call it, so the facade no longer pre-merges
and the devtool shows the shared variants.

A PromQL series has one sample per timestamp, so the identified scan now
declares (series identity, ts) as a key, which CSE's legality rule needs
to share the range selector.

Example 1: 1 -> 48 -> 48 -> 1; P44 (P20's choices over a shared input)
is selected at 52.201 vs 79.401.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Pass 1 now offers, for a top-k over a per-item sum or count whose inner
aggregate has no other consumer, Count-Min and CountSketch + heap
alternatives that read the inner aggregate's input and absorb it (the
legacy keyed-additive rule decides applicability and the update). For
#509 Example 1's Q2 that is one heap per job over the raw samples, keyed
by series identity and weighted by the sample value.

An absorbed target has no choice of its own: enumeration skips its
choices, choice_index ranks in that order, and the tree DP sums only the
targets an alternative still reads (read_targets) and sets the absorbed
target to its pass-through. Top-k readout rows are bounded by the series
count, so a sketch reading several samples per item is sized like the
other realizations (the coupling guard caught the difference).

Example 1: 1 -> 64 -> 64 -> 1; P58 (all exact, shared input) at 52.201;
the best whole-expression CountSketch + heap plan, P64, costs 537.201.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Independent test design for the summary-capability rule (Example 2),
the window-composition rule (Example 3) and Stage 2 materialization
(Example 4). Each spec extracts the doc's per-stage candidates, lists the
invariants and their tests, and records ambiguities and conflicts with
today's planner.

Tests run plan_selection::plan_stages. Behavior that works today passes
(33 tests); tests that need a missing feature are ignored with the
feature's name (25). Window summaries, materialization and retention are
read through pending adapters in tests/planner_layering_common, for the
implementers to fill in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds --example planner-layering-3a (Pattern A, sub-interval batch) and
planner-layering-3b (Pattern B, repeating 5-min p99), matching the
Example 3 acceptance tests' workloads. Example 1's output is unchanged.
Examples 2 and 4 need planner changes first; their specs list them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@zzylol
zzylol force-pushed the stack/509-e2-keyed-additive-topk branch 4 times, most recently from 861c2ec to f08bd19 Compare October 11, 2026 17:11
zzylol added a commit that referenced this pull request Oct 13, 2026
The specs and tests from #590 run the current stages through the shared
planner_layering_common pipeline (Pass 1 and composition,
optimize_physical_asap, select_plan); tests are named after the stages.
Materialization is read from the physical DAG (#667); window forms and
retention stay pending adapters. Behavior that works passes (29 tests);
every expectation that needs a feature not in this stack is ignored with
the PR that delivers it (29 tests): Pass 2 sharing (#588, #595, #596),
window composition (#601, #628, #634), materialization enumeration and
MatAtQuery (#604, #625), UnivMon sizing and accuracy (#621), SQL
recognition and COUNT(*) composition (#598, #603) and plan selection row
estimates (#632). Each spec's "Today" column states the current output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW
zzylol added a commit that referenced this pull request Oct 13, 2026
Ported from #590: --example planner-layering-3a (Pattern A, ad hoc batch of
five p99 reports) and planner-layering-3b (Pattern B, repeating 5-min p99),
the Example 3 acceptance tests' workloads. Example 1's output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW
zzylol added a commit that referenced this pull request Oct 13, 2026
The specs and tests from #590 run the current stages through the shared
planner_layering_common pipeline (Pass 1 and composition,
optimize_physical_asap, select_plan); tests are named after the stages.
Materialization is read from the physical DAG (#667); window forms and
retention stay pending adapters. Behavior that works passes (29 tests);
every expectation that needs a feature not in this stack is ignored with
the PR that delivers it (29 tests): Pass 2 sharing (#588, #595, #596),
window composition (#601, #628, #634), materialization enumeration and
MatAtQuery (#604, #625), UnivMon sizing and accuracy (#621), SQL
recognition and COUNT(*) composition (#598, #603) and plan selection row
estimates (#632). Each spec's "Today" column states the current output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW
zzylol added a commit that referenced this pull request Oct 13, 2026
Ported from #590: --example planner-layering-3a (Pattern A, ad hoc batch of
five p99 reports) and planner-layering-3b (Pattern B, repeating 5-min p99),
the Example 3 acceptance tests' workloads. Example 1's output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW
@zzylol

zzylol commented Oct 13, 2026

Copy link
Copy Markdown
Contributor Author

Closing: this PR's Example 2–4 acceptance specs and tests were ported into #577 (merged), adapted to the current planning stages; its earlier tests had already been ported further up the stack. Closed with the author's approval.

zzylol added a commit that referenced this pull request Oct 13, 2026
…stages (#577)

* test: acceptance spec and pending tests for planner-layering Example 1

Define MVP acceptance for #509 Example 1 before the Phase C stage APIs
exist: 1 -> 6 -> 6 -> 1 candidates (Pass 1 x identical-expression
sharing; physical operator implementation only, no materialization).

- Spec with per-stage candidate tables, invariants and doc ambiguities.
- Integration tests against todo!() stage stubs, ignored until the
  stages land; workload and Stage 0 frontend-shape tests run now.
- Expected-only asap-stage-pipeline/v1 fixture for the DAG viewer.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: run the Example 1 acceptance tests against the real stages

Replace the todo!() stubs with adapters over Stage 0-3, un-ignore the 11
tests that pass, and give each still-ignored test the precise difference
between the implementation and the spec. Add runtime capability checks:
the selected plan compiles in the physical planner; compiling every
candidate stays ignored with the two runtime gaps it finds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test: read Example 1 logical stages as flat DAGs after the export removal

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* test: Example 1 acceptance on the composed stages (1 -> 3 -> 3 -> 1)

The tests run Pass 1 and composition, optimize_physical_asap and
select_plan through a shared tests/planner_layering_common pipeline, and
follow the decided behavior: three Pass 1 candidates (Q2 exact, CMS+heap,
CountSketch+heap), every sub-DAG NotMaterialized, P1 selected, CMS+heap
invalid (weights not proven non-negative) and CountSketch+heap invalid (a
Top-K output has no guarantee and no deployment evidence). Hydra (#605),
Pass 2 sharing (#588) and the two runtime gaps (#593, #579) stay ignored
with the PR that delivers them. Tests are named after the stages; the
compile check no longer uses the PromQL fallback. The spec lists where the
doc and the planner differ. The expected-only viewer fixture is removed:
the generated four-stage fixture replaces it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* test: port #590's Example 2-4 acceptance specs and tests

The specs and tests from #590 run the current stages through the shared
planner_layering_common pipeline (Pass 1 and composition,
optimize_physical_asap, select_plan); tests are named after the stages.
Materialization is read from the physical DAG (#667); window forms and
retention stay pending adapters. Behavior that works passes (29 tests);
every expectation that needs a feature not in this stack is ignored with
the PR that delivers it (29 tests): Pass 2 sharing (#588, #595, #596),
window composition (#601, #628, #634), materialization enumeration and
MatAtQuery (#604, #625), UnivMon sizing and accuracy (#621), SQL
recognition and COUNT(*) composition (#598, #603) and plan selection row
estimates (#632). Each spec's "Today" column states the current output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* feat(devtools): stage_pipeline examples for #509 Example 3

Ported from #590: --example planner-layering-3a (Pattern A, ad hoc batch of
five p99 reports) and planner-layering-3b (Pattern B, repeating 5-min p99),
the Example 3 acceptance tests' workloads. Example 1's output is unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* test: follow #576's per-consumer charging and exact top-k columns

Plan selection charges a NotMaterialized node once per consuming query,
so the charging helper checks NodeCost.multiplier and the Example 4 A3
ambiguity is recorded as decided. Example 1 checks that exact Q2 sorts by
the ranked value and returns [job, topk_10]. The stage viewer guide's
tab 1 row now describes the actual all-exact result.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* refactor(devtools): one planning pipeline for stage_pipeline and the acceptance tests

run_planning_stages and the #509 example workloads move into the
asap-devtools library; stage_pipeline serializes the run and the
planner-layering tests adapt it. The shared data workload drops
ingestion_rate for data at rest, which validate() requires.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* fix(devtools): select over every candidate; --max-displayed limits only the document

stage_pipeline capped enumeration at 64, so Example 3a (243 candidates)
selected P41 instead of the cheapest P122 (KLL for all five queries).
The pipeline now enumerates, optimizes and prices every candidate; the
document shows the first --max-displayed (default 64) plus the selected
one, with `combinations` and `capped`.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* docs: Example 2's SQL candidates compose; the SQL test waits only on #598

Running the ignored SQL test composes every candidate and fails only on
Q2's options (per-source counts until #598), so #603 is not a blocker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* test: name stages by number and name; say query-language frontends

The frontends' Run field, id and locals become stage0_query_language_frontends,
and test names carry stage0..stage3 with the stage name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* test: charging helper follows plan selection's per-consumer rule

With a materialized node the helper accepted any multiplier >= 1. It now
computes each node's computations as plan selection does (walks from
query roots and materialized nodes' inputs, stopping at materialized
nodes), checked on a hand-built candidate with a materialized node.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* test: Example 1 picks Q2 candidates by (option, no shared input)

physical_with and the invalid-candidate check no longer assume one
candidate per Q2 option, so #588's shared-input variants need no change.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* docs: Example 3 Pattern B charges each node once per consuming query

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* docs(stage-viewer): rows 2, 3a and 3b describe the planner's current output

Read from uncapped runs: Example 2's sketch plans are rejected for having
no (ε, δ) guarantee, 3a selects P122 (first of 108 tied cheapest plans,
nothing shared yet) and 3b selects query-time KLL; panes and the latency
check come with the window-summary PRs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* docs(stage-viewer): row 2 from the SQL run; 3a ties 32 plans, not 108

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* test: Example 1 counts only unshared candidates; stage3_ charging-helper names

The 3-logical and 3-physical counts now hold when #588 adds shared-input
variants.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* refactor(devtools): PlanningStagesRun fields carry stage number and name

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

* test(devtools): unique temp file per stage_pipeline run

cargo test runs the tests as threads of one process, so two runs of the same
example shared a file name and one deleted the other's output.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W7qG9aFyPij5uWsyAJCxDW

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@zzylol zzylol closed this Oct 13, 2026
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