Give Muse Spark tool-discipline rules - #981
Merged
TheGreatAxios merged 2 commits intoSep 14, 2026
Merged
TheGreatAxios merged 2 commits into
TheGreatAxios merged 2 commits into
Conversation
TheGreatAxios
force-pushed
the
cl-7869-muse-spark-runs-to-the-turn-budget-without-tool-discipline
branch
from
September 13, 2026 18:02
bef3e48 to
20cbc8f
Compare
Collaborator
Author
Critic review · ApproveAppends Muse-Spark-only tool-discipline rules at the system-prompt tail for main sessions and leaves, composed before super() so they reach the wire. FindingsNo blocking findings. Verified against the diff and main-branch sources:
Should-fix (non-blocking, follow-up)
Notes
|
At medium reasoning effort the model does not reliably stop a tool loop: on a two-file fixture with a bounded fix it re-read files it had already read and ran out an 8-turn ceiling without finishing. The same run with three rules appended finished in 3 turns on 4.3x fewer input tokens. The rules ride at the tail of the system prompt, which is prefix-safe — tail appends hold a 99.1% cache hit while a head edit drops it to 9%. Adds a `muse` model family and pins the Responses quirks: the model batches independent tool calls on its own, and sending parallel_tool_calls: false would collapse that to one call per turn. CL-7869
The rules were appended to the director's own copy of the system prompt after calling super(). The base director keeps its own copy and sets options.systemPrompt from it on every ordinary turn, so withCurrentTools' `?? this._systemPrompt` fallback never fired and the composed prompt was built but never sent. A Muse Spark session received the base prompt verbatim: the whole change was a no-op, and every existing test passed. Compose before super() so the base director holds the composed prompt, and give the compaction governor the same text it will actually be estimating. Sub-agent leaves get the rules too. They are the case the ticket names — a spawned worker running to its turn budget — and SubAgentDirector never received them at all. Adds the test that would have caught this: assert the prompt on the emitted infer action, not the prompt the director was constructed with. CL-7869
TheGreatAxios
force-pushed
the
cl-7869-muse-spark-runs-to-the-turn-budget-without-tool-discipline
branch
from
September 14, 2026 05:05
a45ec38 to
cb0665f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes CL-7869.
At
mediumreasoning effort the model does not reliably stop a tool loop. Given a bounded task and aread_file/grep/edit_filetool set, it re-reads files it has already read and keeps calling until the harness turn budget stops it.Measurement
Scripted agent loop, two-file fixture with a buffer-aliasing bug, deterministic mocked tool results, 8-turn ceiling, terminate on
DONE. The two prompts are identical except for three appended rules:4.3x the input tokens and a non-terminating run, from three missing sentences.
Note the interaction with CL-7867: at
minimalthe model terminates either way. The rules earn their keep exactly at the rungs where each wasted turn is most expensive, so lowering the default effort and adding the rules are complementary — the rules are what keep a futuremedium/highrun from degenerating.The measurement is generous to the plain prompt: the harness re-issued each turn's request to capture raw output items, so the real cost of the 8-turn run is higher than the table shows, not lower.
Where the rules live
Appended at the tail of the system prompt. That position is prefix-safe — measured on the same endpoint, tail appends hold a 99.1% cache hit (even when the appended value changes every turn) while an edit at the head drops it to 9%.
Also pinned
The model batches independent tool calls on its own — three
read_filecalls in one turn — and the gateway default already allows it. Sendingparallel_tool_calls: falsecollapses that to one call per turn.hostQuirks.parallelToolCallsis correctly unset today; the added test is what keeps it that way, since flipping it would silently triple turn counts.Testing
bun run typecheck,bun run lint, full suite: 8890 pass. The 3 failures are pre-existing onmain.The 8-vs-3 result is one fixture and one task shape — it establishes the failure mode is real and that the rules address it, not the size of the effect across the tier cases. The capability suite with
--repeats 5is what sizes it.