| name | debug-loop |
| description | Systematic debugging playbook for the Forge agentic loop (src/core/loop.ts and src/agents/executor.ts). Use when a task is stuck, looping, or producing wrong tool calls. |
/debug-loop — debug the agentic loop
The loop is the single most expensive place to be wrong. Before you
change anything, instrument.
1. Reproduce deterministically
- Run with
FORGE_LOG_LEVEL=debug ./bin/forge.js <command>.
- Capture a session id. Events are in
~/.config/forge/events/<session>.ndjson.
- If the bug only repro's against a real provider, pin to a single
model and disable the router's fallback:
FORGE_MODEL=... FORGE_ROUTER_FALLBACK=0.
2. Read the event stream, not the terminal
Each turn emits: turn.start, model.call, tool.call, tool.result,
validation.result, turn.end. If any stage is missing or out of
order, that is your bug. Grep the ndjson before staring at code.
3. Check the usual suspects, in order
- Mode caps (
src/core/mode-policy.ts) — is the agent hitting the
turn/token cap and being cut off? The event will say so.
- Validation gate (
src/core/validation.ts) — is the gate
rejecting a valid step? Look at validation.result.reason.
- Tool registry — is the tool the model asked for actually
registered?
tool.call with class: not_found means no.
- Permissions — is the call being silently denied?
tool.result.denied=true in the stream.
- State machine (
src/persistence/tasks.ts) — is an illegal
transition being attempted?
4. Add a failing test before the fix
- Unit-test the smallest failing path with
callModel mocked.
- If the bug is in the loop itself,
test/unit/executor-loop.test.ts
is the template.
5. Fix, then verify
Run /verify. If the test you added doesn't turn green, you fixed the
wrong thing.