diff --git a/.github/workflows/tier3-baseline-capture.yml b/.github/workflows/tier3-baseline-capture.yml new file mode 100644 index 00000000000..10a7a54267d --- /dev/null +++ b/.github/workflows/tier3-baseline-capture.yml @@ -0,0 +1,99 @@ +# Manual C1 Phase-1 Tier-3 mirror baseline capture (``tier3_baseline.json``). +# +# Dispatched on `ubicloud-standard-2` (R-3 per ``docs/audit/c1-r3-canonical-bench-host-decision-matrix.md``). +# Runs five independent bench jobs (separate VMs), aggregates per procedure §2 / R-7 via +# ``scripts/aggregate_tier3_baseline.py``. +# +# **Phase-1 gate (R-7):** the canonical baseline lives in the repo tree at +# ``src/v3/compiler/benches/tier3_baseline.json`` (merged on ``main`` before mirror dissolution PRs). +# This workflow does **not** replace that file: it is a **recapture / audit** path for +# Director-approved baseline refresh or for comparing fresh Criterion output against the +# committed baseline (diff the artifact vs the checked-in JSON; land updates only via normal PR). +# +# Once this YAML exists on ``main``, operators may ``gh workflow run tier3-baseline-capture.yml``, +# then review or diff the emitted ``tier3_baseline.json`` artifact. + +name: Tier-3 baseline capture + +on: + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: tier3-baseline-capture-${{ github.repository }} + cancel-in-progress: false + +jobs: + capture-run: + strategy: + fail-fast: false + matrix: + run_number: [1, 2, 3, 4, 5] + runs-on: ubicloud-standard-2 + timeout-minutes: 60 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup Rust + uses: actions-rust-lang/setup-rust-toolchain@v1.16.0 + with: + cache: true + rustflags: "" + + - name: Run tier3 mirror benchmarks + run: cargo bench --bench tier3_mirror_perf -p v3-compiler + + - name: Stage capture bundle (criterion + rustc provenance) + run: | + mkdir -p staging + cp -a target/criterion staging/criterion + rustc --version | tee staging/rustc_version.txt + + - name: Upload capture bundle + uses: actions/upload-artifact@v4 + with: + name: tier3-criterion-${{ matrix.run_number }} + path: staging + + aggregate: + needs: capture-run + runs-on: ubicloud-standard-2 + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Download criterion artifacts + uses: actions/download-artifact@v4 + with: + pattern: tier3-criterion-* + path: runs + merge-multiple: false + + - name: Aggregate into tier3_baseline.json + run: | + set -euxo pipefail + # Artifact-only aggregate (compare vs src/v3/compiler/benches/tier3_baseline.json in-tree). + # Each matrix job uploaded `staging/` with `criterion/` + rustc_version.txt + shopt -s nullglob + bundles=(runs/tier3-criterion-*) + if [ "${#bundles[@]}" -lt 3 ]; then + echo "::error::expected ≥3 capture bundles under runs/tier3-criterion-*, got ${#bundles[@]}" + ls -la runs || true + exit 1 + fi + mapfile -t sorted < <(printf '%s\n' "${bundles[@]}" | sort -V) + python3 scripts/aggregate_tier3_baseline.py \ + --host-id ubicloud-standard-2 \ + --git-sha "${GITHUB_SHA}" \ + --output tier3_baseline.json \ + "${sorted[@]}" + + - name: Upload baseline JSON + uses: actions/upload-artifact@v4 + with: + name: tier3-baseline-json + path: tier3_baseline.json diff --git a/docs/audit/c1-tier3-baseline-capture-procedure.md b/docs/audit/c1-tier3-baseline-capture-procedure.md index 729c0618101..646f237487b 100644 --- a/docs/audit/c1-tier3-baseline-capture-procedure.md +++ b/docs/audit/c1-tier3-baseline-capture-procedure.md @@ -1,33 +1,29 @@ # C1 — Phase 1 0c Baseline Capture Procedure & Schema -**Status:** PROPOSAL (audit/procedure only). Authored 2026-05-01 (silent-boar-29) per Director dispatch via cool-stag-230 (R3 PB). +**Status:** PROPOSAL + **Phase-1 executable addendum** (R-7 baseline may land on `main`). Original shell 2026-05-01 (silent-boar-29); canonical host **R-3 = `ubicloud-standard-2`** ratified in `docs/audit/c1-r3-canonical-bench-host-decision-matrix.md` (2026-05-08). **Parent:** `docs/briefs/r3-pb-tier3-perf-budget-worker.md` (PR #1331), `docs/audit/c1-tier3-perf-budget-readiness-matrix.md` (PR #1358), `src/v3/compiler/benches/tier3_mirror_perf.rs` (PR #1362, merged). **Authority basis:** worker brief §"Phase 1 deliverables" item 0c + §"Dependencies" item 5 + readiness matrix §1 row R-3. -**Scope:** docs-only procedure + schema specification for the eventual Phase 1 0c `tier3_baseline.json` capture. **No baseline JSON committed. No fake or local-machine timing data. No code. No CI wiring. No Phase 2 work.** +**Scope:** Schema + capture commands + validation for `tier3_baseline.json`. **Phase-1 PRs that freeze R-7 commit** `src/v3/compiler/benches/tier3_baseline.json` alongside honest metadata (§4–§5). **Phase-2** perf predicate / substrate wiring stays out of scope here. -This artifact captures everything that *can* be specified without a canonical bench host being designated; the actual capture is gated on R-3 (PB Manager canonical CI machine) per the readiness matrix STOP-A. +Executable landing forbids **fabricated** provenance (`host_id` must match the machine that executed the benches — **never** mint `ubicloud-standard-2` unless those runs happened on that label). A narrow **bootstrap** path is defined in §4 / §5 when the Ubicloud workflow is not dispatchable yet; it still uses **truthful** `host_id`. --- -## 1. STOP condition for capture (R-3 not met) - -Per `docs/audit/c1-tier3-perf-budget-readiness-matrix.md` §1: - -| Prerequisite | State at HEAD `f66334729` | Authority needed | -|---|---|---| -| R-3 — canonical CI machine designated for baseline capture | **NOT MET** — no signal in `docs/r3-structure.md`, `docs/briefs/r3-pb-tier3-perf-budget-worker.md`, or recent CI changes naming the bench host. | PB Manager designate; Substrate Manager if CI-infra cross-cut. | +## 1. Canonical host R-3 (baseline capture) Worker brief §"Discipline / baseline noise concerns" (line 108) is explicit: *"Phase 1 capture and Phase 2 measurement should run on the same canonical CI machine to keep comparison meaningful (hardware-stable). If CI infrastructure varies, escalate to Substrate Mgr."* -**Per dispatch constraint:** "No fake or local-machine baseline JSON unless the canonical-host authority is explicitly satisfied." This procedure document is therefore the bounded preparatory artifact — schema + commands + validation specification authored once, executed once, by the operator who owns the canonical host. +**R-3 designation (ratified):** **`ubicloud-standard-2`** — see `docs/audit/c1-r3-canonical-bench-host-decision-matrix.md` §5.1 + worker dispatch at gunbc **#828**. **Standard case:** `cargo bench` capture for a committed baseline SHOULD run on that label (via `.github/workflows/tier3-baseline-capture.yml` once the workflow exists on `default`) so `captured_on.host_id` records `ubicloud-standard-2`. -**Concrete next-unblock shape:** PB Manager authors a one-line addition to `docs/r3-structure.md` (or a sibling brief) of the form: +**Bootstrap sequencing exception (single authority, P2):** the *first* committed `tier3_baseline.json` may land in the **same PR** that introduces the Ubicloud `workflow_dispatch` workflow, before `gh workflow run` is available against `default`. In that narrow case the capture runs on the **actual** operator/session machine, `captured_on.host_id` is **that honest identifier** (not `ubicloud-standard-2`), and the Phase-1 PR MUST reconcile provenance in its description (**no retroactive `host_id` relabel**). -> *Canonical bench host for C1 Phase 1 0c: `` (e.g., the CI runner labeled `bench-canonical-1`, or a named workspace machine). Phase 1 0c capture and all Phase 2 perf measurements MUST run on this host; deviation requires Director sign-off and a re-capture of the baseline.* +This exception **does not** relax the worker brief §"Discipline" **same-machine comparison** discipline for substantive perf gates—it only unlocks early **presence** of a JSON artifact and the forwarded workflow YAML. **`R-7` authority is split:** +- **`R‑7.presence`** (grep / sequencing / STOP triage needing a tracked `tier3_baseline.json` path): satisfied by merging any honest-schema JSON at `src/v3/compiler/benches/tier3_baseline.json`. +- **`R‑7.canonical coherence`** (**mirror dissolution slices + Phase‑2 canonical measurement** pairing `PerfWithinBaseline`/budget claims against timings collected on **`ubicloud-standard-2`**): **NOT satisfied** solely by a non‑Ubicloud bootstrap seed—the committed JSON **MUST either** record `captured_on.host_id == ubicloud-standard-2` captured via `.github/workflows/tier3-baseline-capture.yml` (landed artifact → PR replacing baseline rows/metadata) **or** bear a **Director / PB-published waiver receipt** affirming dissolution may proceed temporarily against bootstrap numbers (fail-closed if neither). -Once that line lands, this procedure is executable as written. +**Operational default:** after this workflow YAML reaches `default`, operators run **`workflow_dispatch`**, copy the **`tier3-baseline-json`** artifact into‑tree (**same PR stack or immediate follow‑up PR**) so `host_id` + medians authoritative for dissolution work match **Ubicloud**, unless Director waives coherence. ---- +**Director / PB** sign-off gates any waiver-class shortcut; speculative “eventually recapture” without an explicit STOP decision is insufficient for **`R‑7.canonical coherence`** clearance. ## 2. Capture command @@ -54,7 +50,7 @@ cargo bench --bench tier3_mirror_perf -p v3-compiler - `median_ns` in `tier3_baseline.json` = **median of the N per-run medians** (median-of-medians). - `p99_ns` = **max p99 across the N runs** (conservative pin; absorbs run-to-run tail variance). - Per-run medians and p99s are computed via the path-(a) extraction helper at §2.1 from each run's `target/criterion//new/sample.json`. -- The capture PR commits the extraction helper + per-run intermediate JSONs (or a single combined file recording the N samples) alongside the final `tier3_baseline.json` so the multi-run aggregation is reproducible / auditable. +- The capture landing commits **`scripts/aggregate_tier3_baseline.py`** (bundle aggregation + stamping) + the final **`tier3_baseline.json`**. Bundled per-run **`criterion/`** subtrees SHOULD live either **in-repo** alongside the merge (**bootstrap / audited local sequencing**) **or** as **retained Actions artifacts** when capture runs via **`.github/workflows/tier3-baseline-capture.yml`** (preferred once dispatchable on `default`); do not silently drop reproducibility anchors for the **`N`** runs that fed the median-of-medians / max-p99 policy. ### 2.1 p99 source — explicit @@ -67,7 +63,7 @@ The Phase 1 0c capture PR MUST cite which path it took in its description and (f --- -## 3. Mirror-group → bench-name mapping (verified at HEAD `f66334729`) +## 3. Mirror-group → bench-name mapping (authoritative names; reconcile `tier3_mirror_perf.rs` at the artifact's `captured_on.git_sha`) The four perf-budget claims in `tier3_mirror_dissolution_perf_within_budget` map to bench names from `src/v3/compiler/benches/tier3_mirror_perf.rs`: @@ -133,8 +129,11 @@ The committed baseline file lives at `src/v3/compiler/benches/tier3_baseline.jso **Field rules:** - `median_ns` and `p99_ns` are **strictly positive integers** in nanoseconds (> 0; matches §5 rule 4). `median_ns` is the `point_estimate` for the median field of `target/criterion//new/estimates.json`, rounded to the nearest nanosecond. `p99_ns` is **derived per §2.1** from `target/criterion//new/sample.json` raw per-iteration timings (Criterion 0.5's `estimates.json` has no p99 field); use path (a) extraction helper or path (b) Gaussian approximation as documented there. Do not commit decimal/float timings — round both fields to integer nanoseconds before writing the JSON to avoid floating-point platform variance. -- `host_id` is required and must match the canonical host designated under R-3. CI rejects edits to `tier3_baseline.json` whose `host_id` differs from the recorded canonical host without an accompanying Director approval receipt. +- **`host_id` (P2 honesty):** required; MUST identify the machine that executed the benches—**never** spoof `ubicloud-standard-2` unless those runs actually occurred on that label. + - **Standard commits:** SHOULD use **`ubicloud-standard-2`** (captured via `.github/workflows/tier3-baseline-capture.yml` once dispatchable). + - **Bootstrap seed landing** (workflow YAML introduced in the same Phase-1 PR—`workflow_dispatch` not yet on `default`): **`host_id` MUST remain the truthful non-Ubicloud identifier**, with PR-body reconciliation naming **forward canonical authority** (`ubicloud-standard-2`) per §1. Replacing that seed via Ubicloud artifact follows **Director / PB-approved recapture** (worker brief) — **not** by silently rewriting `host_id`. - `git_sha` is the full 40-char SHA, not abbreviated. +- **`captured_at`:** RFC 3339 UTC for when **`tier3_baseline.json`** was **finalized** (**`scripts/aggregate_tier3_baseline.py`** stamps aggregator wall clock—intentional audit receipt); it **need not** match any single **`cargo bench`** end instant. Bench execution spans live in archived **`criterion/`** bundles + workflow/job logs retained with the aggregate PR or artifact lineage. - `mirror_groups` keys MUST be exactly the four strings `termination`, `computation`, `induction`, `effect_carrier` — no others, no aliases. The Phase 2 gate uses these as join keys. - `benches[].name` MUST exactly match a `bench_function` argument in `tier3_mirror_perf.rs` at the captured `git_sha`. CI validation rejects mismatches. @@ -145,43 +144,38 @@ The committed baseline file lives at `src/v3/compiler/benches/tier3_baseline.jso Before the Phase 1 0c PR opens, the operator MUST run the following checks against the produced JSON: 1. **Schema completeness:** every key in §4 is present; no extras; types match. -2. **Bench-name exact match (fail-closed):** the set of bench-names listed in `mirror_groups[*].benches[].name` MUST equal exactly the budgeted bench-name set defined in §3 — no missing names (every budgeted bench measured), no extra names (no out-of-budget bench in the JSON). Concretely at HEAD `f66334729` the required set is exactly `{tier3_termination_merge_evidence, tier3_computation_positive_descent_count, tier3_computation_lower_same_argument_call, tier3_induction_type_iteration_dimension_miss, tier3_effects_lane2_linear_read_chain}` (5 names). If a future bench is intentionally added to `tier3_mirror_perf.rs` but excluded from the budget, that exclusion MUST be a separate explicit allowlist row in §3 of this procedure document (with a receipt) and the JSON's bench-name set continues to equal the §3-budgeted set, not all bench-names registered in the bench file. Supersets are NOT permitted; subsets are NOT permitted. +2. **Bench-name exact match (fail-closed):** the distinct names listed in `mirror_groups[*].benches[].name` MUST equal exactly the §3 budgeted set — no missing names (every budgeted bench measured), no extra names (no out-of-budget bench in the JSON). That budgeted five-name set is `{tier3_termination_merge_evidence, tier3_computation_positive_descent_count, tier3_computation_lower_same_argument_call, tier3_induction_type_iteration_dimension_miss, tier3_effects_lane2_linear_read_chain}` (each appearing once across `mirror_groups`, matching `tier3_mirror_perf.rs` at this JSON file's own `captured_on.git_sha`). If a future bench is intentionally added to `tier3_mirror_perf.rs` but excluded from the budget, that exclusion MUST be a separate explicit allowlist row in §3 of this procedure document (with a receipt) and the JSON's bench-name set continues to equal the §3-budgeted set, not all bench-names registered in the bench file. Supersets are NOT permitted; subsets are NOT permitted. 3. **Sanity bands:** for each bench, `p99_ns >= median_ns` (criterion guarantees this; reject the JSON if violated as it indicates capture corruption). 4. **Non-zero:** every `median_ns` and `p99_ns` is `> 0`. A zero indicates measurement failure (criterion below floor), not a real timing. -5. **Host stability:** `captured_on.host_id` matches the R-3 canonical host string; reject if not. +5. **`host_id` coherence:** Either **`host_id == ubicloud-standard-2`** (standard captures) **or** the **`host_id` matches the bootstrap exception** (§1 / §4) with the Phase-1 PR documenting reconciliation—reject fabricated `ubicloud-standard-2` labels absent Ubicloud-backed runs / dishonest relabeling. 6. **Sample size receipt:** the operator's PR description includes the criterion sample size used (default 100) and the effective measurement budget (criterion's reported `target_time` × `sample_size`). If non-default, justify in the PR body. These rules are spec; their enforcement is a Phase 2 capture-side concern (the Phase 2 PR adds a reader + the structural-acceptance predicate per worker brief §"Acceptance gate" path (a) `PerfWithinBaseline` or path (b) `ExecuteCommand`). --- -## 6. What this PR explicitly does NOT do +## 6. What this procedure does **not** cover (by design) -- ❌ Commit any `tier3_baseline.json` (real or placeholder) to the repo. Per dispatch constraint and worker brief STOP condition: capture is gated on R-3. -- ❌ Add a `criterion_main!` change, alter `tier3_mirror_perf.rs`, or extend the bench surface. Bench file is single-authority for the measurement targets; this doc only specifies how to read its output. -- ❌ Add CI wiring. Phase 1 capture is one-shot; no repeating CI job is appropriate until Phase 2's `PerfWithinBaseline` predicate is authored. -- ❌ Author the `PerfWithinBaseline` substrate predicate. That is a Substrate Manager call (worker brief §"Acceptance gate"), gated separately. -- ❌ Capture timing data on a non-canonical machine and commit it as `tier3_baseline.json`. Worker brief §"Discipline" forbids this; dispatch constraint reaffirms it. -- ❌ Add new hand-authored Rust files. (No SG-0 entry needed for a docs-only PR.) +- ❌ **Fabricate provenance** for `tier3_baseline.json` (including forging `host_id` or timing rows). +- ❌ **Silent** “local seed” without PR reconciliation when `host_id` is not `ubicloud-standard-2` (bootstrap path requires §1 / §4 honesty + description). +- ❌ Author the **`PerfWithinBaseline`** substrate predicate (Substrate Manager; worker brief §"Acceptance gate"). +- ❌ Extend `tier3_mirror_perf.rs` bench surface without updating §3 mapping + JSON row set (fail-closed naming). + +**Historical note:** the *original* drafting PR for this document was explicitly **docs-only** (“do not commit baseline JSON yet”). **Executable Phase-1 landing** supersedes that historical non-goal: committing `src/v3/compiler/benches/tier3_baseline.json` **is** required for R-7 once capture discipline is satisfied. --- -## 7. Routing question (single) +## 7. Routing (authority) -**For PB Manager.** The canonical bench host (R-3) needs a one-line designation in `docs/r3-structure.md` or a sibling authority doc. Once that lands, this procedure is executable. Suggested form in §1 above. Substrate Manager involvement only if the choice cross-cuts CI infrastructure (e.g., requires a new dedicated runner). +- **R-3 host** — ratified as **`ubicloud-standard-2`**; see `docs/audit/c1-r3-canonical-bench-host-decision-matrix.md`. +- **Bootstrap seed vs dissolution coherence** — PB Manager / Director record whether **`R‑7.canonical coherence`** clears via Ubicloud refreshed JSON (**default**) versus a **narrowly scoped waiver**; absence of waiver + non‑Ubicloud `host_id` means dissolution-linked perf benches stay blocked on canonical pairing. --- ## 8. Acceptance summary -This procedure document is intentionally bounded: - -- §1 records the STOP condition (R-3 unmet) and the concrete next-unblock shape. -- §2 specifies the capture command. -- §3 maps mirror groups to bench names, verified against `src/v3/compiler/benches/tier3_mirror_perf.rs` at HEAD `f66334729`. -- §4 specifies the `tier3_baseline.json` schema. -- §5 specifies validation rules. -- §6 enumerates non-goals. -- §7 routes one question to PB Manager. - -**No capture has been run. No timing data exists in this PR.** Phase 1 0c remains gated on R-3. +- §1 designates R-3 (`ubicloud-standard-2`) + **bootstrap sequencing** exception (`host_id` honest; **split `R‑7.presence` vs `R‑7.canonical coherence`** for dissolution-linked perf parity). +- §2–§3 prescribe capture + bench-name mapping. +- §4–§5 prescribe schema + validation (including **`host_id` honesty**). +- §6 lists out-of-scope substrate / fabrication classes. +- §7 names authority for policy on seed vs refresh. diff --git a/docs/audit/c1-tier3-perf-budget-readiness-matrix.md b/docs/audit/c1-tier3-perf-budget-readiness-matrix.md index dfbe4dc9ea1..935873770aa 100644 --- a/docs/audit/c1-tier3-perf-budget-readiness-matrix.md +++ b/docs/audit/c1-tier3-perf-budget-readiness-matrix.md @@ -3,37 +3,37 @@ **Status:** PROPOSAL (audit/planning only). Authored 2026-05-01 (silent-boar-29) per Director dispatch via cool-stag-230 (R3 PB). **Parent brief:** `docs/briefs/r3-pb-tier3-perf-budget-worker.md` (PR #1331, merged). **Authority basis:** PR #1319 (Director ratification — ≤2× median / ≤5× p99 thresholds); `docs/r3-structure.md` §"T-Tier3-Dissolution"; INVARIANTS §P2 (no parallel implementations). -**Scope:** docs-only readiness verification ahead of any Phase 1 dispatch. **No code, no `criterion` dependency, no benchmark fixtures, no `PerfWithinBaseline` variant authoring, no fake pass/fail claims.** +**Scope:** docs-only **readiness artifact** (this file does not land Rust). It **records** Phase 1 / Phase 2 prerequisite state observed against the tracked tree—including that **`criterion`** is present when true (**R‑1** refreshed **2026‑05‑11**). **No benchmark fixtures authored here, no `PerfWithinBaseline` variant authoring, no fake pass/fail claims.** This is the smallest useful preparatory artifact requested by the dispatch: it (a) verifies each Phase 1 / Phase 2 prerequisite at HEAD, (b) inventories the four mirror surfaces with current line ranges, (c) records routing for the open Substrate-Mgr decision, and (d) names what must change before worker dispatch is authorized. --- -## 1. Phase / dispatch readiness at HEAD `5d03c86b0` +## 1. Phase / dispatch readiness -| # | Prerequisite | Phase | State at HEAD | Owner | Routing | +| # | Prerequisite | Phase | Recorded state | Owner | Routing | |---|---|---|---|---|---| -| R-1 | `criterion` dev-dep present in `src/v3/compiler/Cargo.toml` (or workspace) | Phase 1 (deliverable 0a) | **NOT MET** — `grep -n criterion Cargo.toml src/v3/compiler/Cargo.toml` returns zero matches at HEAD. | C1 Phase 1 worker (when dispatched). | Internal to lane; no escalation needed. | +| R-1 | `criterion` dev-dep present in `src/v3/compiler/Cargo.toml` (or workspace) | Phase 1 (deliverable 0a) | **MET** — **`[dev-dependencies]`** declares **`criterion = "0.5"`**; **`[[bench]]`** **`tier3_mirror_perf`** (**`harness = false`**). Verification: **`grep -n criterion src/v3/compiler/Cargo.toml`** and **`grep -n tier3_mirror_perf src/v3/compiler/Cargo.toml`**. | n/a | n/a | | R-2 | Tier-3 hand-Rust mirror sites still live (Phase 1 measures them) | Phase 1 | **MET** — see §2 surface inventory; all four mirror surfaces present, but line-range citations in the parent brief have drifted (see §2). | n/a | n/a | -| R-3 | Canonical CI machine designated for baseline capture (deliverable 0c) | Phase 1 | **NOT MET** — no signal in `docs/r3-structure.md`, `r3-pb-tier3-perf-budget-worker.md`, or recent CI changes naming the canonical bench host. Per brief §"Discipline / baseline noise concerns": Phase 1 capture and Phase 2 measurement must run on the same hardware. | PB Manager. | Substrate Mgr if CI-infra cross-cuts. **Hard prereq for Phase 1 dispatch.** | -| R-4 | Substrate-Mgr decision on `PerfWithinBaseline` `TestPredicate` variant (path (a)) vs `ExecuteCommand` reuse (path (b)) | Phase 2 | **NOT MET** — `src/v3/std/verification.dag:109-160` declares `TestPredicate` variants `Compiles \| FailsWithDiagnostic \| OutputEquals \| PortHasState \| DeclarationHasRefinement \| CostBounded \| BehavioralObservation \| MockBackedInvariant \| ExecuteCommand \| ForAllTargets \| ...`; no `PerfWithinBaseline`. Path (a) requires Substrate Mgr to author the variant before Phase 2 has any `.dag` predicate to reach. | Substrate Manager. | **Hard prereq for Phase 2 dispatch.** Per parent brief §"STOP conditions" item 1. | +| R-3 | Canonical **baseline capture host** designated for **`cargo bench` / `tier3_baseline.json`** capture (deliverable 0c) | Phase 1 | **MET (designation)** — **`ubicloud-standard-2`** ratified in **`docs/audit/c1-r3-canonical-bench-host-decision-matrix.md`**; PR **`#2702`** forwards **`.github/workflows/tier3-baseline-capture.yml`** with **`runs-on: ubicloud-standard-2`**. Merge-blocking **`ci.yml`** **`v3` / compile jobs** intentionally use **`gunbc-ci`** (self-hosted) — orthogonal pool; Phase 1 `cargo bench` capture authority follows R‑3 matrix + capture workflow **not** the default PR compile farm. **`R‑7.canonical coherence`** still awaits a **successful Ubicloud-backed capture artifact** (`captured_on.host_id`) or Director/PB waiver per R‑7 row. | PB Manager | Substrate Mgr if CI-infra cross-cuts. | +| R-4 | Path **(a)** `PerfWithinBaseline` declarative substrate vs path **(b)** `ExecuteCommand` reuse (`TestPredicate`) | Phase 2 | **MET (substrate)** — **`src/v3/std/verification.dag`** declares closed **`PerfBudgetComparisonOp`** (**~L94–97**) and **`TestPredicate`** variant **`PerfWithinBaseline { subject, comparator, baseline_ref }`** (**~L249–253**); **`src/v3/compiler/src/test_runner.rs`** dispatches **`\"PerfWithinBaseline\"` → `eval_perf_within_baseline`** (**~L2496**). Smoke Fixture: **`src/v3/compiler/tests/fixtures/r3_perf_within_baseline_smoke.dag`**. Verification: **`rg -n PerfWithinBaseline src/v3/std/verification.dag src/v3/compiler/src/test_runner.rs`**. Phase 2 is **not** blocked on “no substrate predicate”: it still awaits **dissolution authoring** (**R‑5/R‑6**) and **coherent R‑7** before the mirror perf gate can clear. Director-signoff **path (b)** remains a downgrade option but is no longer forced by substrate absence. | Substrate Manager (shape stewardship); Director if path **(b)** is ratified instead. | Per parent brief §"STOP conditions": path **(a)** authoring **landed**. | | R-5 | All four T-Tier3-Dissolution mirror dissolution PRs merged on `main` | Phase 2 | **NOT MET** — all four mirror sites still live (see §2). | T-Tier3-Dissolution worker pack (`r2-pb-tier3-mirror-dissolution-workers.md`). | n/a; gates Phase 2 only. | | R-6 | R2-Evaluator readiness signal (Phase 2 measures `.dag` body via Evaluator) | Phase 2 | **NOT MET** at audit time — Evaluator is R3 in flight per `r3-structure.md`; readiness signal not yet on the closure ledger. | R2-Evaluator Manager (R3 continuation). | **Hard prereq for Phase 2 dispatch.** | -| R-7 | Phase 1 baseline JSON (`tier3_baseline.json`) merged on `main` BEFORE any mirror dissolution PR | Phase 2 | **NOT MET** — `find . -name 'tier3_baseline*'` returns no matches. Strict temporal ordering: brief §"STOP conditions" item 2 — reverse order is **unrecoverable**. | C1 Phase 1 (worker, when dispatched). | n/a; structural constraint enforced by sequencing. | +| R-7 | Phase 1 baseline JSON (`tier3_baseline.json`) on `main` **and** **`R‑7.canonical coherence`** (`captured_on.host_id` + timings from **`ubicloud-standard-2`** for dissolution-linked perf parity) | Phase 2 / dissolution prep | **`R‑7.presence`:** **landing** via PR **`#2702`** (bootstrap JSON path). **`R‑7.canonical coherence`:** **BLOCKED until** Operators run `.github/workflows/tier3-baseline-capture.yml` post-merge (**or equivalent Ubicloud-backed capture**) replacing committed baseline rows/metadata with `host_id: ubicloud-standard-2`, **unless** Director/PB publishes waiver receipt. Temporal ordering unchanged: dissolution PRs relying on canonical perf benches still follow baseline **coherence**, not bootstrap presence alone (`docs/audit/c1-tier3-baseline-capture-procedure.md` §1). | C1 Phase 1 worker + PB Manager (cadence/waiver ledger). | `workflow_dispatch` refresh after YAML on `default`. | -**Summary:** Phase 1 dispatch is blocked on **R-1** (trivial, internal) + **R-3** (PB-Manager confirmation of canonical CI machine — non-trivial, requires PB-Mgr decision). Phase 2 dispatch is blocked additionally on **R-4** + **R-5** + **R-6** + **R-7**. +**Summary:** §1 **`MET / NOT MET`** rows are authoritative for this **`2026‑05‑11`** audit refresh (**PR `#2702`**) plus **`2026‑05‑12`** **R‑4** substrate reconcile against HEAD — **R‑1** (**`criterion`**) and **R‑3** (**Ubicloud-backed capture designation**) read **MET** here and align with **`c1-r3-canonical-bench-host-decision-matrix.md`** plus **`tier3-baseline-capture.yml`**. **R‑7** splits **`presence` vs canonical `host_id` coherence** per **`c1-tier3-baseline-capture-procedure.md` §1** (**PR `#2702`**); dissolution-linked **`R‑7.canonical coherence`** remains load-bearing separately. **R‑4** (**path‑(a) `PerfWithinBaseline`**) reads **MET** (**`verification.dag` + `test_runner`**). Phase 2 dispatch stays blocked additionally on **R‑5 + R‑6 + coherent R‑7** (**`R‑7.presence`** alone does not unblock perf parity gates; Phase 2 also needs the dissolution lane `.dag` claims that *consumes* the landed predicate against frozen baseline rows). --- ## 2. Tier-3 mirror surface inventory (drift-corrected) -The parent brief cites mirror line ranges as `dag.rs:628-790` (termination), `:839-915` (computation), `:916-980` (induction), plus `dag/effects.rs` and `workflow_idempotency.rs`. Those ranges have drifted at HEAD. The verified ranges below are what Phase 1 bench groups must target. +The parent brief cites mirror line ranges as `dag.rs:628-790` (termination), `:839-915` (computation), `:916-980` (induction), plus `dag/effects.rs` and `compose_operation_effects` (105 LOC in `workflow_idempotency.rs`). Those ranges have drifted at HEAD. The verified ranges below are what Phase 1 bench groups must target. -| Brief claim | Mirror | Current location at HEAD `5d03c86b0` | Verification | +| Brief claim | Mirror | Current layout / anchors (`2026‑05‑11` refresh) | Verification | |---|---|---|---| -| `dag.rs:628-790` | **termination** mirror — `DescentEvidence`, `PositiveDescentAmount`, `ProportionalDivisor`, `ShrinkFactor`, `evidence_rank`, `merge_evidence` | `src/v3/compiler/src/dag.rs:819-1010` (approx). Anchors: `pub enum DescentEvidence` at L819; `pub enum PositiveDescentAmount` at L843; `pub enum ProportionalDivisor` at L852; `pub fn evidence_rank` at L939; `pub fn merge_evidence` at L947; `pub fn join_evidence` at L963; `pub enum ShrinkFactor` at L1084. | `awk 'NR>=800 && NR<=1100 && /^(pub )?(fn\|enum\|struct\|impl)/ {print NR}' src/v3/compiler/src/dag.rs` | -| `dag.rs:839-915` | **computation** mirror — `SizeBound` and recursion-shape derivation | `src/v3/compiler/src/dag.rs` — anchors `pub enum SizeBound` at L1027; `pub fn tree_size_bound` at L1038. (Original brief range `839-915` overlaps with the computation/induction zone but does not match current symbol layout.) | same as above | -| `dag.rs:916-980` | **induction** mirror — `RecursionShape`, `InductiveField`, `SubValueRelation` | `src/v3/compiler/src/dag.rs` — `pub enum RecursionShape` at L1097; further symbols downstream. | same as above | +| `dag.rs:628-790` | **termination** mirror — `DescentEvidence`, `PositiveDescentAmount`, `ProportionalDivisor`, `evidence_rank`, `merge_evidence`, `join_evidence`; **`ShrinkFactor` lives under nested `pub mod computation`**, not contiguous with termination lattice enums | **`src/v3/compiler/src/dag.rs`** — **`pub enum DescentEvidence`** **L1165**; **`PositiveDescentAmount`** **L1189**; **`ProportionalDivisor`** **L1198**; **`evidence_rank`** **L1285**; **`merge_evidence`** **L1293**; **`join_evidence`** **L1309**. Nested scaffold: **`ShrinkFactor`** from **~L162** inside **`pub mod computation`** (**~L84**). | `awk 'NR>=80 && NR<=220 && /^(pub )?(fn\|enum\|struct\|impl)/ {print NR}' src/v3/compiler/src/dag.rs`; `awk 'NR>=1140 && NR<=1360 && /^(pub )?(fn\|enum\|struct\|impl)/ {print NR}' src/v3/compiler/src/dag.rs` | +| `dag.rs:839-915` | **computation** mirror — `SizeBound`, `CallPattern`, recursion-shape scaffolding, `ShrinkFactor`, `tree_size_bound`, … | **`src/v3/compiler/src/dag.rs`** nested **`pub mod computation`** — **`pub enum SizeBound`** **L111**; **`tree_size_bound`** **L122**. | `awk 'NR>=80 && NR<=400 && /^(pub )?(fn\|enum\|struct\|impl)/ {print NR}' src/v3/compiler/src/dag.rs` | +| `dag.rs:916-980` | **induction** mirror — `RecursionShape`, `InductiveField`, `SubValueRelation` | **`src/v3/compiler/src/dag.rs`** — **`pub enum RecursionShape`** **L1368**; downstream symbols in-file. | `awk 'NR>=1340 && NR<=1550 && /^(pub )?(fn\|enum\|struct\|impl)/ {print NR}' src/v3/compiler/src/dag.rs` | | `dag/effects.rs` (216 LOC) + `compose_operation_effects` (105 LOC in `workflow_idempotency.rs`) | **effect-carrier** mirror | `src/v3/compiler/src/dag/effects.rs` (216 LOC, MET); `src/v3/compiler/src/workflow_idempotency.rs` (105 LOC, MET). | `wc -l` on both files. | **Drift recommendation:** Phase 1 bench groups should not hard-code line ranges; reference symbol names instead (`DescentEvidence::evidence_rank`, `merge_evidence`, `tree_size_bound`, `compose_operation_effects`, etc.). Symbols are stable across the kind of refactors that move line numbers; lines are not. **Routing question §4.1.** @@ -44,8 +44,8 @@ The parent brief cites mirror line ranges as `dag.rs:628-790` (termination), `:8 The dispatch authorizes "STOP+PING if the required retired-mirror surfaces are not live enough to attach fixtures." That STOP does not fire — mirrors are live (R-2 met). The relevant blockers are **upstream of fixture authoring**: -- **STOP-A:** Phase 1 worker dispatch is not authorized until R-1 (internal) + R-3 (PB-Mgr canonical CI host) are resolved. -- **STOP-B:** Phase 2 worker dispatch is not authorized until R-4 (Substrate-Mgr `PerfWithinBaseline` decision) + R-5 + R-6 + R-7. R-4 is the load-bearing one — without the predicate variant or an explicit Director-signoff downshift to path (b) `ExecuteCommand`, Phase 2 has no `.dag` predicate to reach. +- **STOP-A:** ~~Phase 1 worker dispatch waits on internal R‑1 + R‑3 designation~~ (**both MET in §1 on this `2026‑05‑11` refresh**); **routing / cadence / `R‑7` bootstrap vs canonical capture pairing** remains PB/Director authority per parent brief (**recapture sequencing is not silent**). +- **STOP-B:** Phase 2 worker dispatch is not authorized until R-5 + R-6 + R-7 coherent + **dissolution-scope `.dag` gate authoring** that exercises **`PerfWithinBaseline`** against **`tier3_baseline.json`** (parent brief suites). ~~R‑4 substrate absence~~ is **obsolete** at HEAD — path **(a)** variant + runner eval **have landed** (see §1 **R‑4**). Only a **Director-signoff downgrade to path (b)** `ExecuteCommand` would deliberately bypass that substrate. - **STOP-C:** Per parent brief §"STOP conditions" item 2, if any T-Tier3-Dissolution mirror PR lands before Phase 1 baseline capture, the perf gate becomes **unrecoverable** without a structural reframe of the threshold (relative → absolute). This is the single most fragile sequencing constraint in the lane and should be reflected in the T-Tier3-Dissolution dispatch order — flagged as routing question §4.2. --- @@ -56,8 +56,8 @@ These are NOT decisions — they are routing questions surfaced by readiness ver 1. **Symbol-keyed vs line-keyed mirror identification:** parent brief cites `dag.rs:628-790` etc.; line ranges have drifted. Phase 1 bench groups should identify mirrors by symbol name, not line range. PB Manager confirm. 2. **Phase-1-before-dissolution sequencing enforcement:** the dispatch order between this lane's Phase 1 PR and the T-Tier3-Dissolution mirror PRs is structurally critical (STOP-C); should the C1 Phase 1 PR be a hard prerequisite in the T-Tier3-Dissolution worker dispatch (i.e., dissolution workers cannot dispatch until `tier3_baseline.json` is on `main`)? PB Manager decision; if yes, the T-Tier3-Dissolution worker pack brief (`r2-pb-tier3-mirror-dissolution-workers.md`) needs an explicit prereq row. -3. **Path (a) vs path (b) for `PerfWithinBaseline`:** Substrate Manager owns the call. Path (a) preserves structural-acceptance precision; path (b) reuses `ExecuteCommand` but loses precision (only exit code observed). Parent brief §"Acceptance gate" assumes path (a) at finalization; STOP+PING expected if Substrate Mgr chooses (b). -4. **Canonical CI machine for baseline capture:** required for Phase 1 dispatch (R-3). PB Manager designate; if no canonical host exists, escalate to Substrate Mgr (CI-infra cross-cut) before Phase 1 dispatches. +3. **Path (a) vs path (b) for `PerfWithinBaseline`:** Substrate Manager owns shape stewardship. Path **(a)** preserves structural acceptance; path **(b)** reuses `ExecuteCommand` but loses precision (only exit code observed). **Ledger reconcile (`2026-05-12`):** HEAD already lands path **(a)** (`verification.dag` declares **`PerfWithinBaseline`**; **`test_runner`** evaluates it — see §1 **R‑4`). STOP+PING applies only if a **Director‑ratified** pivot to **(b)** is chosen after all. +4. **Canonical **`cargo bench`** capture host vs merge-blocking compile fleet:** §1 **R‑3 designation** (**`ubicloud-standard-2`**) reads **MET** here (decision matrix + `tier3-baseline-capture.yml`). PB Manager confirm there is **no accidental substitution** of **`ci.yml`'s `gunbc-ci` PR pool** for authorised Ubicloud **`cargo bench`** capture when interpreting host provenance (**`captured_on.host_id`**). --- @@ -65,11 +65,11 @@ These are NOT decisions — they are routing questions surfaced by readiness ver This readiness matrix is intentionally bounded: -- §1 verifies each Phase 1 / Phase 2 prerequisite at HEAD with explicit MET / NOT MET state and routing. +- §1 verifies each Phase 1 / Phase 2 prerequisite with explicit MET / NOT MET state and routing. - §2 inventories the four mirror surfaces with drift-corrected anchors. - §3 names which STOP conditions fire / do not fire at audit time. - §4 routes 4 open questions to PB Manager / Substrate Manager / Director. -**No worker dispatch is authorized by this audit.** Phase 1 awaits R-1 + R-3; Phase 2 awaits R-4 + R-5 + R-6 + R-7. PB Manager re-reads at gate-clear per parent brief §"Dispatch preconditions." +**No worker dispatch is authorized by this audit alone.** Phase 2 awaits R‑5 + R‑6 + coherent **R‑7** and dissolution perf gate **claim** authoring (**R‑4** substrate **MET**); Phase 1 **internal** rows **R‑1 + R‑3 designation** show **MET** here while **`tier3_baseline.json` coherence / dissolution pairing** stays governed by **`R‑7` split semantics** (**PR `#2702`**, capture procedure §1). PB Manager re-reads at gate-clear per parent brief §"Dispatch preconditions." -**No code, no `criterion`, no benchmark fixtures, no `PerfWithinBaseline` variant, no fake pass/fail.** Strictly the smallest useful preparatory artifact. +**No Rust, benchmark fixtures, or `PerfWithinBaseline` variant authoring in this file — docs-only prerequisite ledger.** diff --git a/scripts/aggregate_tier3_baseline.py b/scripts/aggregate_tier3_baseline.py new file mode 100755 index 00000000000..0d2ed215866 --- /dev/null +++ b/scripts/aggregate_tier3_baseline.py @@ -0,0 +1,206 @@ +#!/usr/bin/env python3 +"""Aggregate N Criterion runs into ``tier3_baseline.json`` per ``docs/audit/c1-tier3-baseline-capture-procedure.md``. + +For each budgeted bench name, per run: invoke ``src/v3/compiler/benches/tier3_extract_perf_stats.py`` +on that run's ``sample.json``. Then ``median_ns`` = median of N per-run medians; ``p99_ns`` = max +of N per-run p99 values (R-7 conservative pin). + +``--host-id`` is stamped into ``captured_on.host_id`` exactly as supplied—there is no runner/OS probe. +Callers MUST pass the truthful capture label (paired workflow step uses ``ubicloud-standard-2`` beside +the matching ``runs-on`` VM); spoofing canonical hosts is procedural fraud, not something this CLI +automates away. + +Ubicloud captures (``.github/workflows/tier3-baseline-capture.yml``) upload **one bundle per matrix job** +(independent VMs). **Bootstrap sessions** often run **five sequential benches on one host**, then pass five +captures here—they still compute **median-of-medians / max(per-run-p99)** (R‑7 aggregation), just with +weaker temporal independence than isolated CI VMs. The **`local-*` bootstrap `tier3_baseline.json`** in +this lineage was emitted via this CLI from five sequential captures on one honest host before the +workflow became dispatchable; replacing it with the Ubicloud artifact repeats the **same formulae**. +""" + +from __future__ import annotations + +import argparse +import json +import re +import statistics +import subprocess +import sys +from datetime import datetime, timezone +from pathlib import Path + +REPO_ROOT = Path(__file__).resolve().parent.parent +EXTRACT = REPO_ROOT / "src/v3/compiler/benches/tier3_extract_perf_stats.py" +# Written by each capture job next to ``criterion/`` (same runner as the bench binary). +RUSTC_VERSION_FILE = "rustc_version.txt" + +TIER3_BENCH_ORDER: list[str] = [ + "tier3_termination_merge_evidence", + "tier3_computation_positive_descent_count", + "tier3_computation_lower_same_argument_call", + "tier3_induction_type_iteration_dimension_miss", + "tier3_effects_lane2_linear_read_chain", +] + + +def criterion_version_from_lock(repo: Path) -> str: + """Return major.minor for the workspace ``criterion`` crate from ``Cargo.lock`` (fail-closed).""" + cargo_lock = repo / "Cargo.lock" + if not cargo_lock.is_file(): + raise SystemExit(f"Cargo.lock missing (cannot record criterion_version): {cargo_lock}") + text = cargo_lock.read_text() + # Lockfile uses full semver (e.g. 0.5.1); JSON stores major.minor per procedure §4. + m = re.search( + r'\[\[package\]\]\nname = "criterion"\nversion = "([0-9]+)\.([0-9]+)(?:\.[0-9]+)?"', + text, + ) + if not m: + raise SystemExit( + 'Cargo.lock parse: no [[package]] name = "criterion" version = "…" block found ' + "(refuse fabricated criterion_version per INVARIANTS P3)" + ) + return f"{m.group(1)}.{m.group(2)}" + + +def read_consistent_rustc_version(run_bundles: list[Path]) -> str: + """Return the single ``rustc --version`` line recorded by every capture bundle. + + Provenance must come from the benchmark-producing jobs (P2: no fresh ``rustc`` read + in the aggregate environment, which may differ from the matrix runners). + """ + versions: list[str] = [] + for bundle in run_bundles: + path = bundle / RUSTC_VERSION_FILE + if not path.is_file(): + raise SystemExit( + f"missing {RUSTC_VERSION_FILE} next to criterion/ in {bundle} " + "(capture job must record rustc --version alongside Criterion output)" + ) + text = path.read_text().strip() + if not text: + raise SystemExit(f"empty {RUSTC_VERSION_FILE} in {bundle}") + versions.append(text) + distinct = sorted(set(versions)) + if len(distinct) != 1: + raise SystemExit( + f"{RUSTC_VERSION_FILE} mismatch across capture bundles: {distinct!r}" + ) + return versions[0] + + +def extract_row(extract_tool: Path, sample: Path, bench: str) -> dict: + out = subprocess.check_output( + [sys.executable, str(extract_tool), str(sample), "--name", bench], + text=True, + ) + return json.loads(out) + + +def mirror_groups_from_runs(criterion_run_dirs: list[Path]) -> dict: + benches_out: dict[str, dict] = {} + for bench in TIER3_BENCH_ORDER: + medians: list[int] = [] + p99s: list[int] = [] + for run_root in criterion_run_dirs: + sample = run_root / bench / "new" / "sample.json" + if not sample.is_file(): + raise SystemExit(f"missing sample.json for {bench}: {sample}") + row = extract_row(EXTRACT, sample, bench) + medians.append(int(row["median_ns"])) + p99s.append(int(row["p99_ns"])) + agg_median = int(round(statistics.median(medians))) + agg_p99 = max(p99s) + if agg_p99 < agg_median: + raise SystemExit( + f"aggregated p99 < median for {bench}: median={agg_median} p99={agg_p99}" + ) + if agg_median <= 0 or agg_p99 <= 0: + raise SystemExit(f"non-positive aggregate for {bench}: median={agg_median} p99={agg_p99}") + benches_out[bench] = { + "name": bench, + "median_ns": agg_median, + "p99_ns": agg_p99, + } + + return { + "termination": { + "claim": "tier3_termination_mirror_perf_within_budget", + "benches": [benches_out["tier3_termination_merge_evidence"]], + }, + "computation": { + "claim": "tier3_computation_mirror_perf_within_budget", + "benches": [ + benches_out["tier3_computation_positive_descent_count"], + benches_out["tier3_computation_lower_same_argument_call"], + ], + }, + "induction": { + "claim": "tier3_induction_mirror_perf_within_budget", + "benches": [benches_out["tier3_induction_type_iteration_dimension_miss"]], + }, + "effect_carrier": { + "claim": "tier3_effect_carrier_mirror_perf_within_budget", + "benches": [benches_out["tier3_effects_lane2_linear_read_chain"]], + }, + } + + +def main() -> int: + ap = argparse.ArgumentParser(description=__doc__) + ap.add_argument("--host-id", required=True, help="R-3 canonical host string") + ap.add_argument( + "--git-sha", + required=True, + help="40-char git SHA at capture (e.g. $GITHUB_SHA)", + ) + ap.add_argument( + "--output", + type=Path, + default=Path("tier3_baseline.json"), + help="output path", + ) + ap.add_argument( + "run_bundle_dirs", + nargs="+", + type=Path, + help="one capture bundle per independent run: must contain subdirectory " + "`criterion/` (Criterion tree) and `rustc_version.txt` from that run's host", + ) + args = ap.parse_args() + + sha = args.git_sha.strip() + if len(sha) != 40 or any(c not in "0123456789abcdef" for c in sha.lower()): + raise SystemExit(f"--git-sha must be a full 40-char hex SHA, got {sha!r}") + + if not EXTRACT.is_file(): + raise SystemExit(f"missing extraction helper: {EXTRACT}") + + run_bundles = [p.resolve() for p in args.run_bundle_dirs] + if len(run_bundles) < 3: + raise SystemExit("need at least 3 run directories (procedure N≥3)") + rustc_line = read_consistent_rustc_version(run_bundles) + criterion_roots = [] + for bundle in run_bundles: + root = bundle / "criterion" + if not root.is_dir(): + raise SystemExit(f"missing criterion/ under capture bundle {bundle}") + criterion_roots.append(root) + mg = mirror_groups_from_runs(criterion_roots) + + doc = { + "$schema": "C1 Phase 1 baseline format v1", + "captured_on": { + "host_id": args.host_id, + "git_sha": sha.lower(), + "criterion_version": criterion_version_from_lock(REPO_ROOT), + "rustc_version": rustc_line, + "captured_at": datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ"), + }, + "mirror_groups": mg, + } + args.output.write_text(json.dumps(doc, indent=2) + "\n") + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/src/v3/compiler/benches/tier3_baseline.json b/src/v3/compiler/benches/tier3_baseline.json new file mode 100644 index 00000000000..951cc2c81fa --- /dev/null +++ b/src/v3/compiler/benches/tier3_baseline.json @@ -0,0 +1,57 @@ +{ + "$schema": "C1 Phase 1 baseline format v1", + "captured_on": { + "host_id": "local-pr2702-phase1-38e365a05571", + "git_sha": "fbafcc8d38b55dbf9343a5946bc7085705bad401", + "criterion_version": "0.5", + "rustc_version": "rustc 1.93.0 (254b59607 2026-01-19)", + "captured_at": "2026-05-11T20:33:04Z" + }, + "mirror_groups": { + "termination": { + "claim": "tier3_termination_mirror_perf_within_budget", + "benches": [ + { + "name": "tier3_termination_merge_evidence", + "median_ns": 1, + "p99_ns": 2 + } + ] + }, + "computation": { + "claim": "tier3_computation_mirror_perf_within_budget", + "benches": [ + { + "name": "tier3_computation_positive_descent_count", + "median_ns": 14, + "p99_ns": 22 + }, + { + "name": "tier3_computation_lower_same_argument_call", + "median_ns": 4, + "p99_ns": 8 + } + ] + }, + "induction": { + "claim": "tier3_induction_mirror_perf_within_budget", + "benches": [ + { + "name": "tier3_induction_type_iteration_dimension_miss", + "median_ns": 8955, + "p99_ns": 12367 + } + ] + }, + "effect_carrier": { + "claim": "tier3_effect_carrier_mirror_perf_within_budget", + "benches": [ + { + "name": "tier3_effects_lane2_linear_read_chain", + "median_ns": 6, + "p99_ns": 12 + } + ] + } + } +} diff --git a/src/v3/compiler/benches/tier3_mirror_perf.rs b/src/v3/compiler/benches/tier3_mirror_perf.rs index 3853e1a4495..595d21cac2c 100644 --- a/src/v3/compiler/benches/tier3_mirror_perf.rs +++ b/src/v3/compiler/benches/tier3_mirror_perf.rs @@ -6,9 +6,12 @@ //! induction / effect-carrier). See that brief for thresholds (≤2× median, //! ≤5× p99) and Phase 1 / Phase 2 split. //! -//! **Frozen baseline** (`tier3_baseline.json`, deliverable 0c): not committed by -//! this skeleton. Capture median + p99 (ns) per group on the canonical CI -//! machine after this bench is stable, then commit JSON per the worker brief. +//! **Frozen baseline** (`tier3_baseline.json` alongside this bench): Phase-1 +//! committed median + p99 (ns) per budgeted `bench_function` (regen via +//! ``scripts/aggregate_tier3_baseline.py`` + procedure at +//! `docs/audit/c1-tier3-baseline-capture-procedure.md`). Ubicloud canonical +//! recapture uses `.github/workflows/tier3-baseline-capture.yml` (diff against +//! the committed JSON; baseline updates land only through PR). use criterion::{black_box, criterion_group, criterion_main, Criterion}; use v3_compiler::dag::{