Skip to content
becwright

Get started

Introduction

What becwright is and why it exists — install the deterministic pre-commit engine, scaffold .bec/rules.yaml and guard your repo in three commands.

Last updated

becwright is a deterministic guardrail engine for git repositories. Every time you commit, it runs the checks you declared against the real staged code — the exact files about to enter history — and each rule comes back as a hard pass or fail. When a blocking rule fails, the commit is stopped before it lands. Advisory files like CLAUDE.md or .cursorrules merely ask an AI agent to follow a rule, and the agent is free to read, misread, or skip them; becwright doesn’t ask anyone to behave — it inspects the result.

An advisory note only works when the agent happens to read, understand and follow it. A becwright check doesn’t depend on any of that: it executes on the code itself and returns the same verdict every time, whichever agent, model or human produced the change.

In short: install becwright once, run becwright init inside your project, and from then on every time you save your work (a commit) it checks your code against your rules and stops the commit if a blocking rule is broken. That’s the whole loop — the rest of this page is the detail.

Install

Pick your ecosystem. The npm packages ship a self-contained binary, so no Python is required:

npm install --save-dev becwright    # or global: npm install -g becwright
pnpm add -D becwright
pipx install becwright              # or: pip install becwright

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

Set up a repo

cd your-repo
becwright init      # scaffolds .bec/rules.yaml (language-aware) + installs the hook

init detects whether the repo has Python or JS/TS files and writes a starter .bec/rules.yaml with matching rules, then installs the pre-commit hook. Review the generated rules and run becwright check --all to see the current state.

From then on, every git commit runs the checks. You can also set up by hand: becwright install plus a .bec/rules.yaml you write yourself.

Commands

CommandDescription
becwright demoShow becwright block a sample bad commit (no setup, no git needed)
becwright initScaffold a starter .bec/rules.yaml and install the hook
becwright listList the built-in checks
becwright checkRun rules over the staged files
becwright check --allRun rules over the whole repo (git ls-files)
becwright installInstall the pre-commit hook
becwright uninstallRemove the hook
becwright export <id> [-o file]Export a rule to a .bec.yaml bundle
becwright import <source> [--yes]Import a BEC from a file or http(s) URL

“Staged files”? When you run git add, the files you picked are staged — queued for the next commit. becwright check looks only at those by default (the exact set the commit will create), which is why it’s fast. Use --all to scan the whole project instead.

Exit codes (the number a command returns when it ends; 0 means success): 0 pass · 1 a blocking rule failed · 2 not a git repo / usage error.

What goes in .bec/rules.yaml?

rules:
  - id: no-token-in-logs        # unique identifier
    intent: >                   # what the rule asks for (the "bound" part)
      Session tokens must never reach any log.
    why_it_matters: >           # why it exists (shown when the rule fails)
      A token in the logs lets anyone steal a session.
    rejected_alternatives:      # optional: approaches considered and dropped
      - "Redact at log time -> too easy to bypass"
    paths:                      # glob patterns of files this rule applies to
      - "src/**/*.py"
    check: "becwright run no_token_in_logs"
    severity: blocking          # blocking (stops commit) | warning (only warns)

Fields

FieldRequiredMeaning
idyesUnique rule id
pathsyesGlob patterns (see below)
checkyesShell command to run (the executable check)
intentnoWhat the rule enforces
why_it_mattersnoWhy it matters; printed when the rule fails
rejected_alternativesnoContext: approaches that were dismissed
severitynoblocking (default) or warning

Globs

  • * matches anything except /.
  • ** matches across directories.
  • e.g. src/**/*.py matches src/a.py and src/x/y/z.py; src/*.py matches only the top level.

Where can you get ready-made rules?

Don’t want to write rules yourself? Import one from the catalog with a single command — becwright shows you the rule, then drops it into your .bec/rules.yaml:

# Python
becwright import https://raw.githubusercontent.com/DataDave-Dev/becwright/main/becs/no-token-in-logs.bec.yaml
becwright import https://raw.githubusercontent.com/DataDave-Dev/becwright/main/becs/no-debug-remnants.bec.yaml

# JavaScript / TypeScript
becwright import https://raw.githubusercontent.com/DataDave-Dev/becwright/main/becs/no-debugger-js.bec.yaml
becwright import https://raw.githubusercontent.com/DataDave-Dev/becwright/main/becs/no-console-log-js.bec.yaml

# Any language
becwright import https://raw.githubusercontent.com/DataDave-Dev/becwright/main/becs/no-hardcoded-secrets.bec.yaml

The full list (Python, JS/TS, Go, Rust) lives in the becs/ catalog.

Next steps