Repository navigation
🤖 fix: freeze AGENTS.md Tool: sections per segment, re-freeze instructions on a model or agent switch - #7323
Conversation
A model or agent switch inside a segment kept the first model's <model-...>/<mode-...> sections in the frozen system prompt and sent the new ones in a row under them. Each model has its own prompt cache, and an agent switch changes <agent-instructions> before the blocks, so the switch already rewrites the cache: the blocks now re-freeze at the new sections. Replay re-freezes where the turn recorded a "system" record. --- _Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_ <!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high -->
…nges getToolsForModel appends each `Tool: <name>` section to its tool's description, inside the cached tool block, so an edit rewrote the whole cached prefix. The sections now follow the skill-index ledger: a new toolInstructions record (the JSON map of tool to instructions) freezes them at the segment start, the request puts the frozen text back at the end of each description, and a change goes in a system row of tagged blocks until the next compaction. A description that no longer ends with its instructions sends as before. Addresses Codex PRRT_kwDOPxxmWM6vgBAW. --- _Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_ <!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high -->
|
@codex review |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (1)
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c027079b3e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
🟢 e2e stories (Haiku): 14 passed27 agent steps · 7 replayed from cache · 31 model calls · 218.8k tokens (70% cached) All 14 tests in 9 files
e2e 0.20.0 · 3m 0s · web · run artifacts 🟢 e2e Electron stories (Haiku): 3 passed3 agent steps · 3 model calls · 8.0k tokens (21% cached) All 3 tests in 3 files
e2e 0.20.0 · 18.4s · electron · run artifacts 🟢 e2e agent repros (Haiku): no tests selectedSpend: $0.00 of the $1.00 cap (proxy ledger) e2e 0.20.0 · 5.3s · 2 targets (web, phone) · run artifacts |
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: c027079b3e
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
planSystemSection returned on "no change" before the re-freeze check. So after an AGENTS.md change sent as a row, a model or agent switch with no new edit kept the stale frozen blocks plus the old row. The re-freeze now runs first and folds the live blocks and the earlier rows into the system prompt. A switch with nothing to fold still changes and records nothing. Replay re-freezes from the turn's "system" record, so it matches. Addresses Codex PRRT_kwDOPxxmWM6vjONA. --- _Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_ <!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high -->
|
@codex review |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: da6b5146b0
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…locks switchesModelOrAgent compared canonical models, so anthropic: -> coder: for the same Claude model was no switch. The <model-...> section is tagged with the raw model string, so its blocks changed and went in a row. A changed routeProvider (both rows set) now counts as a switch too; old rows without the field force no re-freeze. Addresses Codex PRRT_kwDOPxxmWM6vjdlK. --- _Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high`_ <!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high -->
|
@codex review |
|
Codex Review: Didn't find any major issues. 🎉 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
🛡️ Codex Security Review · Automatically triggeredSecurity review completed. No security issues were found in this pull request. Reviewed commit: Only the user who started this review can view the report in Codex. ℹ️ About Codex security reviews in GitHubThis is an experimental Codex feature. Security reviews are triggered when:
Once complete, Codex will leave suggestions, or a comment if no findings are found. |
…coder#7330) ## Summary Tests for three gaps in the `Tool:` section freeze from coder#7323, as its Merge Advisor asked. No production code changes. The tests found no bug. ## Implementation - **Replay test** (`replayVerify.test.ts`): three turns with the `Tool: bash` text "Use rg.", then "Use fd.", then "Use fd." again. `replayVerifySession` must rebuild each recorded request through `readToolInstructionsRecord` and `buildReplayRequest`. Turn 2 must carry the `<tool-instructions tool="bash">` row while its tool descriptions keep "Use rg.", so the test cannot pass vacuously. - **Fixture mode** (`replayFixture.ts`): before this PR the fixture built every recorded request through the replay path itself (replay compared with itself), on Sonnet 4.5, which never sends rows. The new `liveToolInstructions` option records the request with the live `assemblePromptPayload` on Opus 5.5 over the direct route, and writes the records on the assistant row. - **Fallbacks** (`turnContextAssembler.test.ts`): a tool description rewritten after `getToolsForModel` sends as before, with no record and no row. A corrupt frozen record keeps the live description and does not crash. ## Validation Each test fails when the path it covers is broken: - The replay test fails with the `toolInstructions` read in `replayVerify.ts` removed, and with the pass-through in `replayRequestBuilder.ts` removed. - The rewritten-description case fails with the `endsWith` guard in `locateToolInstructions` disabled. - The corrupt-record case crashes with the `frozen == null` guard removed. --- _Generated with `xum` • Model: `anthropic:claude-opus-5-5` • Thinking: `high` • Cost: `$593.65`_ <!-- mux-attribution: model=anthropic:claude-opus-5-5 thinking=high costs=593.65 -->
Summary
An edit to an AGENTS.md
Tool: <name>section no longer rewrites the cached tool block. These sections now follow the same per-segment ledger as the custom instructions (#7304) and the skill index (#7308). A newtoolInstructionsrecord freezes them at the segment start, and the request puts the frozen text back at the end of each tool description. A change goes in a system row as<tool-instructions tool="...">blocks until the next compaction folds it in. Separately, a model or agent switch inside a segment now re-freezes the<model-...>/<mode-...>instruction blocks instead of stacking a row on the old ones.Background
getToolsForModelappendsTool:sections from AGENTS.md to the live tool descriptions, so an edit changed the tools section and broke the prompt cache. This existed before 🤖 fix: keep the cached system prompt when AGENTS.md changes mid-session #7304.<model-...>/<mode-...>sections and the new ones went in a row. That was untested. A switch already invalidates the cache (each model has its own cache, and an agent switch changes<agent-instructions>before the blocks), so re-freezing costs nothing and avoids carrying both versions.Implementation
volatileSystemTail.ts: a third ledger channel,toolInstructions. Its record text is the sorted JSON map of each tool in the request to its instructions ("" for none). A new optionalrenderon the channel turns that JSON into tagged blocks for the row.turnContextAssembler.ts(planToolInstructionsTools): swaps the live instructions at the end of each description for the frozen ones. If any description no longer ends with"\n\n" + instructions, the request is sent as before (the same fallback as the skill index).switchesModelOrAgentcompares the segment's last assistant row (canonical model,agentId) with the request. Only the instruction channel re-freezes. Replay re-freezes when the turn recorded asystemrecord, which after a freeze can only come from a re-freeze.MuxMetadata.toolInstructions, its schema,SYSTEM_SECTION_RECORD_FIELDS,workspaceViewTail,replayVerifyandreplayRequestBuilder.Validation
aiService.test.tsruns the realgetToolsForModelpath: with aTool:section edited between turns, the tool block is byte-identical.turnContextAssembler.test.tscovers a changed section, a first section on another tool, replay, a repeated turn and removal. Each fails with the freeze, the description swap or theturnRequestBuilderplumbing reverted.system) costs no cache rewrite: the request sends "" for the marker, and the next turn reads it as applied. A scratch test showed a byte-identical system message and no rows, so this PR leaves that path unchanged.Risks
Medium-low. It changes Anthropic tool descriptions only while a
Tool:section changed inside a segment.<agent-instructions>: switching between them now re-freezes, which costs one rewrite that a row would have avoided. I expect this to be rare and did not measure it.replayVerify/replayRequestBuilderfor aTool:row; untested fallbacks for a rewritten description and a corrupt record.Generated with
xum• Model:anthropic:claude-opus-5-5• Thinking:high• Cost:$589.85