Relationships
#2881 `swamp repo upgrade` adds its canonical Claude audit hook next to an existing variant, so every command is recorded twice
Opened by 4chems · 10/1/2026· Shipped 10/2/2026
What
swamp repo upgrade (and, per the swamp doctor audit hint, swamp init --tool claude --force) installs the canonical Claude Code hook
swamp audit record --from-hookinto .claude/settings.local.json under PostToolUse and PostToolUseFailure whenever that exact command string is absent. It does not recognise an existing hook that already runs swamp audit record --from-hook in a different form (e.g. backgrounded). The result is two matcher: Bash hooks per event, and every Bash call lands twice in the audit JSONL.
Repro (swamp 20260930.234450.0-sha.657fe527, macOS, tool: claude)
.claude/settings.local.jsonwith exactly one hook per event, the backgrounded variant —swamp doctor auditreports OVERALL: PASS on it:payload=$(cat); (printf '%s' "$payload" | swamp audit record --from-hook >/dev/null 2>&1 &)swamp repo upgrade→ "Settings: updated"; changed files include.claude/settings.local.json.jq '.hooks' .claude/settings.local.jsonnow shows two entries per event: the backgrounded one and the canonical one.swamp audit --hours 48lists every command twice with identical timestamps (seen: "80 swamp, 386 direct", every row duplicated).
The file had been in this doubled state unnoticed for about a month, so the swamp-vs-direct ratio we report from swamp audit was inflated 2x.
Expected
Either treat any hook whose command contains swamp audit record --from-hook as present and leave it alone, or replace it with the canonical form — but never append a second one. swamp doctor audit should also warn when more than one audit hook is wired per event; it currently passes on the doubled file (related: #156, the preflight diagnostic).
Workaround
Keep only the canonical foreground hook (what upgrade would reinstall anyway); costs ~0.4 s per Bash call. The backgrounded variant is faster but gets re-duplicated on every swamp repo upgrade.
(Body re-submitted with redaction off: the automatic redactor had replaced the file name settings.local.json with a host placeholder. Mirrored in our internal tracker as operations #39.)
Shipped
Click a lifecycle step above to view its details.
stack72 commented 10/2/2026, 5:49:03 PM
Thanks @4chems for reporting this! We shipped: Stop swamp repo upgrade and init --force from appending a second audit hook for Claude, Cursor and Copilot when an existing hook already runs swamp audit record --from-hook in another form, repair files already doubled by removing the swamp-added duplicate, and make swamp doctor audit fail when an event has more than one audit hook.. The fix has been merged and a release is on its way. We appreciate your contribution to swamp.
Sign in to post a ripple.