Repository navigation
Roll out global ~/.claude/CLAUDE.md safety rules to all machines #365
Description
Summary
Get the agent write-safety kit installed and current on every machine that runs Claude Code with my gh credentials logged in.
One command per machine. It installs, and it prints one line to paste back here.
Do this on each machine
Clone fresh (or git pull an existing clone — the point is that it is current), then run one command.
Linux, macOS, WSL
git clone --depth 1 https://github.com/ptr727/ProjectTemplate.git /tmp/pt && cd /tmp/pt
./host-setup/agent-safety/install.shWindows (PowerShell)
git clone --depth 1 https://github.com/ptr727/ProjectTemplate.git $env:TEMP\pt; cd $env:TEMP\pt
.\host-setup\agent-safety\install.ps1Both need Python 3 and nothing else. Both are idempotent, so re-running is always safe and is the fix for anything reported below.
Restart Claude Code sessions on that machine afterwards, so the hook and CLAUDE.md load.
What to paste back
The installer ends with one line. Paste it into the checklist below:
server-2 | Debian GNU/Linux 13 (trixie) | hub e2a99f1 | payload 2600d29d59ff247a | agent-safety v1, fleet-bootstrap v1 | 2026-08-11T02:12:07Z
Host name, host type, the hub commit it installed from, a digest of the bytes installed, the marker blocks actually found in CLAUDE.md, and when. That is the record — a tick is not.
Re-checking a machine later, without changing it
./host-setup/agent-safety/install.sh --report # Linux / macOS / WSL
.\host-setup\agent-safety\install.ps1 --report # WindowsRead-only. Run it from a fresh hub checkout and it compares that machine against that checkout:
| Verdict | Exit | Meaning |
|---|---|---|
CURRENT |
0 | Machine matches this checkout |
STALE |
1 | Lists each reason; re-run the installer |
NOT INSTALLED |
2 | No stamp on this machine |
It creates nothing, so running it on a machine that has never been set up leaves it untouched.
Rollout
Every tick below was reset. They recorded that someone ran something once, the kit has changed several times since, and none of them carries a stamp — so none can be checked. Paste the stamp line as each machine is done.
- Server-2 Proxmox (this host — the kit is installed but predates the stamp, so re-run it)
- Windows workstation
- WSL2 Debian
- WSL2 Ubuntu
- Macbook Air
- Thinkpad Windows
- Thinkpad Linux
- Any CI / headless / cron environment that invokes Claude Code with the token
Why the ticks were not enough
The previous body said it outright: "a machine ticked below is not necessarily current." Three things were being conflated, and only the third matters:
- Ran once — what a tick records.
- Files present — what a
grepfor the markers records. A block edited between its own markers passes this. - Current and in force — what the stamp records.
--report checks the third. It compares the installed bytes rather than markers, so a hand-edited block is caught; it reads settings.json, so a kit whose hook is no longer registered is reported inactive rather than fine; and it reports a duplicated or half-written block, which a presence check reads as success.
What is checked
- The deployed hook and both
CLAUDE.mdblocks, byte for byte against the checkout, line endings normalized so a CRLF machine is not falsely stale - The PreToolUse hook is registered in
settings.json, exactly once - Every managed permission rule is present
- Markers are neither duplicated nor half-written
- The install was not made from a dirty checkout, which would mean the recorded commit does not identify the bytes
One thing the installer will not fix
On at least this host, the superseded safety section from #364 still sits above the canonical marker block, so the two overlap. The installer only rewrites what is between its own markers, so that older text survives every re-run and --report will call the machine CURRENT with it still there.
Removing it is a judgment call on a per-machine file rather than something to automate, so it is worth a look while visiting each box.
Relates to #364. The tooling matrix half is #483. Landed in #665.
Activity
Agent write-safety: repo-scope + never-fabricate-id + never-suppress-…
ptr727 commentedon Jul 20, 2026
The rollout is now a portable kit, not a hand-placed file:
host-setup/agent-safety/shipped in #367 (ondevelop) withinstall.sh(Linux / WSL / macOS / Proxmox) andinstall.ps1(Windows). One idempotent, self-testing installer deploys the PreToolUse hook, registers thesettings.jsonentry, and appends the## GitHub Write Safety (Any Project, Every Session)section to~/.claude/CLAUDE.mdin one step. Re-running updates in place.Deployed and verified on this WSL2 machine (the box running this session):
install.shran, hook self-test passed,settings.jsonPreToolUse/Bash entry registered (existing keys preserved), the three-rule section is in~/.claude/CLAUDE.md(2 markers).Remaining boxes still run the kit themselves (the checklist stays yours to tick per box as each is done):
install.ps1to also install the technical hook (the new mechanical half).install.sh.install.sh/install.ps1.install.sh.Verify per box:
python3 ~/.claude/hooks/gh-write-guard.py --selftestandgrep -c 'agent-safety v' ~/.claude/CLAUDE.md(expect 2). On Windows:py -3 "$env:USERPROFILE\.claude\hooks\gh-write-guard.py" --selftest.Relates to #364, #366.
ptr727 commentedon Jul 23, 2026
WSL2 Debian - verified current
Re-ran
host-setup/agent-safety/install.shon WSL2 Debian (Debian on a Win11 workstation) against the current kit (hub614a291, kit last changed 2026-07-21). Idempotent, no functional change - this box was already deployed, and the kit's later revisions are now confirmed in place.Verified:
python3 ~/.claude/hooks/gh-write-guard.py --selftest).~/.claude/hooks/gh-write-guard.pyis byte-identical tohost-setup/agent-safety/gh-write-guard.py(current, not a stale copy).~/.claude/CLAUDE.md: 2agent-safety vmarkers (the safety block is present and marker-delimited).~/.claude/settings.json: exactly one PreToolUse/Bash group carries the hook.-R) throughout this session, so it is enforcing, not just installed. No restart needed on this box.Remaining boxes on the rollout checklist stay as before (Windows workstation
install.ps1for the hook, Proxmoxinstall.sh, other workstations, CI/headless).ptr727 commentedon Jul 23, 2026
Audit: Server-2 Proxmox — safeguard implemented and verified
Machine: Server-2 Proxmox (Proxmox VE / Debian, PlexCleaner host — the machine where the incident originated)
Date: 2026-07-23
File:
/home/pieter/.claude/CLAUDE.mdWhat was done
The file already existed with the incident-specific rules (repo-scope ban, no fabricated GitHub node IDs, no suppressed write output). Per this issue's instructions, the canonical
## Safety rulesblock from #364 (Repo scope / Writes are never probes / Outward-facing actions) was appended to it, with a note that where the two overlap the stricter reading applies.Verification
All three rule headings present — verify check from the issue passes. Rollout checklist updated accordingly.
Posted by Claude Code at the account owner's explicit request in-session.
Promote the agent git-bypass guard and Copilot poll-backoff to main (#…
Document Rule 4 and the refresh procedure in the safety-kit README (#452
Promote the safety-kit README update to main (#452) (#453)
ptr727 commentedon Jul 30, 2026
WSL2 Debian verified and refreshed today.
This box is Debian GNU/Linux 13 (trixie) under WSL2, so it is the
WSL2 Debianrow, already checked for theCLAUDE.mdrules.What was stale. The deployed
~/.claude/hooks/gh-write-guard.pywas the 2026-07-25 copy, predating theAGENTS.mdsplit, so its denial messages pointed atAGENTS.md "Repository Boundaries and Write Safety"for a section that now lives inGOVERNANCE.md. It denied correctly throughout, and it caught a real one this session (agit push ... 2>&1 | tail -2, which is output suppression on a mutation). Only the pointer it hands you was wrong.Re-ran
host-setup/agent-safety/install.sh, and verified rather than assumed:settings.jsonstill parses and still registers the hook.A note for the remaining hosts. A box that installed before the split carries the same stale citation, so re-running the installer is worth doing on each one as it is ticked rather than assuming the first install is current. The installer is idempotent and updates the
CLAUDE.mdblock in place, so a re-run is cheap.Scope of this comment. Only
WSL2 Debianis claimed. The other unchecked rows are untouched, and I have not inspected them.ptr727 commentedon Jul 31, 2026
Server-2 Proxmox is now fully covered, and the checklist line is updated to say so.
Development moved off the WSL2 Debian box onto this host on 2026-07-31. A verification pass found that only the documentary layer had ever been installed here: the
~/.claude/CLAUDE.mdsection from 2026-07-23 was the older #364 draft wording, there was no~/.claude/hooks/directory, and neithersettings.jsonnorsettings.local.jsoncarried ahookskey. Thegh-write-guardmechanical layer was therefore absent on the very machine where the incident originated.Re-running
host-setup/agent-safety/install.shfixed both halves:~/.claude/hooks/gh-write-guard.pyinstalled,--selftestreportsSELFTEST PASS(Rule 4 branch-rule-bypass cases included).PreToolUse/Bashhook registered in~/.claude/settings.json.agent-safety v1block appended to~/.claude/CLAUDE.md, both markers present.One follow-up left for the account owner, not actioned here: the older #364
## Safety rulessection is still in that file above the new canonical block, so the two now overlap. Removing the superseded section is a judgment call on a per-machine file, so it is being surfaced rather than applied.Worth noting for the remaining boxes: the WSL2 Debian entry is ticked for the CLAUDE.md text, which does not imply the hook is installed there. The two layers roll out together only when
install.shis the thing that gets run.Posted by Claude Code at the account owner's explicit request.
Mirror the representative-data rule into the host-wide rules (#532)
Group the backlog by what ships rather than by what it touches (#592)
Carry the Permission Rules the Review Loop Needs in the Installer (#624)
Promote develop to main: the prose gate now blocks on every default r…
ptr727 commentedon Aug 11, 2026
Body updated rather than re-filed, since the rollout it tracks is the same one. Three changes, all because the thing being rolled out grew after this was written.
Scope. This tracked one block.
install.pynow manages two,agent-safetyandfleet-bootstrap, plus thegh-write-guardhook. That matters for the checklist: every tick below predates thefleet-bootstrapblock, so a machine marked done here can still be stale. Its content changed again today, so a machine carrying the older copy routes a stale repository toAUDIT.md, which measures, instead ofRESYNC.md, which applies.The verify command was misleading and is replaced. It grepped the first draft's rule headings, which no longer appear verbatim and never covered the second block, so a current machine could fail it and a stale one could pass. It now uses the installer's own checks, counting two markers per block because a half-written block is exactly what a presence check misses:
Server-2 refreshed today for the new routing, verified: both marker pairs present,
settings.jsonstill valid JSON, hook self-test passing.Two things this does not do. The checklist is untouched, 3 ticked and 5 unticked before and after, because which machines are done is yours to say and I can only reach this one. And it does not claim the ticked machines are current, only that they cannot be assumed to be.
Worth recording how this surfaced. The issue had gone stale in the same way three documents did today, an enumeration that was accurate when written and silently outgrown by the thing it describes. #653, #660 and #662 were the others. Nothing reads an issue body for staleness, so this one only turned up because you asked which issue tracked it.
Stamp Each Host With What It Carries, and Reject the Flags the Instal…
Insist on a Unique Worktree for Every Task and Package It as the repo…
ptr727 commentedon Aug 21, 2026
Current audit against
developat1832702: partial. The portable installer, stamp, read-only--report, and hook self-test exist. The issue's machine rollout is not verified complete, and the checklist carries no current stamp lines for the named hosts. Keep open until the host inventory itself provides current evidence or this rollout is moved to a machine-reporting system.ptr727 commentedon Oct 8, 2026
WSL2 Debian done, run at the maintainer's request from a fresh
maincheckout (4a0d9a0). The stamp line is shown with its host name field omitted:--reportbefore:STALE, for a stale payload, the containment prefix still set while its hook file was missing, no SessionEnd sweep registered, and a hand-editedCLAUDE.md.--reportafter:CURRENT, exit 0, and all three hook self-tests pass.host-localmarker.The checklist tick is left for you.
Posted by Claude Code at the account owner's explicit request.