fix(terminal-review): stop injecting user-global context into the reviewer session - #33
Open
stephanbrez wants to merge 1 commit into
Conversation
…iewer session
The terminal reviewer's system prompt declares the original user request
and the workspace as its only inputs and forbids reading provider skill
directories. But claude-agent-acp defaults to settingSources
["user", "project", "local"] and leaves SDK skill discovery on, so the
user's global CLAUDE.md, settings.json, and skill listings were injected
into the reviewer's context before it read a single instruction —
exactly the sources its own prompt forbids. A prompt-level ban cannot
un-read what the harness injects.
Pass _meta.claudeCode.options {settingSources: [], skills: []} on
session/new — the adapter's documented NewSessionMeta pass-through —
for the terminal reviewer only. Workers and validators deliberately
keep ambient context: global rules files are how users enforce
cross-project conventions. Older adapters without the pass-through
ignore _meta (graceful degradation). The _ensure_claude_settings
workaround is unaffected: the adapter's own SettingsManager loads
unconditionally and only feeds permission-mode/model resolution.
Test infra: mock_acp_agent grows MOCK_ACP_SESSION_PARAMS_PATH (dump
session/new params) and a terminal_review handoff shape.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
stephanbrez
added a commit
to stephanbrez/zenith
that referenced
this pull request
Jul 28, 2026
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
The terminal reviewer's system prompt (
bundled/prompts/terminal-reviewer/system_prompt.md) declares the original user request and the workspace as its only inputs, and its Forbidden Sources list explicitly bans.claude/skills/, provider subagent definitions, andAGENTS.mdshims.But the runtime violates its own spec:
claude-agent-acpdefaults tosettingSources: ["user", "project", "local"]and leaves the Claude Agent SDK's skill discovery enabled. So every terminal-reviewer session gets the user's globalCLAUDE.md,settings.json(including hooks), and skill listings injected into its context before it reads a single instruction. A prompt-level ban cannot un-read what the harness already injected — the reviewer's independence is currently prompt-deep only.Fix
Pass the adapter's documented
NewSessionMetapass-through onsession/new, for the terminal reviewer only:settingSources: []— SDK isolation mode: no user/project/localsettings.json, noCLAUDE.mdfiles.skills: []— skills are a separate SDK option not governed bysettingSources; empty list enables none. This is a context filter, not a sandbox (files stay on disk), but the prompt already forbids reading them — the filter closes the injection channel.Gated to the claude provider; codex/hermes sessions are unchanged.
Deliberately narrow
Workers and validators are not touched. Global rules files are how users enforce cross-project conventions, and the validator prompt already establishes the source hierarchy (contract defines the evidence floor; skills provide method only). Independence is uniquely the terminal reviewer's requirement.
Non-interactions verified
_ensure_claude_settings(thedefaultMode: autoworkaround) is unaffected: the adapter's ownSettingsManagerloads settings unconditionally fromparams.cwdand only feeds permission-mode/model resolution — a separate path from the SDK'ssettingSources._meta.claudeCode.optionspass-through ignore_metaentirely — graceful degradation to current behavior.Consequence worth naming
settingSources: []also drops the user-globalCLAUDE.md, which the Forbidden Sources list doesn't name literally — but the prompt's closed "your only inputs are" list covers it, andsettingSourceshas no finer granularity ("user"is all-or-nothing).Tests
_terminal_reviewer_session_metareturns the isolation options for claude,Nonefor codex/hermes.run_terminal_reviewend-to-end via the mock ACP agent, assertingsession/newcarries the_metaand the handoff round-trips.mock_acp_agent.pygrowsMOCK_ACP_SESSION_PARAMS_PATH(dumpsession/newparams) and aterminal_reviewhandoff shape — both additive.uv run pytest: 216 passed, 7 skipped (the pre-existing real-agent smoke skips) on top ofmain.🤖 Generated with Claude Code