settings: hard-deny edits to coily/ from sessions outside coily/ cwd via PreToolUse hook #65

Open
opened 2026-05-23 20:54:05 +00:00 by coilysiren · 0 comments
Owner

Originally filed by @coilysiren on 2026-04-27T02:25:33Z - https://github.com/coilysiren/coily/issues/20

🤖 Filed by Claude Code on Kai's behalf.

AGENTS.md in this repo says edits to coily from sessions whose primary cwd is not coily/ are forbidden, but today that's enforced only by the agent reading the rule. A session that ignores it (or one where Claude pattern-matches past it under load) can still edit coily files freely. Already happened once in the session that produced f9087cb: primary cwd was the workspace root, edits landed in coily/ anyway. Worked out fine because the work was Kai-directed, but the rule should not depend on Claude noticing.

Wire a PreToolUse hook in ~/.claude/settings.json that hard-denies edits to coily/ from sessions whose primary cwd is anywhere else. Hook is workspace-level, not coily-level - the whole point is to block edits before the agent gets a chance to plead intent.

Shape sketch:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write|MultiEdit|NotebookEdit",
        "hooks": [{ "type": "command", "command": "python3 ~/.claude/hooks/coily_cwd_gate.py" }]
      },
      {
        "matcher": "Bash",
        "hooks": [{ "type": "command", "command": "python3 ~/.claude/hooks/coily_cwd_gate.py" }]
      }
    ]
  }
}

Hook logic:

  1. Read tool-call JSON from stdin.

  2. Resolve the target path(s):

    • For Edit / Write / MultiEdit / NotebookEdit: tool_input.file_path (and edits[*].file_path for MultiEdit).
    • For Bash: parse the command for redirects (>, >>, tee), git apply, cp/mv destinations, anything that writes. Conservative match - if the command mentions a path under coily/ in a write-y context, treat as a target.
  3. If any target path is under ~/projects/coilysiren/coily/ AND $CLAUDE_PROJECT_DIR is not exactly that path, exit 2 with stderr like:

    Edits to coily/ require a session whose primary cwd is /Users/kai/projects/coilysiren/coily.
    See coily/AGENTS.md "Editing coily from other repos: forbidden, file an issue".
    File a GitHub issue with `gh issue create --repo coilysiren/coily ...` instead.
    
  4. Otherwise exit 0.

Edge cases worth nailing:

  • Worktrees of coily under coily/.claude/worktrees/... - resolve via realpath or accept paths under that subtree as still-coily for hook purposes. A session started in a coily worktree should be able to edit coily files.
  • Symlinks pointing into coily/ from elsewhere - resolve before the under-prefix check.
  • Bash false positives on read commands that name a coily path but don't write it (cat, grep, git log). Hook should be write-detection-only on the Bash path; readonly Bash never triggers.
  • The hook lives in user-level settings, not coily/.claude/settings.json, because the goal is to block from outside coily.

Out of scope: any same-rule lockdown for sibling-repo edits (coily-vault, infrastructure, etc.). If those want similar isolation, separate issues. Coily is the only one with the lockdown-wrapper-integrity story that makes the gate worth the friction.

🤖 Filed by Claude Code on Kai's behalf.

_Originally filed by @coilysiren on 2026-04-27T02:25:33Z - [https://github.com/coilysiren/coily/issues/20](https://github.com/coilysiren/coily/issues/20)_ > 🤖 Filed by Claude Code on Kai's behalf. AGENTS.md in this repo says edits to coily from sessions whose primary cwd is not coily/ are forbidden, but today that's enforced only by the agent reading the rule. A session that ignores it (or one where Claude pattern-matches past it under load) can still edit coily files freely. Already happened once in the session that produced f9087cb: primary cwd was the workspace root, edits landed in coily/ anyway. Worked out fine because the work was Kai-directed, but the rule should not depend on Claude noticing. Wire a `PreToolUse` hook in `~/.claude/settings.json` that hard-denies edits to coily/ from sessions whose primary cwd is anywhere else. Hook is workspace-level, not coily-level - the whole point is to block edits before the agent gets a chance to plead intent. **Shape sketch:** ```json { "hooks": { "PreToolUse": [ { "matcher": "Edit|Write|MultiEdit|NotebookEdit", "hooks": [{ "type": "command", "command": "python3 ~/.claude/hooks/coily_cwd_gate.py" }] }, { "matcher": "Bash", "hooks": [{ "type": "command", "command": "python3 ~/.claude/hooks/coily_cwd_gate.py" }] } ] } } ``` **Hook logic:** 1. Read tool-call JSON from stdin. 2. Resolve the target path(s): - For `Edit` / `Write` / `MultiEdit` / `NotebookEdit`: `tool_input.file_path` (and `edits[*].file_path` for MultiEdit). - For `Bash`: parse the command for redirects (`>`, `>>`, `tee`), `git apply`, `cp`/`mv` destinations, anything that writes. Conservative match - if the command mentions a path under coily/ in a write-y context, treat as a target. 3. If any target path is under `~/projects/coilysiren/coily/` AND `$CLAUDE_PROJECT_DIR` is not exactly that path, exit 2 with stderr like: ``` Edits to coily/ require a session whose primary cwd is /Users/kai/projects/coilysiren/coily. See coily/AGENTS.md "Editing coily from other repos: forbidden, file an issue". File a GitHub issue with `gh issue create --repo coilysiren/coily ...` instead. ``` 4. Otherwise exit 0. **Edge cases worth nailing:** - Worktrees of coily under `coily/.claude/worktrees/...` - resolve via `realpath` or accept paths under that subtree as still-coily for hook purposes. A session started in a coily worktree should be able to edit coily files. - Symlinks pointing into coily/ from elsewhere - resolve before the under-prefix check. - Bash false positives on read commands that name a coily path but don't write it (`cat`, `grep`, `git log`). Hook should be write-detection-only on the Bash path; readonly Bash never triggers. - The hook lives in user-level settings, not coily/.claude/settings.json, because the goal is to block from *outside* coily. **Out of scope:** any same-rule lockdown for sibling-repo edits (coily-vault, infrastructure, etc.). If those want similar isolation, separate issues. Coily is the only one with the lockdown-wrapper-integrity story that makes the gate worth the friction. > 🤖 Filed by Claude Code on Kai's behalf.
coilysiren added
P3
and removed
P2
labels 2026-05-31 06:59:47 +00:00
Sign in to join this conversation.
No labels
P0
P1
P2
P3
P4
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
coilyco-bridge/coily#65
No description provided.