Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
8f711c1
Name the four assumptions the tool path is built on
nvdorman Aug 13, 2026
3a406d0
Plan the tool-path determinism refactor as nine tested tasks
nvdorman Aug 13, 2026
169269d
Cut text on runes, not bytes
nvdorman Aug 13, 2026
3fe1cb9
Cut tool output on runes too
nvdorman Aug 13, 2026
c9da061
Pin the two character budgets that were hand-written
nvdorman Aug 13, 2026
907dff0
Match a tool result to its call by id
nvdorman Aug 13, 2026
e715bbd
Bind a tool result inside its own turn before looking further
nvdorman Aug 13, 2026
e5f5aa9
Tell a stuck loop apart from ordinary progress
nvdorman Aug 13, 2026
2e6e1a2
Cover every tool name the repeat guard used to special-case
nvdorman Aug 13, 2026
bf29f63
Stop a stalled follower from crashing its own stream
nvdorman Aug 13, 2026
3fefdf1
Scan for danger by what a tool can do
nvdorman Aug 13, 2026
50e1fa4
Read a command the way the shell will read it
nvdorman Aug 13, 2026
d9d5df0
Let a denying plugin deny even when it exits badly
nvdorman Aug 13, 2026
7fb043f
Read what an MCP server actually returned
nvdorman Aug 13, 2026
af66520
Tell an empty file apart from content it cannot read
nvdorman Aug 13, 2026
edbe221
Let a blob be read when the text beside it is empty
nvdorman Aug 13, 2026
ec4b0b6
Say when grep did not look at a file
nvdorman Aug 13, 2026
538e898
Refuse to call a cut-off stream a finished answer
nvdorman Aug 13, 2026
2b7fa3b
Treat a severed body and a capped answer as the cut streams they are
nvdorman Aug 13, 2026
69f4654
Register an MCP call before its request goes out
nvdorman Aug 13, 2026
c0c2019
Hold gemini to a terminal marker like every other adapter
nvdorman Aug 13, 2026
9a97550
Never answer a call with output produced before it was made
nvdorman Aug 13, 2026
8b1e127
Ask whether to stop repeating on every turn, not only when nudging
nvdorman Aug 13, 2026
c4a3986
Cut a grep line on a character, not a byte
nvdorman Aug 13, 2026
7c9749e
Cap eight tool outputs on characters and say how many were dropped
nvdorman Aug 13, 2026
0c2a08c
Bound Dispatch by the timeout the manifest declares
nvdorman Aug 13, 2026
7fc788a
Require a plugin's reply to be an object
nvdorman Aug 13, 2026
5df1c11
Pin where the nudge lands, and say what the key test really covers
nvdorman Aug 13, 2026
6eafcca
Merge upstream main into the tool-path determinism branch
nvdorman Aug 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 25 additions & 7 deletions HANDOFF.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,31 @@ below is done and green unless called out under **Next Steps**.

1. **Push the 11 local commits** once the user is ready (they have not asked yet —
do NOT push without confirmation).
2. **Agent loop guardrail (explicitly deferred, user picked "frontend first").**
The agent can loop writing the same file with slightly different contents; the
repeat tracker fingerprints name+args so changing content never trips it, and
`grContinue` lets the 60-call hard stop reset up to 9× (~600 calls). Proposed
fix: detect repeated `write_file`/`edit_file` to the SAME path (regardless of
content) as a repeat. This is what produced the giant turn that caused the OOM
in item 4 — the frontend is now hardened, but the loop itself remains.
2. **Agent loop guardrail (still open — the fix once proposed here was tried and
reverted).** The agent can loop writing the same file with slightly different
contents; the repeat tracker fingerprints name+args, so changing the content
never trips it. The fix this note used to recommend — treat repeated
`write_file`/`edit_file` to the SAME path as a repeat regardless of content —
was implemented and then removed again in "Tell a stuck loop apart from
ordinary progress". Keying on the path alone cannot tell three different edits
to one file from one edit made three times, so it fired on ordinary work, which
for a coding agent is most of the work. **Do not reintroduce it.** `repeatKey`
is now uniform over the full normalised arguments for every tool, and
`internal/agent/repeat_guard_test.go` fails if `write_file`, `edit_file` or
`vps_upload` is given a coarser key again. Those are the three names that ever
carried a special case, and the test names each of them; it asserts nothing
about any other tool, so a coarser key introduced for a different tool would
pass. The loop itself is therefore still unsolved: a model that varies the
content each time is bounded only by the ceilings below, and any replacement
needs a signal other than the call fingerprint. This is what produced the giant
turn that caused the OOM in item 4 — the frontend is now hardened, but the loop
remains.

The ceilings as they actually stand: the hard stop is 60 tool calls per segment
(`HardStopAfter`), `grContinue` may reset it up to 4× (`maxGuardrailContinues`,
`harness.go:477`) for five segments, and `AbsoluteMaxToolCalls: 200`
(`config/defaults.go:137`) caps the whole run regardless — so 200 calls, not the
~600 this note previously claimed.
3. **Rotate exposed credentials.** The Z.ai API key and Voyage embed key were
visible in `~/.antares/config.yaml` read during earlier sessions. Still
outstanding; user's call.
Expand Down
Loading
Loading