#![allow(clippy::unwrap_used, clippy::expect_used)]
use std::sync::Arc;
use std::time::Duration;
use axum::routing::post;
use axum::{Json, Router};
use bytes::Bytes;
use firstpass_core::{GENESIS_HASH, verify_chain};
use firstpass_proxy::provider::ProviderRegistry;
use firstpass_proxy::proxy::AppState;
use firstpass_proxy::{ProxyConfig, app, store};
use serde_json::{Value, json};
#[tokio::main]
async fn main() {
let upstream = spawn_upstream().await;
let db = std::env::temp_dir().join(format!("firstpass-demo-{}.db", uuid::Uuid::now_v7()));
let proxy = spawn_proxy(&upstream, &db).await;
println!(
"\n\x1b[1mFirstpass demo\x1b[0m — routing one request through a real enforce ladder\n"
);
let client = reqwest::Client::new();
let served: Value = client
.post(format!("{proxy}/v1/messages"))
.header("x-api-key", "byok-demo")
.json(&json!({
"model": "claude-haiku-4-5",
"max_tokens": 256,
"messages": [{ "role": "user", "content": "write a hello world in rust" }],
}))
.send()
.await
.expect("request")
.json()
.await
.expect("json");
println!("served output : {}", served["content"][0]["text"]);
println!("served model : {}\n", served["model"]);
let trace = wait_for_trace(&db).await;
println!("\x1b[1m── audit receipt ──────────────────────────────────\x1b[0m");
for a in &trace.attempts {
let verdict = match a.verdict {
firstpass_core::Verdict::Pass => "\x1b[32mPASS\x1b[0m",
firstpass_core::Verdict::Fail => "\x1b[31mFAIL\x1b[0m",
firstpass_core::Verdict::Abstain => "\x1b[33mABSTAIN\x1b[0m",
};
println!(
" rung {} · {:<28} · {verdict} · ${:.4}",
a.rung, a.model, a.cost_usd
);
}
let f = &trace.final_;
println!(" ─────────────────────────────────────────────────");
println!(" total ${:.4}", f.total_cost_usd);
println!(
" baseline ${:.4} (always top-tier)",
f.counterfactual_baseline_usd
);
println!(
" \x1b[32mSAVED ${:.4} ({:.0}% cheaper at proven quality)\x1b[0m",
f.savings_usd,
if f.counterfactual_baseline_usd > 0.0 {
f.savings_usd / f.counterfactual_baseline_usd * 100.0
} else {
0.0
}
);
println!(" trace_id {}", trace.trace_id);
println!(
" chain {}\n",
if verify_chain(std::slice::from_ref(&trace), &trace.prev_hash).is_ok() {
"verified ✓"
} else {
"BROKEN"
}
);
let trace_id = trace.trace_id.to_string();
let fb = client
.post(format!("{proxy}/v1/feedback"))
.json(&json!({ "trace_id": trace_id, "gate_id": "ci-tests", "verdict": "pass", "reporter": "github-actions" }))
.send()
.await
.expect("feedback");
println!(
"feedback POST /v1/feedback → {} (downstream outcome recorded)",
fb.status()
);
let view = store::load_trace_view(&db, &trace_id)
.expect("view")
.expect("trace");
println!(
"deferred verdicts on trace: {} ({} reported it)",
view.deferred.len(),
view.deferred[0].reporter
);
let all = store::load_all_traces(&db).expect("all");
println!(
"audit chain after feedback : {}\n",
if verify_chain(&all, GENESIS_HASH).is_ok() {
"\x1b[32mstill verified ✓\x1b[0m — the sealed record never changed"
} else {
"BROKEN"
}
);
let _ = std::fs::remove_file(&db);
}
async fn spawn_upstream() -> String {
async fn messages(body: Bytes) -> Json<Value> {
let model = serde_json::from_slice::<Value>(&body)
.ok()
.and_then(|v| v.get("model").and_then(Value::as_str).map(str::to_owned))
.unwrap_or_default();
let text = if model.contains("haiku") {
""
} else {
"fn main() { println!(\"hello world\"); }"
};
Json(json!({
"id": "msg_demo", "type": "message", "role": "assistant", "model": model,
"content": [{ "type": "text", "text": text }],
"usage": { "input_tokens": 1200, "output_tokens": 220 },
}))
}
let router = Router::new().route("/v1/messages", post(messages));
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();
tokio::spawn(async move { axum::serve(listener, router).await.unwrap() });
format!("http://{addr}")
}
async fn spawn_proxy(upstream: &str, db: &std::path::Path) -> String {
let routing = "[[route]]\nmatch = {}\nmode = \"enforce\"\nladder = [\"anthropic/claude-haiku-4-5\", \"anthropic/claude-sonnet-5\", \"anthropic/claude-opus-4-8\"]\ngates = [\"non-empty\"]\n";
let (up, dbs) = (upstream.to_owned(), db.to_string_lossy().into_owned());
let config = ProxyConfig::from_lookup(move |k| match k {
"FIRSTPASS_UPSTREAM_ANTHROPIC" => Some(up.clone()),
"FIRSTPASS_MODE" => Some("enforce".to_owned()),
"FIRSTPASS_CONFIG_TOML" => Some(routing.to_owned()),
"FIRSTPASS_DB" => Some(dbs.clone()),
_ => None,
})
.unwrap();
let providers = ProviderRegistry::new(&config.upstream_anthropic, &config.upstream_openai);
let (traces, _writer) = store::open(db).unwrap();
let state = AppState {
config: Arc::new(config),
http: reqwest::Client::new(),
providers,
gate_health: Arc::new(firstpass_proxy::gate::GateHealthRegistry::new()),
traces,
adaptive: None,
};
let listener = tokio::net::TcpListener::bind("127.0.0.1:0").await.unwrap();
let addr = listener.local_addr().unwrap();
tokio::spawn(async move { axum::serve(listener, app(state).unwrap()).await.unwrap() });
format!("http://{addr}")
}
async fn wait_for_trace(db: &std::path::Path) -> firstpass_core::Trace {
for _ in 0..150 {
if let Ok(t) = store::load_all_traces(db)
&& let Some(first) = t.into_iter().next()
{
return first;
}
tokio::time::sleep(Duration::from_millis(20)).await;
}
panic!("no trace recorded");
}