mirror of
https://github.com/bdbrown4/peltier.io.git
synced 2026-11-07 10:58:28 +00:00
gates: verdict pipeline — gates + bench + ledger row, pristine-rebuilt baselines
Adds crates/verdict ('just verdict'): runs the core gates on the
candidate binary, then an interleaved A/B bench vs the baseline with
the CI-lower-bound rule, and writes the append-only ledger row with
per-side median CIs, workload statement, and env fingerprint. Gate
failure short-circuits to rejected-gate; --needs-human-review caps an
accepted verdict (never upgrades). CPU pinning moves into accept.toml
(pin_prefix, machine-specific, applied to both sides identically).
The smoke test caught a real trust gap: pointing --baseline-bin at the
workspace build (phase1-verdict-smoke-001) measured patched-vs-patched
and returned null, because gate runs rebuild the workspace binary from
the patched tree. Fix: --rebuild-baseline stashes the patch, builds
the baseline into isolated targets/<name>/baseline/, and restores the
patch — SPEC 3.1's pristine-checkout rule, now enforced by the
harness. Re-run (phase1-verdict-smoke-002) reproduces the Phase 0
result mechanically: +10.4% median, 95% CI [1.0932, 1.1137], accepted.
Both smoke rows are in the ledger, including the null one.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EcKPWQ3MQD4NdEHwar96u2
This commit is contained in:
@@ -0,0 +1,78 @@
|
||||
//! Core gate sequence, callable from the diff-test CLI and from verdict:
|
||||
//! corpus pin (refuses on mismatch) → upstream tests → golden replay.
|
||||
|
||||
use crate::target::{expected_golden_hash, TargetSpec};
|
||||
use crate::{pin, GateLayer, GateOutcome};
|
||||
use sha2::{Digest, Sha256};
|
||||
use std::path::Path;
|
||||
use std::process::{Command, Stdio};
|
||||
|
||||
fn sh(root: &Path, cmd: &str) -> anyhow::Result<std::process::Output> {
|
||||
Ok(Command::new("sh")
|
||||
.arg("-c")
|
||||
.arg(cmd)
|
||||
.current_dir(root)
|
||||
.stdout(Stdio::piped())
|
||||
.stderr(Stdio::piped())
|
||||
.output()?)
|
||||
}
|
||||
|
||||
/// Run the mechanical gates for `target`, testing `binary` (repo-root-
|
||||
/// relative) in the golden replay. Corpus-pin mismatch is an error, not
|
||||
/// a gate failure: nothing runs on a tampered corpus.
|
||||
pub fn run_core_gates(
|
||||
root: &Path,
|
||||
spec: &TargetSpec,
|
||||
binary: &str,
|
||||
) -> anyhow::Result<Vec<(GateLayer, GateOutcome)>> {
|
||||
let verified = pin::verify_manifest(
|
||||
&root.join(&spec.corpus.manifest),
|
||||
&root.join(&spec.corpus.root),
|
||||
)?;
|
||||
eprintln!(
|
||||
"corpus pin: {verified} files verified against {}",
|
||||
spec.corpus.manifest.display()
|
||||
);
|
||||
|
||||
let mut results = Vec::new();
|
||||
|
||||
let t = sh(root, &spec.gates.tests)?;
|
||||
results.push((
|
||||
GateLayer::UpstreamTests,
|
||||
if t.status.success() {
|
||||
GateOutcome::Passed
|
||||
} else {
|
||||
GateOutcome::Failed {
|
||||
detail: String::from_utf8_lossy(&t.stderr).chars().take(2000).collect(),
|
||||
}
|
||||
},
|
||||
));
|
||||
|
||||
let g = sh(root, &spec.gates.golden.replace("{binary}", binary))?;
|
||||
let expected = expected_golden_hash(&root.join(&spec.corpus.golden_sha256))?;
|
||||
let actual = format!("{:x}", Sha256::digest(&g.stdout));
|
||||
results.push((
|
||||
GateLayer::GoldenReplay,
|
||||
if g.status.success() && actual == expected {
|
||||
GateOutcome::Passed
|
||||
} else {
|
||||
GateOutcome::Failed {
|
||||
detail: format!("exit={:?} expected={expected} actual={actual}", g.status.code()),
|
||||
}
|
||||
},
|
||||
));
|
||||
|
||||
results.push((
|
||||
GateLayer::DifferentialFuzz,
|
||||
GateOutcome::Skipped {
|
||||
reason: "per-attempt manual step in Phase 1 (needs old/new pair)".into(),
|
||||
},
|
||||
));
|
||||
results.push((
|
||||
GateLayer::Sanitizers,
|
||||
GateOutcome::Skipped {
|
||||
reason: "per-attempt manual step in Phase 1 (nightly toolchain)".into(),
|
||||
},
|
||||
));
|
||||
Ok(results)
|
||||
}
|
||||
Reference in New Issue
Block a user