controller: planner picks sketch family per metric from query intent (5-sketch demo) - #339
Merged
Merged
Conversation
…(5-sketch demo) Pin the (sketch, statistic) capability matrix as a first-class module and route `bind_workload_typed` through it. The MVP demo contract (issue #46) requires per-metric family selection — `http_latency_ms` must bind to DDSketch (Quantile, rel-err), `request_size_bytes` to KLL (Quantile, rank-err), `unique_users_per_min` to HLL (Cardinality), `top_endpoint_qps` to CountSketch (TopK), `endpoint_request_freq` to CMS (Frequency), and `http_requests_total` to raw passthrough (SumRateCount). The previous priority-based dispatcher always picked DDSketch over KLL on Quantile, so the rank-err preference for byte-size metrics was unreachable. `sketch_type_override` (the workload-spec's `sketch_family_override`) wins over the capability-matched default when the override is valid for the statistic class; an invalid override (HLL on a Quantile workload) falls back to the catalog default rather than producing a nonsense binding. Files: - `sketch_algebra/capability_matching.rs` (new) — `StatisticClass`, `AccuracyPreference`, `is_valid_pair`, `pick_family`, `classify_demo_metric`. 14 unit tests pin the matrix. - `sketch_algebra/params.rs` — add `From<SketchType> for SketchKind` for the override translation. - `planner/rules.rs::bind_workload_typed` — capability-matrix-driven pick; family-specific `Bind*` rule dispatch; 10 unit tests covering every contract row, override behaviour, and invalid-override fallback. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
zzylol
added a commit
that referenced
this pull request
May 8, 2026
Activates the typed-stage-split path for every compose invocation that includes base.yml, so the demo (and any ad-hoc `docker compose up controller` against base alone) routes through the typed pipeline: bootstrap GET (#329), OpAMP-on-connect replan (#334), and per-metric 5-sketch family routing (#339 + #340 + the in-flight stitching PR). The mvp-multi-stage.yml overlay already sets the same default; this just promotes the gate to the base layer so it is on without the overlay. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2 tasks
zzylol
added a commit
that referenced
this pull request
May 8, 2026
…_family map (#46) (#342) PR #339 (planner: per-metric SketchExpr) and PR #340 (emitter: metric_to_family-driven 5-sketch routing) landed in parallel, but nothing populated `EdgeStageConfig.metric_to_family`, so the new routing-connector wire path stayed dormant — every bootstrap and OpAMP-push emitted single-pipeline DDSketch even with the six contract metrics declared in `workloads.yaml`. This stitches them: a new `config::collect_metric_to_family` walks the workload registry, runs `bind_workload_typed` per metric, and collects committed sketch families into the HashMap. Metrics that decline binding (`http_requests_total` raw passthrough, exact-required, multi-intent) are skipped — the emitter routes those to `metrics/raw_passthrough` by default. Wired into both: * `main::emit_bootstrap_typed` — also generalised the candidate resolution so a registry whose first agent-role entry is raw (e.g. `http_requests_total`) walks to the next binding metric for the edge_cfg shape rather than falling back to legacy. * `replan::Replanner::try_emit_typed_edge_yaml_for_workload` — same stitch so OpAMP-pushed YAML on reconnect / replan also activates the routing connector. Acceptance test (`api_tests::bootstrap_emits_5sketch_routing_for_six_contract_metrics`): loads all six MVP §46 contract metrics into the registry, hits the bootstrap GET endpoint with `USE_TYPED_STAGE_SPLIT=1`, and asserts the emitted YAML contains all 5 sketch processors, `routing` under `connectors:` (not `processors:`), all 6 named pipelines, and a `route() where metric.name == "..."` rule for each sketched metric. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
Pin the (sketch, statistic) capability matrix as a first-class module
in
controller/src/sketch_algebra/capability_matching.rsand routebind_workload_typedthrough it. The MVP demo contract (issue #46)requires per-metric family selection that the priority-based dispatcher
could not produce — DDSketch (priority 6) always beat KLL (priority 5)
on Quantile, so the rank-err preference for byte-size metrics was
unreachable.
Family-per-statistic mapping (issue #46)
http_requests_totalhttp_latency_msrequest_size_bytesunique_users_per_mintop_endpoint_qpsendpoint_request_freqCapability matrix (final state)
SumRateCounthas no valid sketch — the agent emits raw OTLP and thebackend computes the answer directly.
sketch_family_overridebehaviourThe workload-spec's
sketch_type_override(= the spec'ssketch_family_overrideper orchestrator contract) wins over thecapability-matched pick when the override is valid for the statistic
class. An invalid override (HLL on a Quantile workload) is silently
dropped and the planner falls back to the catalog default — the
binding never produces a nonsense (sketch, stat) pair.
Files touched
controller/src/sketch_algebra/capability_matching.rs(new) —StatisticClass,AccuracyPreference,is_valid_pair,pick_family,classify_demo_metric. 14 unit tests pin the matrix.controller/src/sketch_algebra/params.rs— addFrom<SketchType> for SketchKindfor the override translation.controller/src/sketch_algebra/mod.rs— register module + re-exports.controller/src/planner/rules.rs::bind_workload_typed— capability-matrix-driven family pick; family-specific
Bind*rule dispatch(bypasses the priority-based dispatcher's tie-break); 10 unit tests
covering every contract row, override behaviour, and invalid-override
fallback.
Test plan
cargo test --release sketch_algebra::capability_matching)cargo test --release planner::rules::tests::typed_binding_*,*sketch_type_override*,all_six_contract_metrics_produce_expected_family)SketchExprfamily (covered by theall_six_contract_metrics_produce_expected_familysweep test)planner::cost_model::workload_cost_tests::*failures (unresolvedRef("w")) are unrelated to this PR and reproduce onorigin/maincargo build --releaseclean (warnings only)🤖 Generated with Claude Code