fix(orchestration): break the no-op-write loop + un-rot retry feedback
A stage (configure_ethos_theme) looped forever re-writing an identical
postcss.config.js: file_write returned "written successfully" on a byte-
identical write, and the retry-feedback entry that says WHY it failed got
truncated out of context every turn, so the model cold-started on the same
wrong idea. CAS hashes leaked into its face from two sides too.
- SandboxedToolExecutor: a write whose result is byte-identical to disk now
returns "No change: … nothing was written" (+ noop=true) instead of a false
success signal. Uses the pre-image hashes already captured for reversibility.
- DefaultContextPackBuilder: pin "retryFeedback" in neverDropSourceTypes so the
failure reason + already-written-files list survives truncation.
- ContextFeedback: drop the opaque "— CAS <hash>" from the retry entry; path only.
- tool_output withheld until the session actually spills over-cap output to CAS
(StageConfig.ALWAYS_AVAILABLE_READ_TOOLS -> on-demand via sessionHasSpilledOutput),
so a hash-eating tool isn't advertised to every stage that never spills.
- Wrap 10 long lines in kernel to bring detekt back under maxIssues (99 -> 89).
Tests: infrastructure:tools (+2 no-op cases), core:{transitions,context,kernel} green.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -73,8 +73,12 @@ data class StageConfig(
|
||||
get() = if (allowedTools.isEmpty()) allowedTools else allowedTools + ALWAYS_AVAILABLE_READ_TOOLS
|
||||
|
||||
companion object {
|
||||
/** Read-only tools every tool-granting stage may call regardless of its declared set. */
|
||||
/** Read-only tools every tool-granting stage may call regardless of its declared set.
|
||||
* `tool_output` is deliberately NOT here — it can only retrieve output that has actually been
|
||||
* spilled to CAS, so the orchestrator adds it on demand (once a spill has occurred) rather than
|
||||
* advertising a hash-eating tool to every stage that will never spill (context noise that nudges
|
||||
* models into reasoning about opaque hashes). */
|
||||
val ALWAYS_AVAILABLE_READ_TOOLS: Set<String> =
|
||||
setOf("file_read", "list_dir", "glob", "grep", "tool_output")
|
||||
setOf("file_read", "list_dir", "glob", "grep")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user