fix(routing-block): remove injection-shaped framing (#911)#918
fix(routing-block): remove injection-shaped framing (#911)#918YuryKoltashevModdelix wants to merge 1 commit into
Conversation
The injected <context_window_protection> block (rides along on every Agent-tool dispatch, mksglu#233) used a <priority_instructions> tag claiming elevated authority over the rest of the prompt, and a session_continuity clause telling the agent "a past phrase does not bind you" — both read as classic prompt-injection framing to Claude Code's auto-mode permission classifier, causing legitimate Agent dispatches to be denied. - Rename <priority_instructions> -> <usage_hint>, a tag name that doesn't claim authority over surrounding instructions. - Drop the "user's most recent message always takes precedence... a past phrase does not bind you" sentence from session_continuity. The remaining "memory aid, not a standing order" framing (already softened in mksglu#856) still conveys the intent without instructing the agent to discount prior directives. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
This looks like the right minimal fix for the two obvious classifier triggers. One thing I would still consider before merging: the issue's second denial quoted the “raw output kept out of the conversation” shape as an oversight-bypass signal, not just the The remaining
That is true for context economy, but to a permission/security classifier it can still read as “hide tool output from the review surface.” A small auditability clause may make the routing block less ambiguous without weakening the product: Even better if the regression test asserts the block contains this kind of “not for concealment / raw source remains retrievable for review” invariant. That gives the classifier a positive safety statement instead of only removing suspicious phrasing. |
Summary
Fixes #911. The injected
<context_window_protection>routing block (spliced into every Agent-tool dispatch prompt, see #233) used two pieces of framing that read as classic prompt-injection to Claude Code's auto-mode permission classifier:<priority_instructions>tag name that claims elevated authority over the rest of the prompt.session_continuityclause stating "the user's most recent message always takes precedence... a past phrase does not bind you" — instructing the agent to discount prior captured directives.Both are accurate/well-intentioned in isolation (avoid a stale captured role/skill freezing into a standing directive, per the #856 fix), but structurally they're indistinguishable from a prompt trying to claim priority and tell the model to ignore prior instructions — which is exactly what a security classifier is supposed to catch.
Changes
hooks/routing-block.mjs: rename<priority_instructions>→<usage_hint>; drop the "past phrase does not bind you" sentence from<session_continuity>, keeping the already-softened "memory aid, not a standing order" framing from Pi host: a casual user phrase gets frozen as behavioral_directive and re-injected every turn → do-nothing loop (1.0.163 & next) #856 intact.tests/opencode-plugin.test.ts: update assertion for the renamed tag.tests/core/routing.test.ts: add a regression test (Issue #911) asserting the block never contains the old tag name or the discounting-prior-instructions phrasing.cli.bundle.mjsregenerated vianpm run build(only bundle that embeds the routing block;server.bundle.mjsand the other hook bundles are unaffected).Intentionally did not add an opt-out/quiet-mode flag (also suggested in the issue) — that's a larger feature decision I'll leave to a maintainer, this PR is scoped to the two concrete wording triggers.
Test plan
npm run build— tsc + bundle + assert-bundle + assert-asymmetric-drift all passnpx vitest run— full suite: 4716 passed, 0 failed, 28 skippednpx vitest run tests/core/routing.test.ts tests/opencode-plugin.test.ts— 96 passed including new Injected session_continuity/priority_instructions framing trips Claude Code's auto-mode classifier (Auto-Mode Bypass) #911 regression tests🤖 Generated with Claude Code