Skip to content

Failure-process hardening: annotate silent results, detect same-failure repairs, thread requirements into checkers#88

Open
davidrhodus wants to merge 5 commits into
mainfrom
feat/failure-process-hardening
Open

Failure-process hardening: annotate silent results, detect same-failure repairs, thread requirements into checkers#88
davidrhodus wants to merge 5 commits into
mainfrom
feat/failure-process-hardening

Conversation

@davidrhodus

Copy link
Copy Markdown
Contributor

Four changes motivated by "Failure as a Process: An Anatomy of CLI Coding Agent Trajectories" (arXiv:2607.09510) — 1,794 trajectories showing coding-agent failures dominated by epistemic errors (57.9%; false premises 30.7%), with wrong-problem repair consuming 39% of wasted execution and 26% of failed runs fabricating success.

  • feat(tools): annotate silent shell results. Empty success → [no output — command succeeded (exit 0)]; stderr-only success and empty failure annotated; successful cd commands get a just-in-time cwd-reset note. Fixes the steering timed-out matcher (matched a never-emitted string).
  • feat(agent): detect same-failure verify rounds. Verifier hashes each failure (stage, exit code, digit/hex-masked output); an unchanged signature escalates the nudge to demand a validated diagnosis. New repeated_verify_failures telemetry + report key. Nudge-only in v1.
  • feat(agent): thread verbatim task requirements (bounded ~1.5 KB digest) into verify nudges and the independent review, which previously never saw the prompt.
  • feat(agent): make skipped reviews and unverified turns visible — trio fail-open books skeptic telemetry + explicit TUI warning; one-shot stderr trailer for unverified mutations; regression tests lock honest outcomes.

Evidence

  • ~1,120 tests green per commit (clippy -D warnings, fmt); ~20 new tests; mechanisms live-verified with real models.
  • ~1,000 paired A/B runs across four regimes (coder-balanced, glm-5.2-fast, qwen2.5-coder:7b × spec/hard/hidden/vloop/vloop-dense/premise): zero pass-rate differences (paired McNemar all n.s.), honesty metrics even.
  • Known cost caveat: on unrecoverable repair loops with a weak 7B model, richer nudges add ~+36% tokens (sign p=0.004) without changing outcomes — motivates the follow-up of ending doomed loops on the second identical failure instead of nudging again. Strong-model regimes were cost-neutral.
  • repeated_verify_failures fired on real Terminal-Bench tasks in the new Harbor integration.

🤖 Generated with Claude Code

David and others added 5 commits July 15, 2026 08:15
Empty and stderr-only results are where models form false premises
("did it work?" / "stderr means it failed") — the largest failure
trigger in Zhao et al.'s CLI-agent trajectory study (arXiv:2607.09510,
false premises = 30.7% of decisive errors). Make the verdict explicit:

- empty success:        [no output — command succeeded (exit 0)]
- stderr-only success:  [command succeeded (exit 0) — output above is stderr]
- empty failure:        [exit code N — no output on stdout or stderr]
- successful commands containing a `cd` segment get a note that the
  working directory resets before the next command (just-in-time
  version of the system-prompt warning)

Success annotations never contain "[exit code " — steering classifies
that marker as failure. Also fix the steering timed-out matcher, which
looked for "[timed out after " while the emitted text is
"[timed out — process killed]".

Co-Authored-By: Claude Fable 5 <[email protected]>
"Repairing the wrong problem" is the costliest coding-agent failure
behavior (39% of wasted execution in arXiv:2607.09510). The verifier
now hashes each failure (stage, exit code, digit/hex-masked output) and
compares rounds: when a repair didn't change the failure signature, the
verify nudge stops saying "reconsider" and instead demands a validated
diagnosis via a discriminating probe before any further edit.

Line/column drift is masked so an edit that only shifts code is still
recognized as the same failure. Unstable-stage failures keep their own
escalation (stage_mutation_counts) and are excluded. Nudge-only in v1 —
no control-flow change; `repeated_verify_failures` telemetry (report
key added) will show whether burning rounds is worth it.

Co-Authored-By: Claude Fable 5 <[email protected]>
… review

Supplying the task's requirements to a checker is the single biggest
recall lever for specification-relative failures (arXiv:2607.09510:
ignored-requirement recall 3%->22%, false premises 15%->32% once the
monitor sees the spec). The independent review previously saw only the
derived TaskContract + diff; the verify-failure nudge saw no
requirement text at all.

TaskContract::requirements_digest builds a bounded (~1.5 KB) digest —
derived acceptance sentences plus a verbatim prompt excerpt — computed
once per turn and injected into (1) the verify-failure nudge and
(2) the independent review context. Deterministic only: no side-call,
no config, no latency.

Co-Authored-By: Claude Fable 5 <[email protected]>
Fabricated success clusters exactly where verification is absent
(26% of failed trajectories in arXiv:2607.09510, beginning at the
point of no return). VerificationStatus::Unverified already gates
status and exit codes end-to-end; this closes the residual gaps:

- trio review stays fail-open, but an Unavailable verdict now books
  skeptic_unavailable_count / skeptic_last_status telemetry and the
  TUI prints an explicit "approved WITHOUT review" warning instead
  of a dim aside
- one-shot runs print a deterministic stderr trailer when changes
  were made but no verification stage ran — emitted regardless of
  --allow-unverified (the flag changes the exit code, not the truth)
- regression tests lock the honest outcomes: round-cap exhaustion
  reports Failed+Incomplete, mutation without stages reports
  Unverified, and --allow-unverified completes the turn without
  laundering the verification status

Co-Authored-By: Claude Fable 5 <[email protected]>
cargo fmt on the core crates plus the two clippy -D warnings failures
the trio commit introduced (doc list continuation in trio.rs, nested if
in parse_trio_args). hi-mlx formatting is left untouched — it doesn't
build everywhere and is outside the CI crate list, though note that
`cargo fmt --all --check` still fails on it.

Co-Authored-By: Claude Fable 5 <[email protected]>
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