Skip to main content
← Back to list
01Issue
FeatureOpenSwamp CLIPublic
AssigneesNone

Relationships

#4410 audit: register legitimate non-swamp commands as approved bypasses

Opened by maphew · 11/4/2026

Summary

swamp audit record --from-hook classifies every non-swamp shell command as direct, and "direct" is treated as bypassing swamp. There is no way to declare "this command is an approved tool in this repo, not a violation". Teams that legitimately run other trackers/CLIs next to swamp (bd/beads, gh, git, terraform) accumulate bypass signal on every call, which then feeds the session summaries and tuning findings.

Repro (swamp 20261103.191618.0-sha.17ecb554, claude hooks)

git init /tmp/repro && cd /tmp/repro && swamp repo init --tool claude
echo '{"tool_name":"Bash","tool_input":{"command":"bd ready --json"},
       "hook_event_name":"PostToolUse","cwd":"/tmp/repro","session_id":"s"}' \
  | swamp audit record --from-hook --tool claude
swamp audit --all --json

Result:

{ "entries": [ { "source": "direct", "summary": "bd ready --json", ... } ],
  "totalSwamp": 0, "totalDirect": 1 }

The same input with swamp behavior list is recorded as source: "swamp". So the only thing separating "good" from "bypass" is whether the command starts with swamp — a tool we deliberately run alongside swamp is indistinguishable from an agent going around it.

Impact

  1. False compliance signal. Beads is a dependency-aware issue tracker used instead of swamp for task tracking by design (swamp has no task tracker). Every bd call is counted as bypass.
  2. Per-call cost with no allowlist exit. The hook spawns the swamp binary on every Bash call. The only current mitigations are disabling the hooks entirely (losing the audit trail) or --no-telemetry (does not change classification).
  3. Tuning noise. Session records carry per-call label: swamp|bypass| neutral|unlabeled plus findings[] with severity and tune text, so approved tooling shows up as something the agent should stop doing.

Proposal

Add a per-repo registry of approved non-swamp commands, so classification becomes three-valued: swamp | approved-bypass | bypass.

Suggested surface (names illustrative — happy to follow house style):

swamp audit bypass add 'bd *'        --reason 'issue tracking, by design'
swamp audit bypass add 'gh *'        --reason 'GitHub workflow'
swamp audit bypass list --json
swamp audit bypass rm 'bd *'

Storage: the existing tracked config surface (e.g. .swamp.yaml under audit.bypass: [{pattern, reason}]) so the decision is reviewable in a diff, plus an optional machine-wide config key.

Behaviour:

  • audit record matches the command against patterns (glob or regex; glob preferred) before writing the entry and labels it approved-bypass, with the matched pattern id and the reason attached.
  • swamp audit totals gain totalApprovedBypass; existing totalSwamp and totalDirect stay for compatibility.
  • Session summaries/tuning: calls labelled approved-bypass are excluded from bypass share and never generate findings.
  • Compliance reports (swamp audit report --list) keep the raw label so an auditor can still see what ran; add a filter to include/exclude it.
  • Unmatched non-swamp commands keep the current bypass behaviour — the registry is opt-in, never a blanket allow.

Acceptance criteria

  • swamp audit bypass add 'bd *' then running bd ready produces an entry with source: "approved-bypass" and no tuning finding.
  • swamp audit shows a separate total; JSON adds the field without breaking existing consumers.
  • swamp audit bypass list --json reflects exactly what is in the tracked config file; a hand-edit of that file is honoured.
  • Pattern matching is documented (glob, whole-command, first-token) and covered by tests, including a command that looks like an approved tool but is not (bd-malicious, echo bd ready).
  • Removing a pattern returns the command to bypass on the next call.

Alternatives considered

  • Classify by first token against the extension registry. Does not help third-party CLIs like bd, gh, terraform.
  • A single audit.enabled: false switch. Loses the trail entirely; the request is for accurate recording, not less recording.
  • Have agents wrap calls in swamp behavior run. Not always possible (many are repo-local dev commands) and wrong as a blanket rule.

Context / motivation

I maintain a starter layout that runs swamp and bd side by side: beads owns task tracking, swamp owns automation. It works, but out of the box the audit hook turns correct usage into bypass statistics — so the starter ships with the audit hooks disabled, which loses the audit trail I actually want. An approved-bypass registry would let me leave the hooks on.

02Bog Flow
◉OPEN○TRIAGED○IN PROGRESS○SHIPPED

Open

11/4/2026, 10:21:17 PM

No activity in this phase yet.

03Sludge Pulse

Sign in to post a ripple.