freeze
Restrict file edits to a specific directory for the session. (gstack)
Try your first task
freeze
Start a fresh conversation. Replace the highlighted placeholders.
Use freeze to restrict Edit, Write and NotebookEdit operations to [directory] and confirm the boundary only if activation succeeds. Explain that shell writes remain unrestricted and the boundary persists until explicitly removed.
Required inputs
- [directory]
Suggested template by Skill Leaderboard, grounded in the linked source. Task evidence ↗
SKILL.md
name: freezeversion: 0.1.0description: Restrict file edits to a specific directory for the session. (gstack)triggers: - freeze edits to directory - lock editing scope - restrict file changesallowed-tools: - Bash - Read - AskUserQuestionhooks: PreToolUse: - matcher: "Edit" hooks: - type: command command: 'bash -c "exec bash \"$HOME/.claude/skills/gstack/freeze/bin/check-freeze.sh\""' statusMessage: "Checking freeze boundary..." - matcher: "Write" hooks: - type: command command: 'bash -c "exec bash \"$HOME/.claude/skills/gstack/freeze/bin/check-freeze.sh\""' statusMessage: "Checking freeze boundary..." - matcher: "NotebookEdit" hooks: - type: command command: 'bash -c "exec bash \"$HOME/.claude/skills/gstack/freeze/bin/check-freeze.sh\""' statusMessage: "Checking freeze boundary..."/freeze — Restrict Edits to a Directory
Lock file edits to a specific directory. Any Edit, Write or NotebookEdit operation targeting a file outside the allowed path will be blocked (not just warned).
GSTACK_STATE_ROOT=$(~/.claude/skills/gstack/bin/gstack-paths --get GSTACK_STATE_ROOT); : "${GSTACK_STATE_ROOT:?gstack-paths failed; reinstall with ./setup or /gstack-upgrade}"
mkdir -p "$GSTACK_STATE_ROOT"/analytics
echo '{"skill":"freeze","ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","repo":"'$(basename "$(git rev-parse --show-toplevel 2>/dev/null)" 2>/dev/null || echo "unknown")'"}' >> "$GSTACK_STATE_ROOT"/analytics/skill-usage.jsonl 2>/dev/null || true
Setup
Ask the user which directory to restrict edits to. Use AskUserQuestion:
- Question: "Which directory should I restrict edits to? Files outside this path will be blocked from editing."
- Text input (not multiple choice) — the user types a path.
Once the user provides a directory path:
Set the user-selected boundary with the shared state writer. It resolves the physical absolute path and serializes replacement with investigation cleanup:
bash "$HOME/.claude/skills/gstack/freeze/bin/freeze-state.sh" set "<user-provided-path>"
Only report success if the helper succeeds. On FREEZE_BUSY or unexpected state, preserve it and ask the user to inspect recovery after any active writer finishes; never write or delete the state file directly.
Tell the user: "Edits are now restricted to <path>/. Any Edit, Write or
NotebookEdit outside this directory will be blocked. To change the boundary, run /freeze
again. To remove it, run /unfreeze."
How it works
The hook reads file_path from the Edit/Write tool input JSON, or
notebook_path from a NotebookEdit (Jupyter notebook) call (shared
real-JSON extractor with /careful — one copy, sourced by both hooks), then
checks whether the path starts with the freeze directory. If not, it returns a
hookSpecificOutput payload with permissionDecision: "deny" to block the
operation (nested under hookSpecificOutput — Claude Code ignores a top-level
permissionDecision).
Polarity is fail-closed: a tool payload the hook cannot parse is DENIED, not
allowed — a boundary that fails open is not a boundary. A payload that parses
but has neither path field (a non-file tool) is allowed. A deny names the
tool, the path field, the boundary and /unfreeze. The path is resolved before
the check: ~, .. and relative paths, and symlinks at every depth, even
through folders that do not exist yet. A path the hook cannot place (a symlink
loop, a line break, a Windows drive-relative path, over 4096 characters) is
denied.
The freeze boundary persists until explicitly removed via the state file. The hook script reads it on every Edit/Write/NotebookEdit invocation. Boundaries containing spaces are supported.
Notes
- The trailing
/on the freeze directory prevents/srcfrom matching/src-old - Freeze applies to Edit, Write and NotebookEdit only — Read, Bash, PowerShell, Glob, Grep are unaffected
- This prevents accidental edits, not a security boundary — Bash or PowerShell commands like
sedorSet-Contentcan still modify files outside the boundary - To deactivate, run
/unfreeze; ending or killing a conversation does not remove persisted state