fix(workspace-context): skip blocked touches and disable in Code Mode

Address the two remaining review warnings on PR #106.

- tools/post-execute: when a downstream listener/policy returns `block`,
  return early without loading or attaching workspace instructions. The
  registry turns a block into a final isError result, so reconciling off
  the original successful result leaked instructions from a rejected call
  and advanced nested/baseline tracking off a touch that never happened.
- Disable workspaceContext in the Code Mode examples: fs tools run as
  run_code sub-dispatches and code-mode.ts drops sub-call additionalContext,
  so dynamic AGENTS.md updates are silently discarded there.

Update the block regression test to assert no context is attached, and add
a waterfall case proving accept still surfaces the discovered instructions.
This commit is contained in:
Yichen Jiang
2026-07-13 03:40:10 +00:00
parent 1795dc6e19
commit c748f30055
5 changed files with 92 additions and 16 deletions

View File

@@ -91,6 +91,13 @@ export function apply(ctx: Context, config: Config): void {
next,
): Promise<PostToolDecision> => {
const downstream = await next()
// A downstream listener/policy blocked this call: the registry turns it
// into a final `isError` result, so treat it like a failed fs touch and
// load nothing. Reconciling here would surface workspace instructions from
// a call the pipeline rejected, violating the "successful fs tool touches"
// contract, and would advance the nested/baseline tracking state off a
// touch that never really happened.
if (downstream.kind === 'block') return downstream
const fileSystem = ctx.get('fs')
if (fileSystem === undefined) return downstream
const context = await dynamicInstructionContext(
@@ -104,14 +111,10 @@ export function apply(ctx: Context, config: Config): void {
fileSystem,
)
if (context === undefined) return downstream
const additionalContext = concatContext(context, downstream.additionalContext)
if (downstream.kind === 'block') {
return { kind: 'block', feedback: downstream.feedback, additionalContext }
}
return {
kind: 'accept',
...downstream.content !== undefined ? { content: downstream.content } : {},
additionalContext,
additionalContext: concatContext(context, downstream.additionalContext),
}
})
}