~/bouncer

bouncer v0.1.0 · node · 100% local-first · no LLM · MIT

bouncer — ~/projects/app
 ___   ___   _   _  _  _   ___  ___  ___
| _ ) / _ \ | | | || \| | / __|| __|| _ \
| _ \| (_) || |_| || .` || (__ | _| |   /
|___/ \___/  \___/ |_|\_| \___||___||_|_\

compliance controls, checked statically.

A local-first CLI and MCP server that verifies the controls a regulation requires actually exist in your code — UK Online Safety Act, ICO Children's Code — as deterministic rule packs. Runs in CI. No LLM.

$ bouncer check
fail high aadc.geolocation-default-off — Standard 10 — Geolocation
fail high osa.report-mechanism-ugc — report affordance missing on chat surface
pass high osa.block-mechanism-ugc — components/chat/ChatHeader.tsx:42
unknown high aadc.dpia-exists — surface not located — can't determine
✓ pass 2 · ✗ fail 2 · ? unknown 1

# bouncer is an engineering aid, not legal advice — a green report means the coded controls were found, not that you are compliant. Pair it with a real compliance / DPO review.

# how it works

Regulation → rule pack → surface → verdict → evidence. Five moving parts, all deterministic.

01

packs

Regulations encoded as declarative rule packs. Each rule maps a legal standard to a static assertion over your code. The engine knows nothing about the law — the packs do.

$ bouncer packs

02

surfaces

A stack adapter maps regulation surfaces — sign-up, profile, chat, livestream, UGC — onto the files in your repo. Packs stay portable; only the adapter is stack-specific.

$ bouncer list

03

verdicts

Every control resolves to pass, fail, or unknown. A surface bouncer can't locate is never a green pass — it's an honest 'can't determine'. No false comfort.

$ bouncer check --status fail

04

evidence

Passes cite the file:line where the control lives. Fails carry the intent and the fix. A self-contained HTML report an auditor or DPO can read without your codebase.

$ bouncer report --out report.html

05

gate

Exit non-zero when a required control goes missing. Baseline the known gaps, then fail the build only on a regression — like someone removing an age-gate or a report button.

$ npx -y @nugehs/bouncer check

06

portable

Bring your own packs and adapters. The same engine that checks UK regulation checks your internal security or design-system policies.

$ bouncer explain <ruleId>

# what it checks

Two regulation packs ship in the box, plus the machinery to write your own.

uk osa pack

Online Safety Act controls: highly-effective age assurance, report & block on UGC, content moderation, illegal-content risk assessment, CSEA route.

uk aadc pack

ICO Children's Code: age-appropriate application, high-privacy defaults, geolocation off, parental consent under 13, DPIA, no nudge techniques.

stack adapters

next (App Router) and react-native out of the box. Surface aliases map the law onto your file layout. Add an adapter, reuse every pack.

precision probes

allInFile + within-window assertions require a control and its default to co-occur in the same block — not just appear somewhere in a big file.

honest verdicts

pass / fail / unknown. Surfaces that can't be located are reported, never guessed green. The same discipline tieline brings to API contracts.

html audit report

A self-contained, dependency-free report: compliance ring, per-pack control tables, file-level evidence. Hand it to compliance as-is.

ci baseline

Ignore known-open gaps to go green today; CI then fails only when a passing control regresses. Close a gap, delete its id, lock the win.

zero deps

Plain Node, no runtime dependencies, fully local. Nothing about your code leaves the machine. Runs the same in CI and on a laptop.

# works with or without an agent

bouncer is a plain CLI a human runs in CI — and an MCP server an agent can call for the same deterministic verdicts. The LLM is an optional consumer, never the engine. Nothing leaves your machine.

compliance_check list_rules explain_rule list_packs
.mcp.json
{
  "mcpServers": {
    "bouncer": {
      "command": "npx",
      "args": ["-y", "@nugehs/bouncer", "mcp"]
    }
  }
}

# install

RUN IT

$ npx @nugehs/bouncer init
$ npx @nugehs/bouncer check
$ npx @nugehs/bouncer report --out report.html

GATE A PULL REQUEST

# .github/workflows/bouncer.yml
- run: npx -y @nugehs/bouncer@latest check

Baseline existing gaps in bouncer.config.json, then the build fails the moment a passing control is removed.

Part of the same local-first toolchain as repoctx and tieline — deterministic developer tools that are useful with or without an agent.