Back to work

sous

Checks what coding agents actually do · AI Infrastructure

A Claude Code harness you install in one command, plus a doctor that checks it still holds. It blocks destructive commands and secret reads, fails a green test run that executed nothing, flags the edit that made tests pass by weakening them, and names any plugin that changed since you approved it.

View source on GitHub

decision records

how it was built

Problem

Agents are asked for a green build, and a green build is easy to fake by accident: xcodebuild reports success when a filter matches nothing, pytest, Vitest and Jest stay green when every test is skipped, and deny rules match the command text, so /bin/rm walks past a rule written for rm.

Decisions

  • Paired every guard rule with a command it must block and a near-miss it must allow, and made the suite fail when a block message has no pair.
  • Counted executed tests from the log instead of trusting the exit code, and reported the largest count rather than a sum, so it is a zero-detector and not a coverage number.
  • Listed the known gaps in the test corpus itself (a command built in a variable passes the guard), so the docs go red if the behavior changes.

Outcome

Each claim in the README is backed by a test you can run. The OS sandbox is still the real boundary; sous covers what text matching and exit codes miss.

Key features

  • A PreToolUse guard that stops the spellings deny rules miss, such as /bin/rm -rf, sh -c and git -C . push -f
  • tests-ran exits 1 when a test log shows zero executed tests; tests-weakened reads a diff and flags deleted, skipped or loosened tests
  • sous lint maps each "never" line in CLAUDE.md to a real control, or names it as unenforced
  • sous accept records each plugin's hooks and scripts, so doctor names a change even when the version did not move

Impact

An agent that reports green has to show the tests ran and were not weakened to get there.

Tech stack

Bash, Python, Claude Code hooks, GitHub Actions

interested in something like this?

Get in touch