Skip to content
open source · deterministic guardrails

Deterministic pre-commit guardrails for AI-generated code

Rules that run, not notes that get ignored

becwright enforces constraints on your code deterministically. Instead of asking an AI agent to respect a rule — the way CLAUDE.md or .cursorrules do — it verifies the result and blocks the commit when the rule is broken.

npm · pnpm · pipx — a self-contained binary, no Python required

pre-commit · becwright

$ git commit -m "feat: session logging"

becwright check

no-dangerous-eval pass

no-debug-remnants pass

no-token-in-logs BLOCKED

src/auth/session.py:42 — token leaked into a log

commit aborted — 1 blocking rule failed

The problem

Why CLAUDE.md and .cursorrules don't stop bad commits

A note is a promise. A commit ships anyway.

An AI agent writes code and leaves a note: “this must never log session tokens.” That note is text. Three months later another agent regenerates the module, never reads it, and drops the token into the logs. Nobody notices until it blows up in production.

Notes are probabilistic — they depend on the agent reading, understanding and obeying. becwright is deterministic: the rule runs against the real code and returns pass/fail, no matter which agent or model made the change.

// The two layers are complementary: CLAUDE.md prevents, so 95% comes out right the first time. becwright is the safety net for the 5% that slips through.

diff · note vs rule
Aspect Note in CLAUDE.md becwright rule
What it does Asks to be respected Verifies it was respected
Depends on The agent reading and obeying Nothing — it runs against the code
Result Likely Guaranteed
Analogy A “speed limit” sign A physical bump in the road
Core concept

A BEC is a Bound Executable Constraint

Three properties that no current artifact has together. Each one closes a gap the others leave open.

B intent · why_it_matters

Bound

The rule is born tied to the intent and the decision that created it — the why. It is not a loose rule without context.

E check → exit 0 | 1

Executable

It carries a check that runs and returns pass/fail (exit code 0 or 1). It is not prose someone promises to respect.

P export → import

Portable

It can be exported from one repo and imported into another, like a package. This is what creates the network effect over time.

How it works

Installed once. It runs on every commit.

  1. 01

    Install the engine

    Pick your ecosystem. The npm packages ship a self-contained binary — no Python needed.

  2. 02

    Scaffold your rules

    becwright init detects your language, writes .bec/rules.yaml and installs the native git hook.

  3. 03

    Commit — it checks

    Every commit runs the checks over staged files. If a blocking rule fails, the commit stops.

.bec/rules.yaml
rules:
  - id: no-token-in-logs
    intent: >
      Session tokens and credentials must
      never reach any log.
    why_it_matters: >
      If a token shows up in the logs,
      anyone with access can steal a session.
    paths: ["src/**/*.py"]
    check: "becwright run no_token_in_logs"
    severity: blocking   # stops the commit
Included checks

Built-in checks: block secrets, tokens in logs, eval and debug leftovers

Text/regex based and conservative by design. The value is binding each rule to the reason it exists — and you can write your own in any language.

  • forbid Any regex you pass (--pattern) any blocking (default)
  • no_token_in_logs Tokens / credentials in log calls Python blocking
  • hardcoded_secrets AWS keys, private keys, password = "…" literals any blocking
  • debug_remnants Forgotten breakpoint(), pdb.set_trace(), import pdb Python blocking
  • dangerous_eval eval() / exec() calls any blocking
  • wildcard_imports from x import * Python warning
  • redundant_comments Comments that restate the obvious code (heuristic) Python warning
Any language

The engine only filters files by their paths globs and runs the check as a command — it never assumes Python. Watch JavaScript, Go, Rust, or anything else with the generic forbid check or your own script.

Built for AI agents

Deterministic guardrails for AI agents — Claude, Cursor, Copilot

CLAUDE.md asks an agent to behave. becwright is the guard that checks — and the agent can install and drive it for you. A dedicated Claude Code plugin adds a becwright skill and a /becwright command; every other agent — Cursor, Windsurf, opencode — drives it through the MCP server or the plain CLI.

  • becwright skill

    Auto-invoked when you ask for a guardrail. The agent knows how to install, scaffold rules, and read and fix check output.

  • /becwright command

    One entry point: init · check · add · status — install, run, and import BECs without leaving the chat.

  • check --json

    Machine-readable pass/fail with intent and why — no parsing, works from the standalone binary.

  • MCP server

    Exposes check and list_checks as tools to any MCP agent — Claude, Cursor, Windsurf, opencode.

Works with Claude Code Cursor Windsurf opencode
Set up becwright in your agent
Claude Code plugin

/plugin install becwright@becwright

/becwright init

becwright check --all

no-dangerous-eval pass

no-token-in-logs BLOCKED

src/auth.py:42 — fixing…

commit unblocked

Get started

Three commands to a guarded repo

$ npx becwright demo

Try it first — no install, nothing touched

# 1. Install the engine

$ npm install --save-dev becwright

# 2. Scaffold rules + install the hook

$ becwright init

# 3. Done — every commit runs the checks

npm packages cover linux-x64, linux-arm64, darwin-x64, darwin-arm64 and win32-x64. On any other platform use pipx install becwright.

Contribute

Found a bug? Have an idea?

Open an issue in seconds. Pick a type, describe it, and we’ll take you to GitHub with everything prefilled.

Type

Opens GitHub’s new-issue form with your text prefilled. A GitHub account is required to submit.

Sponsors

Sponsors supporting deterministic guardrails

becwright is open source and grows with the support of the people and companies who use it.

FAQ

Questions about deterministic pre-commit guardrails

How do I stop an AI coding agent from committing secrets?

becwright installs a native git pre-commit hook that runs deterministic checks over staged files. If a rule such as no-token-in-logs or hardcoded-secrets matches, the commit is blocked with exit code 1 — regardless of which AI agent or model wrote the code.

Why isn't CLAUDE.md or .cursorrules enough to enforce rules?

CLAUDE.md and .cursorrules are probabilistic: they depend on the agent reading, understanding and obeying the note. becwright is deterministic — the rule runs against the real code and returns pass/fail, so it catches the cases the agent ignores or never reads.

What is a Bound Executable Constraint (BEC)?

A BEC is a rule that is Bound to the intent that created it (the why), Executable (it carries a check that runs and returns pass/fail), and Portable (it can be exported from one repo and imported into another like a package).

Does becwright require Python?

No. The npm and pnpm packages ship a self-contained binary covering linux-x64, linux-arm64, darwin-x64, darwin-arm64 and win32-x64. A pipx install is also available for any other platform.

Which languages does becwright support?

Any language. The engine filters files by path globs and runs each check as a command — it never assumes Python. Use the generic forbid regex check or your own script for JavaScript, Go, Rust or anything else.

Can an AI agent install and run becwright for me?

Yes. A dedicated Claude Code plugin adds a becwright skill and a /becwright command; every other agent — Cursor, Windsurf, opencode — drives it through the MCP server or the check --json CLI output.

Stop trusting notes. Start enforcing rules.

becwright is open source and verified end-to-end — from install to a blocked commit. Bring deterministic guardrails to your repo today.