PLAN Loop Engineering
August 9, 2026 · View on GitHub
Loop engineering = running the VT Code harness repeatedly, with isolation and durable state, so long-horizon work makes monotonic progress.
This document describes the loop-engineering substrate that lets a plan
(generated once) drive many execution steps without losing context or
colliding with itself. It pairs with
agent-capability-composition.md:
a loop is where the "keep getting closer to completion" invariant is exercised
at scale.
Principles
- Worktree isolation. Each spawned sub-agent with
isolation = "worktree"gets its own git worktree under.vtcode/worktrees/. File mutations stay in the child's working tree until explicitly merged, so parallel loop runs never collide on the working tree. - Propose / verify separation.
SubagentController::verify_proposed_change()spawns a read-only verifier that re-reads affected files and approves or rejects the change. The verifier shares no context with the proposer. - Loop state persistence.
crates/codegen/vtcode-core/src/loop_state.rscaptures the durable state a loop scheduler reads on resume: current step index, last artifact path, and status. State lives under.vtcode/state/loop-{id}.json. - Cost guardrails. Long loops accrue spend;
SessionBudget(crates/codegen/vtcode-core/src/llm/usage_cost.rs) pauses or escalates at thresholds so a loop cannot run unbounded. - Progress over time. The
ProgressLedger(crates/codegen/vtcode-memory/src/progress.rs) andProgressMonitor(crates/codegen/vtcode-core/src/core/agent/progress_monitor.rs) give the loop an external, compaction-safe signal of goal progress and detect stalls. - Evidence-bounded self-improvement. Evaluator observations are bounded task-scoped notes with a claim, scope, evidence, and falsifier. Replanning must preserve each scope and add each falsifier to the tracker; notes are not promoted into global beliefs or persistent memory automatically.
The guidance follows Bennett, The Optimal Choice of Hypothesis Is the Weakest, Not the Shortest: choose the weakest sufficient hypothesis, preserve its scope, and keep a concrete falsifier close to the evidence. A local observation should not become a general rule merely because it is concise or reusable.
Lifecycle
plan ──► loop scheduler ──► spawn child (worktree)
└──► child proposes change
└──► verifier approves/rejects
└──► merge or retry
└──► record progress, next step
The scheduler reads LoopRunState on resume to know where execution left off,
and reads the ProgressLedger to decide whether the loop is actually
advancing or should escalate.
Evidence-bounded replanning
The evaluator may emit at most eight notes. Each note is normalized and
validated before it is rendered into current_evaluation.md. A replan receives
the validated notes, repeats every scope verbatim, and creates tracker
verification steps from the falsifiers. The evaluation artifact and execution
contract are the task-local record; the loop does not write these observations
to global beliefs or cross-session memory as a side effect.
Cross-references
- Harness invariants:
docs/harness/ARCHITECTURAL_INVARIANTS.md - Agent loop contract:
docs/guides/agent-loop-contract.md - Capability composition:
docs/guides/agent-capability-composition.md