controller: port replan.rs::push_config_to_agent to typed-stage-split pipeline - #334
Merged
Merged
Conversation
… pipeline `Replanner::push_config_to_agent` (and the agent-config push in `replan_metric`) called the legacy `generate_agent_config` emitter, which produces a single-pipeline DDSketch YAML with no `gorillas3` archive write, no OTTL `routing` processor, and no `metrics/warm_passthrough` pipeline. Agents that connected via the OpAMP `on_connect` callback (the post-#333 reconnection path) got that legacy YAML — so freshness-probe routing reached fresh-connect agents (criterion ⑥ on issue #46) but NOT plan-pinned reconnecting agents. Mirror `main::emit_bootstrap_typed`'s flow on the OpAMP push path: `bind_workload_typed` → `split_typed_three_stage` → pick the Edge stage → extend with freshness-probe + workload-registry archive metrics → `emit_for_runtime`. Gate it behind the existing `USE_TYPED_STAGE_SPLIT` env var so the legacy single-pipeline fallback still runs when the gate is off, matching `handle_plan` / `handle_bootstrap_agent_config`. On any typed-emit error the push falls back to the legacy emitter so it never silently drops. The bootstrap-scope demo plumbing (freshness probes + workload-registry archive metrics) is lifted out of `emit_bootstrap_typed` into a shared `config::extend_edge_with_demo_plumbing` helper; both bootstrap and replan now apply the SAME extension. The runtime defaults to `AgentRuntime::AsapOtel` since OpAMP `on_connect` doesn't surface the agent's runtime header today (matches the bootstrap default for legacy clients). Adds two unit tests in `replan::tests`: - `typed_replan_emit_includes_freshness_probe_routing` — asserts the typed path emits `gorillas3`, `routing`, `metrics/warm_passthrough`, and references `http_freshness_probe_warm`. - `legacy_path_omits_typed_processors_when_gate_off` — pins the gate semantics so a regression that always-on'd the typed path would surface here. Together with PR #329 (bootstrap GET path) this finishes the OpAMP-on-connect side of the typed emit so reconnecting agents now receive the same routed YAML as fresh-connect agents. 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>
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
Ports the OpAMP-push side of the agent-config emit to the typed L5
stage-split pipeline so reconnecting (plan-pinned) agents receive
the same routed YAML as fresh-connect agents — finishes the
OpAMP-on-connect side of the typed emit after #329 ported the
bootstrap GET path.
Why
Replanner::push_config_to_agent(and the agent-config push inreplan_metric) called the legacygenerate_agent_configemitter,which produces a single-pipeline DDSketch YAML with no
gorillas3archive write, no OTTL
routingprocessor, and nometrics/warm_passthroughpipeline. Agents that connected via theOpAMP
on_connectcallback (the post-#333 reconnection path) gotthat legacy YAML — so freshness-probe routing reached
fresh-connect agents (criterion ⑥ on #46) but NOT plan-pinned
reconnecting agents.
Closes the gap on issue #46, criterion ⑥.
What changed
replan.rs: new private helperstry_emit_typed_edge_yaml(metric)/
try_emit_typed_edge_yaml_for_workload(&wl)that mirrormain::emit_bootstrap_typed's flow (bind_workload_typed→split_typed_three_stage→ pickEdge→ apply demo plumbing →emit_for_runtime).push_config_to_agentandreplan_metric's agent-config pushbranch on
planner::stage_split::typed_stage_split_enabled()—typed emit on, legacy fallback on emit failure or when the gate
is off.
Replanner::with_workload_registry(Arc<WorkloadRegistry>)so the typed path can extend its edge config with the same
archive-tier metrics the bootstrap GET path applies.
main()wires it during replanner construction.
config/mod.rs: extractedextend_edge_with_demo_plumbingfromthe inline body of
emit_bootstrap_typed. Both bootstrap andreplan now apply the SAME freshness-probe + workload-registry
archive extension.
main::emit_bootstrap_typedcollapses to aone-line call.
Gate behaviour
USE_TYPED_STAGE_SPLIT0generate_agent_config(single-pipeline DDSketch). Backwards-compat.1/true/yesemit_for_runtime(AsapOtel, …). On error, falls back to the legacy emitter so the push never silently drops.Same gate / same matrix as
handle_plan(#329's PR) andhandle_bootstrap_agent_config.Runtime default
OpAMP
on_connectdoesn't surface the agent'sX-Agent-Runtimeheader today, so the typed emit defaults to
AgentRuntime::AsapOtel— matches the bootstrap default forunspecified clients. If a future commit threads runtime info
through OpAMP, swap the default for a per-agent lookup.
Test plan
cargo test --release replan::tests::— 7/7 pass, includingthe two new tests:
typed_replan_emit_includes_freshness_probe_routing—asserts the typed YAML contains
gorillas3,routing,metrics/warm_passthrough, and references the freshness probe.legacy_path_omits_typed_processors_when_gate_off— pinsthe gate semantics so a regression always-on'ing the typed path
surfaces here.
cargo build --releasefor this PR — requires a full demo run).
Pre-existing failing tests in
controller/src/main.rs::api_tests(
agent_receives_config_on_connect_via_workload_registry,replan_pushes_only_to_registered_agent) fail onorigin/maintoo— unrelated WebSocket protobuf decode race.
🤖 Generated with Claude Code