{ "cleanupPeriodDays": 7, "attribution": { "commit": "", "pr": "", "sessionUrl": false }, "permissions": { "allow": [ "Bash(git status)", "Bash(git log*)", "Bash(git diff*)", "Bash(git branch*)", "Bash(git fetch*)", "Bash(git pull*)", "Bash(git add *)", "Bash(git commit*)", "Bash(git checkout *)", "Bash(git switch *)", "Bash(git stash)", "Bash(git stash push*)", "Bash(git stash list*)", "Bash(git stash show*)", "Bash(git tag*)", "Bash(git show*)", "Bash(ls *)", "Bash(ls)", "Bash(find *)", "Bash(cat *)", "Bash(head *)", "Bash(tail *)", "Bash(grep *)", "Bash(rg *)", "Bash(fd *)", "Bash(wc *)", "Bash(echo *)", "Bash(pwd)", "Bash(which *)", "Bash(type *)", "Bash(whoami)", "Bash(uname *)", "Bash(mkdir -p *)", "Bash(touch *)", "Bash(jq *)", "Bash(yq *)", "Bash(awk *)", "Bash(sort *)", "Bash(uniq *)", "Bash(tr *)", "Bash(cut *)", "Bash(diff *)", "Bash(rtk grep *)", "Bash(*/rtk grep *)", "Bash(rtk ls)", "Bash(rtk ls *)", "Bash(*/rtk ls)", "Bash(*/rtk ls *)", "Bash(rtk cat *)", "Bash(*/rtk cat *)", "Bash(rtk head *)", "Bash(*/rtk head *)", "Bash(rtk tail *)", "Bash(*/rtk tail *)", "Bash(rtk wc *)", "Bash(*/rtk wc *)", "Bash(rtk diff *)", "Bash(*/rtk diff *)", "Bash(rtk git status)", "Bash(*/rtk git status)", "Bash(rtk git log*)", "Bash(*/rtk git log*)", "Bash(rtk git diff*)", "Bash(*/rtk git diff*)", "Bash(rtk git show*)", "Bash(*/rtk git show*)", "Bash(rtk git branch*)", "Bash(*/rtk git branch*)", "Read(**/*.md)", "Read(**/*.txt)", "Read(**/*.json)", "Read(**/*.yaml)", "Read(**/*.yml)", "Read(**/*.toml)", "Read(**/*.lock)", "Read(**/*.gitignore)", "Read(**/*.dockerignore)", "Read(**/.claudeignore)", "Read(**/Makefile)", "Read(**/Dockerfile*)", "Read(**/docker-compose*)" ], "deny": [ "Bash(rm -rf *)", "Bash(rm -rf /*)", "Bash(rm -r *)", "Bash(rm -fr *)", "Bash(rmdir *)", "Bash(git push --force)", "Bash(git push --force *)", "Bash(git push -f*)", "Bash(git push * +*)", "Bash(git reset --hard*)", "Bash(git clean -fd*)", "Bash(sudo rm*)", "Bash(sudo chmod*)", "Bash(sudo chown*)", "Bash(sudo dd*)", "Bash(su *)", "Bash(chmod 777 *)", "Bash(chmod -R 777 *)", "Bash(ssh *)", "Bash(scp *)", "Bash(nc *)", "Bash(netcat *)", "Bash(crontab *)", "Bash(systemctl *)", "Bash(service *)", "Bash(npm install -g *)", "Read(**/.env)", "Read(**/.env.*)", "Read(**/secrets/**)", "Read(**/*.pem)", "Read(**/*.key)", "Read(**/*.p12)", "Read(**/*.pfx)", "Read(**/id_rsa*)", "Read(**/id_ed25519*)", "Read(**/.ssh/**)", "Read(**/credentials)", "Read(**/credentials.json)", "Read(**/.aws/credentials)", "Read(**/.azure/**)", "Edit(**/.env)", "Edit(**/.env.*)", "Edit(**/secrets/**)", "Edit(**/*.pem)", "Edit(**/*.key)", "Edit(**/*.p12)", "Edit(**/*.pfx)", "Edit(**/id_rsa*)", "Edit(**/id_ed25519*)", "Edit(**/.ssh/**)", "Edit(**/credentials)", "Edit(**/credentials.json)", "Edit(**/.aws/credentials)", "Edit(**/.azure/**)", "Edit(**/*.lock)", "Edit(**/package-lock.json)", "Edit(**/pnpm-lock.yaml)", "Edit(**/go.sum)", "Edit(**/node_modules/**)", "Bash(eval *)", "Bash(exec *)", "Bash(find * -delete*)", "Bash(find * -exec rm*)", "Bash(find * -execdir rm*)", "Bash(find * -exec *)", "Bash(find * -execdir *)", "Bash(perl -e *)", "Bash(ruby -e *)", "Bash(cat .env)", "Bash(cat .env.*)", "Bash(cat */.env)", "Bash(cat */.env.*)", "Bash(cat */secrets/*)", "Bash(cat */*.pem)", "Bash(cat */*.key)", "Bash(cat */id_rsa*)", "Bash(cat */id_ed25519*)", "Bash(cat */.aws/credentials)", "Bash(head .env)", "Bash(head .env.*)", "Bash(tail .env)", "Bash(tail .env.*)", "Bash(less .env)", "Bash(less .env.*)", "Bash(more .env)", "Bash(more .env.*)", "Bash(grep * .env)", "Bash(grep * .env.*)", "Bash(sed * .env*)", "Bash(awk * .env*)", "Bash(cut * .env*)", "Bash(tr * .env*)", "Bash(sort * .env*)", "Bash(uniq * .env*)", "Bash(diff * .env*)", "Bash(od * .env*)", "Bash(xxd * .env*)", "Bash(strings * .env*)", "Bash(env)", "Bash(printenv)", "Bash(printenv *)", "Bash(export *)", "Bash(cp .env*)", "Bash(cp **/.env*)", "Bash(cp **/secrets/*)", "Bash(mv .env*)", "Bash(mv **/.env*)", "Bash(mv **/secrets/*)", "Bash(git add .env*)", "Bash(git add **/.env*)", "Bash(cp **/id_rsa*)", "Bash(cp **/id_ed25519*)", "Bash(cp **/.ssh/*)", "Bash(source /dev/stdin)", "Bash(xargs * .env*)", "Bash(tar * .env*)", "Bash(zip * .env*)", "Bash(base64 .env*)", "Bash(rtk cat *.env*)", "Bash(*/rtk cat *.env*)", "Bash(rtk grep * .env*)", "Bash(*/rtk grep * .env*)", "Bash(rtk head *.env*)", "Bash(*/rtk head *.env*)", "Bash(rtk tail *.env*)", "Bash(*/rtk tail *.env*)" ], "ask": [ "Bash(bash -c *)", "Bash(curl * | bash)", "Bash(wget * | bash)", "Bash(curl * | sh)", "Bash(wget * | sh)", "Bash(mkfifo *)", "Bash(git push *)", "Bash(git push)", "Bash(brew install *)", "Bash(apt install *)", "Bash(apt-get install *)", "Bash(dnf install *)", "Bash(pacman -S *)", "WebSearch", "WebFetch", "Bash(git stash pop*)", "Bash(git stash drop*)", "Bash(git stash clear)", "mcp__magic__21st_magic_component_builder", "mcp__magic__21st_magic_component_refiner", "mcp__magic__21st_magic_component_inspiration", "mcp__magic__logo_search" ], "defaultMode": "auto", "disableBypassPermissionsMode": "disable", "additionalDirectories": [] }, "model": "claude-fable-5-1[1m]", "hooks": { "SessionStart": [ { "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/session-start.sh" } ] } ], "PreToolUse": [ { "matcher": "Bash", "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/rtk-rewrite.sh" } ] } ], "Notification": [ { "matcher": "permission_prompt|idle_prompt|agent_needs_input|elicitation_dialog|elicitation_url_dialog", "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/notify-attention.sh", "timeout": 5, "statusMessage": "Ringing terminal bell..." } ] } ], "Stop": [ { "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/notify-attention.sh", "timeout": 5, "statusMessage": "Ringing terminal bell..." } ] } ], "UserPromptSubmit": [ { "hooks": [ { "type": "command", "command": "bash ~/.claude/hooks/design-toolchain-reminder.sh", "timeout": 5, "statusMessage": "Checking design signals..." }, { "type": "command", "command": "bash ~/.claude/hooks/ctx7-reminder.sh", "timeout": 5, "statusMessage": "Checking fast-libs..." } ] } ] }, "statusLine": { "type": "command", "command": "bash ~/.claude/hooks/statusline.sh" }, "enabledPlugins": { "example-skills@anthropic-agent-skills": false, "ui-ux-pro-max@ui-ux-pro-max-skill": true, "security-guidance@claude-code-plugins": true, "superpowers@superpowers-marketplace": true, "pr-review-toolkit@claude-code-plugins": false, "frontend-design@claude-plugins-official": true }, "extraKnownMarketplaces": { "claude-code-plugins": { "source": { "source": "github", "repo": "anthropics/claude-code" } }, "superpowers-marketplace": { "source": { "source": "github", "repo": "obra/superpowers-marketplace" } }, "ui-ux-pro-max-skill": { "source": { "source": "github", "repo": "nextlevelbuilder/ui-ux-pro-max-skill" } }, "anthropic-agent-skills": { "source": { "source": "github", "repo": "anthropics/skills" } } }, "effortLevel": "xhigh", "remoteControlAtStartup": true, "inputNeededNotifEnabled": true, "skipAutoPermissionPrompt": true, "autoMode": { "allow": [ "$defaults", "Local dev containers: `docker exec`, `docker run`, `docker compose up`/`exec`/`logs`/`ps` against a container running on this workstation whose name does not carry `prod` or `production` (a local Supabase or Postgres such as `supabase_db_*`) is routine development, not a remote shell into a shared host. Running a SQL file or script that lives in the repo inside it (`psql -f`, migrations, verify scripts) and piping the output through `tail` or `grep` passes. Remote Shell Writes, Production Reads and Sensitive Remote Exec apply only to hosts named as sensitive in Environment or carrying `prod`. A literal `DROP`, `TRUNCATE` or `DELETE` without a predicate typed on the command line stays under Mass Delete.", "Project-local node: `node `, `npm run`, `pnpm` or `yarn` scripts, and `npx` or `pnpm exec` of a package declared in the project's manifest or lockfile, with effects inside the current working directory, pass like `awk` or `echo`. `node -e` that computes or edits inside the working directory passes; the soft block on inline interpreters that delete or write outside it still applies." ], "soft_deny": [ "$defaults", "Scope of intent: an instruction clears a SOFT BLOCK for the current turn only. An approval given in an earlier turn is not an approval now, and the same action repeated in a later turn has to be asked for again.", "Writing outside the current working directory: `cp`, `mv`, `sed -i`, `rsync`, `tee`, or a shell redirection whose destination resolves outside the cwd. Several sibling projects live under `~/Documents/`, so the realistic failure is writing into the wrong one, where git recovers nothing. Clear only when the user named the destination in this turn.", "`rsync` invoked with `--delete`. It removes files at the destination that are absent from the source, with no undo. Clear only against a destination the user named in this turn.", "Sending SIGKILL (`kill -9`) or killing processes by name (`killall`, `pkill`). These reach processes outside this session, including the user's editors, shells, dtach sessions and background jobs, and the target is chosen by a pattern, so a typo kills the wrong thing. Clear only when the user named the process in this turn.", "Editing more than one file in place in a single command: `sed -i` or `perl -pi` over a glob, or a loop over `git ls-files`. The damage is not loss, since git recovers it, but a diff spanning hundreds of files that nobody reads before committing. `sed -i` on a single named file passes. Clear only when the user asked for the sweep.", "Moving or renaming a directory inside the repo (`mv src/api src/api_old`, or any `mv` of a tree). It breaks imports and paths silently, and the breakage surfaces far from the command. Clear only when the user asked for that move.", "An inline interpreter or `xargs` that deletes, or that writes outside the current working directory: `python3 -c`, `python -c` or `node -e` calling `rmtree`, `remove`, `unlink` or `truncate`; `xargs` feeding `rm`, `mv` or `dd`. `find ... | xargs rm` is the case that matters, since it routes around the `find * -exec rm` deny rule. Reading, computing, and editing a file inside the working directory pass untouched.", "Docker data destruction on this workstation: `docker rm -f`, `docker volume rm` or `prune`, `docker system prune`, `docker compose down -v` (drops named volumes, which hold local database data with no undo), and `docker run` with `--privileged` or a bind mount outside the current working directory. Clear only when the user named the container or volume in this turn.", "Undeclared node packages: `npx `, `pnpm dlx` or `yarn dlx` of a package absent from the manifest and lockfile runs code fetched at call time; `npm install ` or `pnpm add ` adds a dependency the house rule requires naming first. Clear only when the user named the package in this turn." ], "hard_deny": [ "$defaults", "Secret exfiltration: reading a `.env`, an SSH key, a token or a credentials file, and then sending what it contained outside this machine. That covers an HTTP request body or header, a paste or gist service, a file upload, an email, and a commit or push to any repository. The static deny rules match the reading tools by pattern and cannot see the second half of the chain; read and send are separate steps and may sit several turns apart. No instruction clears this.", "Production deployment: running a project's deploy script (`bin/deploy.sh` and its equivalents), any lftp, FTP, SFTP or rsync push to a hosting provider, and any action against a target whose name carries `prod` or `production` as a whole word or name segment. The user deploys by hand, out of session. A green test suite, a finished feature, or a plan step that reads \"deploy\" is not an instruction to deploy. No in-session instruction clears this.", "Disarming the guardrails: removing or weakening an entry in the `deny`, `soft_deny` or `hard_deny` lists of any settings.json, passing `--no-verify` to git, deleting or chmod-ing `.githooks/pre-commit`, setting `disableAllHooks`, or switching `permissions.defaultMode` to `bypassPermissions`. Adding a restriction is fine; removing one is not. When a task is blocked by a guardrail, say so and stop, rather than widening the guardrail to get through. The user maintains these files by hand. No instruction clears this." ], "environment": [ "$defaults", "### Machine-specific (refines any \"None configured\" default above)", "**Primary use of Claude Code**: software development on a personal Linux workstation. Single developer, no organization.", "**Source control**: self-hosted Gitea at `git.bchanot.fr` (SSH on port 49220). Some checkouts under `/home/bchanot/Documents/` have no remote at all and are local-only.", "**Repository visibility**: private. The Gitea instance is self-hosted and not publicly indexed, and a checkout with no remote is local-only. Treat every repo here as private unless its remote points at a public host.", "**Trusted repo**: the checkout Claude Code is currently working in, under `/home/bchanot/Documents/`. No single repo is privileged over the others — read the current one, do not assume a previous session's project.", "**Trusted internal domains**: `git.bchanot.fr` (self-hosted Gitea). It is the only internal service.", "**Default / protected branches**: gitflow. `main` (prod) and `develop` (integration) are protected: a per-repo pre-commit hook refuses code commits on either (exempting `.claude/**` and merges) and Gitea enforces branch protection on both. Work lands on `feature/*`, `bugfix/*`, `chore/*`, `release/*`, `hotfix/*`.", "**Secrets management**: `~/.claude/.env` is the single source of truth and lives outside every git tree; repos reach it through a gitignored symlink. Only `.env.example`, holding placeholders, is ever tracked. A real secret inside a repo is a defect, not a configuration.", "**Internal sharing / snippet hosting**: none. Public paste, gist and pastebin services are outside the trust boundary.", "**CI/CD deploy targets**: no CI system. Deploys run out of band from a per-project runbook, typically lftp/FTP to OVH mutualised hosting for web projects. Nothing deploys automatically on a push or a merge.", "**Internal package registry**: none. Public npm and PyPI.", "**Host containment**: an ordinary developer workstation with open internet and no sandbox. Nothing is contained by the environment itself.", "**Sensitive remote targets**: any namespace, host, database or container whose name carries `prod` or `production` as a whole word or name segment.", "**Sensitive data locations & audiences**: per-project `.env` files (gitignored) hold database, deploy and API credentials; some web projects store customer-submitted form data under a retention policy. Both are personal or client data — never send either to an external service." ] } }