mirror of
https://github.com/bdbrown4/peltier.io.git
synced 2026-11-07 10:58:28 +00:00
bench: cache+branch-sim profiles, hypothesis-granular ledger memory, long-poll read_verdict
- Profiles regenerated with callgrind --cache-sim --branch-sim for both targets: per-function D1/LL miss and branch-mispredict columns unlock playbook class-4 preconditions (comrak: syntect write_highlighted owns 31% of D1 read misses; tokei: parse_lines owns 56% of Ir). - tokei workspace: accepted Phase 0 wins banked as a local commit so stash-based baseline rebuilds attribute only the marginal patch to new attempts (false-accept trap closed before grinding). - read_ledger now returns per-attempt history (class, hotspot, hypothesis, verdict): a class may be re-entered with a materially new hypothesis, never a duplicate one. Task prompt updated to match. - read_verdict long-polls the ledger up to 45s server-side (under the 60s MCP cap), cutting the agent's polling turn burn ~15x. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EcKPWQ3MQD4NdEHwar96u2
This commit is contained in:
@@ -84,7 +84,21 @@ fn serve_socket(root: &Path, sock: &Path) -> Result<()> {
|
||||
}
|
||||
|
||||
fn respond(root: &Path, line: &str) -> Value {
|
||||
let _guard = HANDLE_LOCK.lock().unwrap_or_else(|p| p.into_inner());
|
||||
// read_verdict long-polls the ledger (read-only) and must not hold
|
||||
// the lock that serializes mutating ops while it sleeps.
|
||||
let is_read_verdict = serde_json::from_str::<Value>(line)
|
||||
.ok()
|
||||
.and_then(|v| {
|
||||
v.get("op")
|
||||
.and_then(Value::as_str)
|
||||
.map(|o| o == "read_verdict")
|
||||
})
|
||||
.unwrap_or(false);
|
||||
let _guard = if is_read_verdict {
|
||||
None
|
||||
} else {
|
||||
Some(HANDLE_LOCK.lock().unwrap_or_else(|p| p.into_inner()))
|
||||
};
|
||||
match handle(root, line) {
|
||||
Ok(v) => json!({"ok": true, "result": v}),
|
||||
Err(e) => json!({"ok": false, "error": e.to_string()}),
|
||||
@@ -143,7 +157,14 @@ fn handle(root: &Path, line: &str) -> Result<Value> {
|
||||
// Read-only surface over the append-only DB.
|
||||
let ledger = ledger::Ledger::open(&root.join("results/ledger.sqlite"))?;
|
||||
let classes = ledger.attempted_classes(t)?;
|
||||
Ok(json!({"attempted_playbook_classes": classes, "total_attempts": ledger.count()?}))
|
||||
let history = ledger.attempt_history(t)?;
|
||||
Ok(json!({
|
||||
"attempted_playbook_classes": classes,
|
||||
"attempts": history,
|
||||
"total_attempts": ledger.count()?,
|
||||
"note": "a class may be re-entered with a materially NEW hypothesis; \
|
||||
never duplicate a (hotspot, class, hypothesis) that has a verdict",
|
||||
}))
|
||||
}
|
||||
"read_playbook" => {
|
||||
let class = match req.get("class") {
|
||||
@@ -303,11 +324,21 @@ fn handle(root: &Path, line: &str) -> Result<Value> {
|
||||
}
|
||||
"read_verdict" => {
|
||||
let run_id = field(&req, "run_id")?;
|
||||
let ledger = ledger::Ledger::open(&root.join("results/ledger.sqlite"))?;
|
||||
match ledger.verdict_summary(run_id)? {
|
||||
Some(v) => Ok(v),
|
||||
None => Ok(json!({"status": "running",
|
||||
"note": "no ledger row yet; the pipeline is still building/benching"})),
|
||||
// Long-poll: the pipeline runs for minutes and the MCP transport
|
||||
// caps a tool call at 60s. Waiting ~45s server-side per poll cuts
|
||||
// the agent's turn burn ~15x versus instant "running" replies.
|
||||
let deadline = std::time::Instant::now() + std::time::Duration::from_secs(45);
|
||||
loop {
|
||||
let ledger = ledger::Ledger::open(&root.join("results/ledger.sqlite"))?;
|
||||
if let Some(v) = ledger.verdict_summary(run_id)? {
|
||||
return Ok(v);
|
||||
}
|
||||
drop(ledger);
|
||||
if std::time::Instant::now() >= deadline {
|
||||
return Ok(json!({"status": "running",
|
||||
"note": "no ledger row yet; the pipeline is still building/benching — poll again"}));
|
||||
}
|
||||
std::thread::sleep(std::time::Duration::from_secs(3));
|
||||
}
|
||||
}
|
||||
other => Err(anyhow!(
|
||||
|
||||
@@ -165,6 +165,27 @@ impl Ledger {
|
||||
Ok(rows.collect::<Result<Vec<_>, _>>()?)
|
||||
}
|
||||
|
||||
/// Per-attempt history for a target: class, hotspot, hypothesis,
|
||||
/// verdict. The agent's anti-duplicate memory at hypothesis
|
||||
/// granularity — a class may be re-entered with a materially new
|
||||
/// hypothesis, but never the same (hotspot, class, hypothesis).
|
||||
pub fn attempt_history(&self, target: &str) -> Result<Vec<serde_json::Value>, LedgerError> {
|
||||
let mut stmt = self.conn.prepare(
|
||||
"SELECT run_id, playbook_class, hotspot, hypothesis, verdict \
|
||||
FROM attempts WHERE target = ?1 ORDER BY rowid",
|
||||
)?;
|
||||
let rows = stmt.query_map([target], |r| {
|
||||
Ok(serde_json::json!({
|
||||
"run_id": r.get::<_, String>(0)?,
|
||||
"playbook_class": r.get::<_, u8>(1)?,
|
||||
"hotspot": r.get::<_, String>(2)?,
|
||||
"hypothesis": r.get::<_, String>(3)?,
|
||||
"verdict": r.get::<_, String>(4)?,
|
||||
}))
|
||||
})?;
|
||||
Ok(rows.collect::<Result<Vec<_>, _>>()?)
|
||||
}
|
||||
|
||||
/// Read-only verdict summary for one run — the agent's only window
|
||||
/// onto a completed attempt (harnessd `read_verdict`). Returns the
|
||||
/// verdict plus the bench CIs; never enough to game, since the row
|
||||
|
||||
Reference in New Issue
Block a user