Skip to content

Pin which repository surfaces Claude runs still load - #2073

Merged
ppXD merged 1 commit into
mainfrom
fix/pin-which-repository-surfaces-claude-runs-load
Oct 6, 2026
Merged

ppXD merged 1 commit into
mainfrom
fix/pin-which-repository-surfaces-claude-runs-load

Conversation

@ppXD

@ppXD ppXD commented Oct 6, 2026

Copy link
Copy Markdown
Owner

Summary

  • Correct the ClaudeCodeHarness doc comments on what the --setting-sources user pin keeps under Claude 2.1.263:
    • Only .claude/rules files without a paths: frontmatter load from an --add-dir.
    • An --add-dir naming a subdirectory loads that subdirectory's memory in place.
    • The sealed-egress --settings flag is applied on top of the in-loop Stop hook's settings.json in the config home; it does not replace it.
  • Pin both sides of that line against the real CLI in every Claude arm of RepositoryConfigE2ETests:
    • Kept memory must be in the first request: CLAUDE.md, the in-repo file it @-imports, .claude/CLAUDE.md, and a rule without paths:.
    • Dropped surfaces must reach no request, run no command and stay off the init line: a skill, a command, an agent, CLAUDE.local.md, a paths:-scoped rule, sub/CLAUDE.md and a repository output style.
    • A fixture check requires each repository's sub/notes.txt to come back as a tool result, because the scoped rule and sub/CLAUDE.md attach only after that Read.
    • ScriptedModelUpstream refuses with a 400 any call the request does not offer, so a renamed CLI tool fails the run at once.
  • Add a non-root arm: an acceptance-bearing Allowlist Claude run, which carries --settings {"skipWebFetchPreflight":true}, must still run the platform's own Stop hook. ProductionSpec now applies the executor's egress step, which is a no-op for Full egress.
  • The Codex arm pins that a repository skill's agents/openai.yaml MCP dependency is never started.
  • The class doc lists which checks can fail per arm. 2.1.263 reads no settings from a repository below a multi-repo cwd, so that arm's settings checks guard a later CLI.

Test plan

  • E2E on macOS, real Claude 2.1.263 / Codex 0.142.2 against a scripted model on 127.0.0.1: all RepositoryConfigE2ETests arms, the Standard single-repo arm and the new Stop-hook arm (7/7)
  • Mutation: a scripted Read of app.txt fails both Claude arms on the new fixture check
  • Mutation: an unoffered Task call fails in 2 s with API Error: 400 The CLI offered no Task tool…
  • Mutation: a Stop-hook settings.json of {} fails the new arm on its marker
  • dotnet build CodeSpace.sln: 0 errors
  • CI non-root sandbox lane: floor 16 → 17, marker [repo-config-e2e] ran non-root claude-code own-stop-hook sealed-egress Standard uid=1654 confined=True

@ppXD
ppXD force-pushed the fix/publish-agent-work-from-a-clean-repository branch from 81250ad to 0fa166e Compare October 6, 2026 16:30
@ppXD
ppXD changed the base branch from fix/publish-agent-work-from-a-clean-repository to main October 6, 2026 16:30
@ppXD
ppXD force-pushed the fix/pin-which-repository-surfaces-claude-runs-load branch from f2e44f9 to b9613a4 Compare October 6, 2026 16:30
The settings pin (--setting-sources user, with the workspace added back
as an --add-dir) was documented as loading .claude/rules and as leaving
a subdirectory's CLAUDE.md no route. Against Claude 2.1.263 only rules
without a paths: frontmatter load from an added directory, and an
--add-dir naming a subdirectory does load its memory in place. The
sealed-egress note also claimed the runner writes no settings.json,
which is false for an acceptance-bearing run's Stop hook; the CLI
layers --settings over that file, so the hook still runs. A non-root
arm now pins that: an acceptance-bearing Allowlist run's own Stop hook
must leave its marker, with --settings on the argv.

The E2E only checked that each repository's CLAUDE.md reached the
model, so nothing would catch a CLI release that starts loading what
the pin drops or stops loading what it keeps. Each Claude arm now
plants both sides. .claude/CLAUDE.md, an unscoped rule and an
in-repository @import must be in the first request. A skill, a
command, an agent, CLAUDE.local.md, a paths:-scoped rule, sub/CLAUDE.md
and a repository output style must reach no request, run none of their
commands and stay off the init line, after the scripted model has read
sub/notes.txt, invoked the skill and the command and delegated to the
agent. The scoped rule and sub/CLAUDE.md attach only once that Read
happens, so each repository's sub/notes.txt must come back to the model
as a tool result. The scripted model gains named Claude tool calls, and
refuses with a 400 any call the request does not offer, so a renamed
tool fails the run at once. The Codex arm pins that a repository
skill's openai.yaml MCP dependency is never started.

Dropping --setting-sources (with the hijacking env left out so the run
still reaches its broker) fails every drop assertion in the single-repo
arms, and in the multi-repo arm the skill, command, agent,
CLAUDE.local.md, scoped-rule and sub/CLAUDE.md ones: 2.1.263 reads no
settings from a repository below a multi-repo cwd, so that arm's
settings checks guard a later CLI. Dropping the add-dir memory switch
fails every kept one.
@ppXD
ppXD merged commit b63b11f into main Oct 6, 2026
5 checks passed
@ppXD
ppXD deleted the fix/pin-which-repository-surfaces-claude-runs-load branch October 6, 2026 16:32
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.

1 participant