Skip to content

mvp v6 phase E: driver + report v6 (run pending v5 merge) - #300

Merged
zzylol merged 4 commits into
mainfrom
mvp/v6-phase-e-driver-report
May 6, 2026
Merged

zzylol merged 4 commits into
mainfrom
mvp/v6-phase-e-driver-report

Conversation

@zzylol

@zzylol zzylol commented May 6, 2026

Copy link
Copy Markdown
Contributor

Summary

Phase E of the MVP v6 plan — author-mode. DRAFT — Phase F runs the demo against this driver once v5 PRs (#295 ASAPCollector + #90 ASAPQuery-backend) merge to main.

Three new scripts + one test module under `deploy/scripts/`:

  • `run_mvp_demo_v6.sh` (~516 LOC) — controller-driven multi-stage demo driver. Eight phases: preflight → stack up (`USE_TYPED_STAGE_SPLIT=1`) → measurements (replay + stages + per-edge bandwidth) → freshness via `run_freshness_phase.sh` → ad-hoc postings exercise → cold-fallback verification → compactor concat-only (dry-run + live) → teardown → report. Captures controller-emitted runtime configs from `/api/v1/collector-config/{agent,backend}`, falls back gracefully to placeholder configs when typed-stage-split returns None.
  • `mvp_report_v6.py` (~943 LOC) — MVP_REPORT_v6.md generator. Eight sections covering the six-criterion verdict + per-query-class breakdown + per-edge bandwidth + postings + compaction + S3-ops cost + honest caveats + emitted-config status. Pure stdlib, idempotent.
  • `measure_per_edge_bandwidth.py` (~332 LOC) — per-edge bandwidth probe for the v6 fan-in topology (sdk→agent / agent→gateway / gateway→backend / gateway→s3). Uses `docker stats` NetIO deltas; same mechanism as `measure_stages.py`.
  • `tests/test_mvp_report_v6.py` (~433 LOC) — 9 hermetic unit tests for the report generator. All synthetic fixture data is clearly marked MOCK.

Independent from v5's `run_mvp_demo.sh` + `mvp_report.py` — separate file, separate output dir, separate report. Those v5 files are NOT touched (in active use by v5 demo PID 1945011).

What Phase F needs to know

  • Knobs (env vars): `OUT_BASE` (default `deploy/eval-results/mvp-v6-2026-05-06`), `COMPACTOR_BIN` (default `compactor/target/release/gorilla-compactor` — built from v5 once mvp/v5: postings index + concat-only compactor + agent + demo (issue #46) #295 merges), `USE_TYPED_STAGE_SPLIT` (default 1), `STACK_SETTLE_S`/`AGENT_WARMUP_S`/`SOAK_S` (default 60s each).
  • Output paths: `${OUT_BASE}/{stack-up.log, controller-emitted-configs/, measurements/, freshness/, ad-hoc/, compactor/, MVP_REPORT_v6.md}`.
  • Pre-req images: `asap/sketchcol:dev`, `asap/query-backend:dev` (built from v5 PRs), `asap/fake-exporter:dev` (must have freshness probes — `EXPORTER_FRESHNESS_PROBES=on`, see Phase D mvp v6 phase D: fake-exporter freshness probes + measure_freshness.py #299).
  • Invocation: `bash deploy/scripts/run_mvp_demo_v6.sh`. The driver brings up the stack, runs all phases, tears down, and writes the report.

Test plan

  • `shellcheck deploy/scripts/run_mvp_demo_v6.sh` clean
  • `pytest deploy/scripts/tests/test_mvp_report_v6.py` — 9 pass, 0 fail
  • `pytest deploy/scripts/tests/` (full suite) — 24 pass, 0 fail
  • Module imports clean for all three scripts (`python3 -c "import"`)
  • (Phase F) End-to-end: `bash deploy/scripts/run_mvp_demo_v6.sh` against v5-merged tree → MVP_REPORT_v6.md
  • (Phase F) Verify §8 reports `live` (controller emitter exercised), or document why fallback-placeholder

Prior phases

Structural notes

  • The Phase B emitter pushes runtime configs via OpAMP (agent/gateway YAML) and BackendClient (backend JSON) — not to disk. The driver captures emitted configs through the controller's introspection endpoints (`/api/v1/collector-config/agent`, `/api/v1/collector-config/backend`, `/api/v1/config/`, `/api/v1/agents`). It also greps the controller's stderr for the `USE_TYPED_STAGE_SPLIT` tracing markers to record an emitter STATUS (`live` / `fallback-placeholder` / `not-exercised`) for the report's §8.
  • §4 (postings) and §6 (S3 cost) render `v5-merge-pending` markers when the v5 response/endpoint fields aren't present yet — the driver doesn't fail.

🤖 Generated with Claude Code

zzylol and others added 4 commits May 6, 2026 17:31
DRAFT — does not run the demo. Phase F brings up the stack and posts
numbers once v5 PRs (#295 ASAPCollector, #90 ASAPQuery-backend) land.

run_mvp_demo_v6.sh is independent from v5's run_mvp_demo.sh (which is
in active use by the v5 demo run, PID 1945011) — separate file, separate
output dir, separate report. Eight phases:

  0. preflight (docker, docker-compose, compactor binary check)
  1. stack up via base.yml + mvp-v6-multi-stage.yml + USE_TYPED_STAGE_SPLIT=1
  2. measurements (replay + measure_stages.py + measure_per_edge_bandwidth.py)
  3. freshness via run_freshness_phase.sh (raw/warm/archive)
  4. ad-hoc postings exercise (count + topk-5xx)
  5. cold-fallback verification (gorilla_archive marker)
  6. compactor concat-only (dry-run + live)
  7. teardown
  8. mvp_report_v6.py reduce → MVP_REPORT_v6.md

Captures controller-emitted runtime configs from /api/v1/collector-config/
and /api/v1/config/<metric>; falls back to placeholder gateway+agent
configs when typed-stage-split returns None (logged as
fallback-placeholder STATUS marker for the report).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Extends measure_stages.py's docker stats sampling with per-edge
labelling for the v6 fan-in topology:

  edge_sdk_to_agent       (10 producers TX)
  edge_agent_to_gateway   (2 agents TX)
  edge_gateway_to_backend (backend RX — distinguishes the gateway's
                           split egress)
  edge_gateway_to_s3      (minio RX — same rationale)

Output schema: edge,sample_ts_ms,window_s,bytes_total,bytes_per_s.
One row per (edge, sample) for a per-edge time-series; mvp_report_v6.py
reduces to per-edge mean B/s for criterion ① bandwidth.

Stdlib only; same `docker stats --no-stream` mechanism as
measure_stages.py so two probes can run in parallel without
docker-daemon contention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Independent from v5's mvp_report.py (which is in active use, PID 1945011).
Eight sections:

  §1 Stage-separated resource table (per-stage TOTAL across containers)
  §2 Six-criterion verdict table (bandwidth/latency/resource/accuracy/
     cold-fallback/freshness)
  §3 Per-query-class breakdown (window/label/combined latency + accuracy)
  §4 Postings filtering effect (gated on v5 merge — renders
     v5-merge-pending markers if response fields absent)
  §5 Compaction effect (before/after MinIO object count + bytes)
  §6 S3-ops cost (gated on v5 cost tracker endpoint)
  §7 Honest caveats (no replan, no hot reconfig, 10K not 1M, single host)
  §8 Controller-emitted runtime configs status (live /
     fallback-placeholder / not-exercised)

Pure stdlib, idempotent. Reads the v6 results dir layout written by
run_mvp_demo_v6.sh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Hermetic — no compose stack, no docker. Synthesises a minimal v6
results directory layout (with mock CSVs / JSON / JSONL fixtures
clearly marked synthetic) and asserts:

  * happy-path: all 8 sections present, all 6 criteria rows in §2,
    all 5 stages in §1, all 3 query classes in §3
  * idempotency: re-running over the same CSVs produces byte-identical MD
  * sparse fixture (only stages.csv): renderer still produces complete
    MD with UNKNOWN verdicts, v5-merge-pending markers in §4 / §6
  * fallback emitter status renders correctly in §8
  * missing --results-dir produces self-explanatory MD rather than crashing
  * helper unit tests (per-edge mean, query-class classifier,
    minio-listing counter, postings field extractor)

9 tests, all pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zzylol
zzylol marked this pull request as ready for review May 6, 2026 21:53
@zzylol
zzylol merged commit 85ac902 into main May 6, 2026
@zzylol
zzylol deleted the mvp/v6-phase-e-driver-report branch May 6, 2026 21:53
zzylol added a commit that referenced this pull request May 7, 2026
…ess probe routing (#301)

* mvp v6.1: fix typed-stage-split fire + backend overlay + freshness env

Three integration gaps that the v6 demo (PR #300) surfaced as
`not-exercised`/`v5-merge-pending`/empty CSVs.

(1) Typed-stage-split path never fired. The block lives inside
`handle_plan` (`controller/src/main.rs:465+`); the workload-registry
pre-pop loop at startup uses a different code path. The driver now
POSTs each canonical workload to /api/v1/plan after stack settle so
the typed path is exercised end-to-end.

(2) v6 overlay omitted backend env + per-metric routing. Without
ASAP_GORILLA_S3_* and ASAP_BACKEND_STORAGE_ROUTING the cold-archive
engine isn't registered and every query lands on the warm tier.
Mirror the wiring already proven in baseline-b6-asap-single-sketch.yml,
plus the asap-gorilla MinIO bucket seed.

(3) YAML `<<:` merge does NOT deep-merge per-service environment
maps under docker-compose, so the producer-* services were missing
EXPORTER_FRESHNESS_PROBES + EXPORTER_RATE / FREQ_HZ from the anchor.
Inline the full env per producer.

CONTROLLER_BACKEND_ENDPOINT also wired so the typed-backend JSON
push has a real target instead of silently logging "no client
configured".

See v6-1-diagnosis.md for full diagnosis.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* mvp v6.1 follow-ups: STATUS detector grep stdout + backend endpoint path

The first v6.1 run captured §8 STATUS=`not-exercised` even though the
controller's typed-stage-split path actually fired. Two small fixes:

1. The driver's STATUS detector greps `controller.stderr` only.
   Rust's `tracing_subscriber::fmt::init()` writes events to stdout,
   so docker logs splits them into our `controller.stdout` capture.
   Grep both files.

2. CONTROLLER_BACKEND_ENDPOINT must include the
   `/api/v1/streaming-config` path component — the BackendClient POSTs
   to the configured URL verbatim. Without the path, the typed
   backend JSON push hits the backend's root and gets a 404.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* mvp v6.1: artifacts from the fix-and-rerun (v6 → v6.1)

Captures the run-output artifacts referenced in the v6.1 PR comment.
Headline:

  §8 STATUS:  not-exercised → live
  Crit ⑤:    FAIL          → PASS (gorilla_archive marker present)
  Crit ⑥:    UNKNOWN       → UNKNOWN (deeper backend wiring required;
                                       routing yaml + producer env are
                                       fixed but SimpleEngine has no
                                       pattern registered for
                                       http_freshness_probe_*)
  §4 / §6:   v5-merge-pending / 0   (gorilla engine doesn't support
                                     `count(...)`, so the postings
                                     query returns 4xx; cost tracker
                                     stays at 0 because no successful
                                     archive query in the 60s window)

Two of three gaps closed. The third needs SimpleEngine pattern
registration for the freshness probe metric (or a streaming-config
overlay), which is a backend change beyond the scope of v6.1's
compose-overlay + driver fixes.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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