Skip to content

fix(routing-block): remove injection-shaped framing (#911)#918

Open
YuryKoltashevModdelix wants to merge 1 commit into
mksglu:mainfrom
YuryKoltashevModdelix:fix/911-routing-block-injection-framing
Open

fix(routing-block): remove injection-shaped framing (#911)#918
YuryKoltashevModdelix wants to merge 1 commit into
mksglu:mainfrom
YuryKoltashevModdelix:fix/911-routing-block-injection-framing

Conversation

@YuryKoltashevModdelix

Copy link
Copy Markdown

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:

  • A <priority_instructions> tag name that claims elevated authority over the rest of the prompt.
  • A session_continuity clause 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.mjs regenerated via npm run build (only bundle that embeds the routing block; server.bundle.mjs and 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

🤖 Generated with Claude Code

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>
@caioribeiroclw-pixel

Copy link
Copy Markdown

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 priority_instructions / stale-directive wording.

The remaining usage_hint still says:

surface only the derived answer — the raw bytes stay out

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:

Use context-mode to reduce context volume, not to hide actions or evidence. If the user, host, or permission review needs the raw result, provide or retrieve the relevant raw/indexed source reference instead of only a derived summary.

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Injected session_continuity/priority_instructions framing trips Claude Code's auto-mode classifier (Auto-Mode Bypass)

2 participants