potiuk opened a new pull request, #198:
URL: https://github.com/apache/airflow-steward/pull/198

   ## Summary
   
   Fixes [#197](https://github.com/apache/airflow-steward/issues/197) — the 
harness pre-resolves `sandbox.filesystem.allowRead: ["."]` at session start and 
silently drops the literal, so reads under CWD fall through to the broad 
`denyRead: ["~/"]` and fail under the sandbox. The defensive measure: add the 
project root as an explicit absolute path to both `allowRead` and `allowWrite` 
in the adopter's **project-local** `<repo>/.claude/settings.local.json` 
(gitignored, per-machine, per-project). The `.` entry stays in the committed 
project-scope `settings.json`.
   
   The fix is also wired so that **worktrees inherit access automatically** — 
each worktree carries its own `<worktree>/.claude/settings.local.json` entry, 
both for worktrees that already exist when the fix runs and for worktrees added 
later via `git worktree add`.
   
   ### Scope choice — project-local, not user-scope
   
   | Scope | File | Suitable? |
   |---|---|---|
   | User | `~/.claude/settings.json` | No — pollutes user-scope with every 
adopter project's abs path. |
   | Project (committed) | `<repo>/.claude/settings.json` | No — 
machine-specific abs paths would leak into the repo. |
   | Project (local, gitignored) | `<repo>/.claude/settings.local.json` | Yes — 
per-machine, per-project, never committed. |
   
   The helper writes only to the project-local file. User-scope and committed 
project-scope are never touched.
   
   ### What landed
   
   - **New helper** `tools/agent-isolation/sandbox-add-project-root.sh` 
(executable, Apache 2.0). With `--all-worktrees`, enumerates `git worktree list 
--porcelain` and writes each worktree's path into **that worktree's own** 
`.claude/settings.local.json`. Without the flag (post-checkout hook mode), 
writes only the current worktree's path. Creates the target file if missing; 
updates atomically (`jq` → tmp → `mv`); idempotent.
   
   - **`setup-isolated-setup-install`** — new Step P that installs the script 
under `~/.claude/scripts/` (the *file* lives user-scope; what it *writes* is 
project-local) and runs it once with `--all-worktrees` against the adopter repo.
   
   - **`setup-isolated-setup-verify`** — new Check 8: live read+write probe of 
the current worktree's project root, plus a static cross-check that the abs 
path is in the current worktree's `.claude/settings.local.json`.
   
   - **`/setup-steward adopt`** Step 12 pass 3 — runs the helper with 
`--all-worktrees` after the worktree-init propagation. Step 10 post-checkout 
hook content extends to chain into the helper. Step 7 gitignore gains 
`/.claude/settings.local.json` (most adopters already gitignore it by Claude 
Code convention; the adopt flow checks and adds the line if missing).
   
   - **`/setup-steward upgrade`** Step 6c — after the per-worktree 
`worktree-init` loop, the helper runs with `--all-worktrees`.
   
   - **`/setup-steward worktree-init`** new Step 1c — invokes the helper for 
just this worktree's root.
   
   - **`/setup-steward verify`** new Check 8b — static cross-check that the 
current worktree's abs path is in its own `.claude/settings.local.json`. Scopes 
to the current worktree only, since each worktree carries its own per-machine 
settings file.
   
   - **`docs/setup/secure-agent-setup.md`** — new section *Project-root 
coverage in the sandbox allowlists* (harness behaviour, scope rationale, helper 
surface, four invocation points).
   
   - **`tools/agent-isolation/README.md`** — table row for the new helper.
   
   ### Testing
   
   Dry-run on this repo: 4 worktrees, each one gets its own absolute path 
written to its own `<worktree>/.claude/settings.local.json` (one worktree had 
no existing file — helper creates it from scratch with only the 
sandbox.filesystem block). Idempotent — second run produces no diff.
   
   ## Test plan
   
   - [ ] On a fresh adopter clone with the secure setup already installed, run 
`/setup-steward` and confirm the project root lands in 
`<repo>/.claude/settings.local.json`'s 
`sandbox.filesystem.allowRead`/`allowWrite`.
   - [ ] On an adopted repo, `git worktree add ../foo feature-x`; confirm the 
post-checkout hook fires in the new worktree and the path lands in 
`<new-worktree>/.claude/settings.local.json` (not in the main's).
   - [ ] On a multi-worktree adopted repo, run `/setup-steward upgrade` and 
confirm each worktree's `settings.local.json` carries its own path.
   - [ ] Run `setup-isolated-setup-verify` on a stale session whose project 
root is not yet in the local settings; confirm Check 8's live probe surfaces ✗ 
and remediation pointer fires.
   - [ ] Run the helper with `--dry-run --all-worktrees` and verify the diff 
matches expectations without writing.
   - [ ] Run the helper twice in a row — second run should be a no-op (no diff 
output, exit 0).
   - [ ] Run the helper from a directory that has no `.claude/` yet — confirm 
it creates `.claude/settings.local.json` from scratch with only the 
`sandbox.filesystem` block.
   - [ ] Confirm user-scope `~/.claude/settings.json` is **never** touched by 
the helper, even when running with `--all-worktrees`.
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to