Skip to main content

harness_loop_engine/
lib.rs

1//! # harness-loop-engine — loop engineering for harness-rs
2//!
3//! *Agent = Model + Harness.* A **harness** wraps a single agent call. A
4//! **loop** wraps the harness: it runs that call again and again, on a
5//! cadence, with state, verification, budgets, and gates — driving toward a
6//! goal over time instead of in one shot. This crate is harness-rs's loop
7//! layer.
8//!
9//! > "Loop engineering is replacing yourself as the person who prompts the
10//! > agent. You design the system that does it instead." — and you stay the
11//! > engineer responsible for that system.
12//!
13//! The building blocks already live elsewhere in harness-rs — scheduling
14//! (`harness-scheduler`), worktrees (`harness-sandbox`), sub-agents
15//! (`harness-loop`), memory (`harness-core`), MCP (`harness-mcp`). What this
16//! crate adds is the **orchestration discipline** that turns those parts
17//! into a loop you can trust:
18//!
19//! - [`LoopLevel`] — maturity levels **L1 (report) → L2 (assisted) → L3
20//!   (unattended)**. A loop earns autonomy in stages.
21//! - [`HumanGate`] — the proceed-or-escalate decision, tied to the level.
22//!   Built-ins: [`AlwaysEscalate`], [`AllowlistGate`], [`CallbackGate`].
23//! - [`ActionExecutor`] — the side-effect handoff after a verified L3
24//!   auto-approval. Built-ins: [`ApprovalOnlyExecutor`],
25//!   [`CallbackActionExecutor`].
26//! - [`TokenBudget`] — a per-round spend ceiling, because unattended loops
27//!   spend without bound if you let them.
28//! - [`LoopSpec`] — the inert, serializable description of a loop.
29//! - [`LoopEngine`] — the runner: recall state → isolate → **maker**
30//!   sub-agent → **checker** sub-agent → gate → record state.
31//! - [`LoopScheduler`] — runs loops on their cadence.
32//! - [`patterns`] — the seven named production loops (daily triage, PR
33//!   babysitter, CI sweeper, …), each a ready-made [`LoopSpec`].
34//!
35//! ## The anatomical loop
36//!
37//! ```text
38//!   schedule (cadence)
39//!        │
40//!        ▼
41//!   recall STATE / memory ──► isolated worktree (sandbox)
42//!        │                          │
43//!        │                          ▼
44//!        │                  maker sub-agent  (proposes)
45//!        │                          │
46//!        │                          ▼
47//!        │                  checker sub-agent  (tests + gates)
48//!        │                          │
49//!        │                          ▼
50//!        │                     human gate? ──┬─ safe/allowlisted ─► action executor
51//!        │                                   └─ risky/ambiguous ──► escalate
52//!        ▼                                            │
53//!   write STATE / memory  ◄────────────────────────── recurse next tick
54//! ```
55//!
56//! ## Two debts to watch
57//!
58//! Loop engineering names two failure modes that accrue silently. This
59//! crate makes them *visible* rather than solving them — they are
60//! engineering responsibilities, not features:
61//!
62//! - **Intent debt** — the drift between what a loop was *meant* to do and
63//!   what it actually does. Antidote: [`LoopSpec::intent`] is a required,
64//!   one-sentence statement of purpose, injected into every maker turn and
65//!   printed in every report. Review it as the loop evolves.
66//! - **Comprehension debt** — the gap between what the loop ships and what
67//!   humans still understand about its behaviour. Antidote: the
68//!   maker/checker split, the recorded state spine, and rendered reports
69//!   keep a legible trail of every round.
70//!
71//! ## Safety stance
72//!
73//! Verification stays on you — unattended loops make unattended mistakes.
74//! Defaults are conservative: L1 makers are strictly read-only, the default
75//! gate for every level is [`AlwaysEscalate`], and L3 auto-proceed requires
76//! an explicit [`AllowlistGate`]. Graduate a loop's level only as you build
77//! trust in it.
78
79mod budget;
80mod engine;
81mod level;
82pub mod patterns;
83mod scheduler;
84mod spec;
85
86pub use budget::{BudgetLimit, BudgetState, TokenBudget};
87pub use engine::{
88    ActionError, ActionExecutor, ActionReceipt, ApprovalOnlyExecutor, CallbackActionExecutor,
89    LoopEngine, RoundOutcome, RoundReport,
90};
91pub use level::{
92    AllowlistGate, AlwaysEscalate, CallbackGate, GateDecision, HumanGate, LoopLevel,
93    ProposedAction, default_gate_for,
94};
95pub use scheduler::{LoopScheduler, LoopSink, StdoutSink};
96pub use spec::LoopSpec;