Skip to content

setup-isolated-setup-install: "." in allowRead does not cover CWD; need defensive abs-path resolution at install time #197

Description

@potiuk

Problem

The framework's canonical settings template
(.claude/settings.json) declares sandbox.filesystem.allowRead: ["."]
with the intent that any adopter project — placed anywhere on disk,
named anything — is readable under the sandbox by virtue of being the
session's CWD.

In practice this is not happening. In a session started in
~/code/airflow-s/ with the template installed at user-scope, the
resolved sandbox state shows:

  • write.allowOnly keeps "." and "\$TMPDIR" as literals → resolved
    at access-time → write to CWD works.
  • read.allowWithinDeny pre-resolves everything to absolute paths →
    "." silently disappears from the resolved set → reads under CWD
    fall through to the broad denyRead: ["~/"] and fail with
    Operation not permitted.

Symptom seen on a real session: git rev-parse --git-dir in the project
root fails ("Unable to read current working directory: Operation not
permitted"); Read-tool reads of .apache-steward.lock,
.apache-steward/, etc. also fail. The only way to unblock is per-command
dangerouslyDisableSandbox: true or hand-editing ~/.claude/settings.json
to add an explicit absolute path for the project.

This breaks the promise that adoption alone is sufficient to make the
secure setup work on a freshly-cloned project, regardless of its path
or name.

Where to fix

Two parts:

  1. Upstream (out of framework scope, but worth surfacing):
    the harness should resolve "." consistently across allowRead and
    allowWrite — either keep it literal in both (resolved at access-time)
    or expand it to the abs path of CWD-at-session-start in both.

  2. Framework-side defensive fix (this issue):
    setup-isolated-setup-install should resolve the project root at
    install time (git rev-parse --show-toplevel) and add the resulting
    absolute path to allowRead (and allowWrite if not already
    covered) in the merged ~/.claude/settings.jsonin addition to
    the "." entry, not replacing it.

    Belt and braces:

    • If the harness ever stops resolving ".", the explicit absolute
      path still covers this project.
    • If "." works correctly, the explicit entry is redundant but
      harmless.
    • Idempotent: re-installs check for an existing entry before adding.

    `setup-steward/adopt` is not the right place — sandbox config is
    `setup-isolated-setup-install`'s responsibility. `adopt` should at
    most verify the project root is covered and refer out to
    `setup-isolated-setup-install` if not (verify-and-remediate, not
    own-and-write).

Verify-side follow-up

`setup-isolated-setup-verify` should add a check: attempt a sandboxed
read of the project root and a sandboxed write of a temp file inside it.
If either fails, surface the gap and propose re-running
`setup-isolated-setup-install`.

Repro

  1. Fresh clone of any adopter project (e.g. `git clone ~/code/foo/`).
  2. Run the secure-setup install with no project-specific customisation.
  3. Start a Claude Code session in `~/code/foo/`.
  4. Invoke any framework skill that reads project files — e.g.
    `/setup-steward verify`. Reads under `~/code/foo/` will fail.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions