Skip to content

fix(autopilot): wire the runaway backstop (guardTripped) into the loop - #331

Merged
dngioidev merged 1 commit into
mainfrom
fix/317-autopilot-runaway-guard-wired
Aug 1, 2026
Merged

fix(autopilot): wire the runaway backstop (guardTripped) into the loop#331
dngioidev merged 1 commit into
mainfrom
fix/317-autopilot-runaway-guard-wired

Conversation

@dngioidev

Copy link
Copy Markdown
Owner

Closes #317 (parent epic #183)

Problem

ledger.mjs exports guardTripped(run, boardSize, factor=2) — a correct, tested pure fn bounding a file-a-ticket-per-iteration runaway (max iterations = board size × factor) — but it had no runtime caller. The loop was prose in SKILL.md, so the runaway was bounded only by orchestrator discipline, not by code.

Change (thin, mirrors #316's pattern)

  • nextIteration(run, boardSize, factor=2) added to ledger.mjs: the pure per-iteration guard the orchestrator is contractually required to call first each iteration. It reads the persisted iteration counter (run.iterations, maintained by applyOutcome → resume-safe & auditable) and delegates the trip test to guardTripped, returning { stop, escalate, iterations, cap, reason }. A trip is a halt + escalate decision, not a silent continue. It never mutates the run, so the natural stop (board clear) and --limit are untouched.
  • SKILL.md now makes the backstop a code call, not prose: the loop diagram calls nextIteration at the top of every iteration; the Loop-backstop rail is mechanical; the driver-scripts list names it as guardTripped's real caller.

Acceptance criteria

  • AC.1 — the loop invokes guardTripped each iteration and escalates/stops when it trips. nextIteration is that caller (delegates to guardTripped, returns stop/escalate); SKILL.md's loop calls it first each iteration and halts+escalates on a trip. Verified by AC-317.1 + AC-317.2.
  • AC.2 — test simulates a runaway and asserts the guard halts the loop. AC-317.2 runs a non-converging loop (files + records an outcome every iteration) with a 1000-iteration safety cap and asserts the guard halts it at exactly board size × 2 (6 on boardSize 3), with escalate:true and a runaway backstop tripped reason — so the guard, not the safety cap, stopped it.

Verification

  • pnpm verify: 605/605 passing (was 600; +2 new AC-317 tests, existing autopilot tests unchanged).
  • Editing repo autopilot code does not affect the live installed cache run.

🤖 Generated with Claude Code

guardTripped bounds a file-a-ticket-per-iteration runaway (max iterations =
board size × factor) but had NO runtime caller — the loop was prose in
SKILL.md, so the backstop rested on orchestrator discipline alone (#317).

Add ledger.mjs `nextIteration(run, boardSize, factor=2)`: the pure per-iteration
guard the orchestrator is contractually required to call FIRST each iteration. It
reads the persisted iteration counter (run.iterations, maintained by applyOutcome,
so the bound is resume-safe and auditable) and delegates the trip test to
guardTripped, returning `{ stop, escalate, iterations, cap, reason }`. A trip is a
halt+escalate decision (not a silent continue); it never mutates the run, so the
natural stop (board clear) and --limit stay intact.

SKILL.md now documents the guard as a code call, not prose: the loop diagram calls
nextIteration at the top of every iteration, the Loop-backstop rail is mechanical,
and the driver-scripts list names nextIteration as guardTripped's real caller.

Tests (engine.test.mjs): AC-317.1 the guard is invoked and returns continue under
the cap (delegates to guardTripped, honours factor + boardSize floor); AC-317.2 a
simulated non-converging runaway is halted by the guard at board size × factor
(exactly 6 iterations on boardSize 3, then halt+escalate).

Closes #317

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SATRHKa6mDHDuirhP6QuwL
@dngioidev
dngioidev merged commit 1caf90f into main Aug 1, 2026
6 checks passed
@dngioidev
dngioidev deleted the fix/317-autopilot-runaway-guard-wired branch August 1, 2026 17:56
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.

autopilot: wire the runaway backstop (guardTripped) into the loop

1 participant