Skip to content

Commit d8126cd

Browse files
authored
Merge branch 'main' into feat/doctor-validate
2 parents 92071ec + b24a58b commit d8126cd

11 files changed

Lines changed: 628 additions & 12 deletions

File tree

CONTRIBUTING.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,26 @@ pip install -e ".[dev]"
1212
pytest
1313
```
1414

15+
## Map of the code
16+
17+
Everything lives under `src/becwright/`[architecture.md](documentation/architecture.md)
18+
has the full picture and the exact check flow; this is the one-paragraph version:
19+
20+
| Module | Owns |
21+
|---|---|
22+
| `cli.py` | argparse commands; each `_cmd_*` is one subcommand |
23+
| `engine.py` | glob matching + running checks (subprocess per rule) |
24+
| `rules.py` | the `Rule` model and validated loading of `.bec/rules.yaml` |
25+
| `git.py` | repo root, staged files, staged snapshot, native hooks |
26+
| `bundle.py` / `catalog.py` | export/import bundles; the packaged catalog |
27+
| `report.py` | shared JSON payloads (`check --json`, `why --json`, MCP) |
28+
| `checks/` | built-in checks (each one file, shared skeleton) |
29+
| `becs/` | catalog bundles (`<id>.bec.yaml`) |
30+
31+
becwright is dogfooded: this repo's own [.bec/rules.yaml](.bec/rules.yaml)
32+
gates every commit. After `pip install -e ".[dev]"`, run `becwright check --all`
33+
here to see it police itself.
34+
1535
## Workflow
1636

1737
`main` is protected: changes land via pull request with CI green.

README.es.md

Lines changed: 57 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ Con becwright, el commit no llega a existir:
3838
> **Velo vos mismo en 5 segundos** — sin configurar nada, sin git, sin tocar tu
3939
> máquina:
4040
> ```bash
41-
> npx becwright demo # sin instalar · o: pipx run becwright demo
41+
> npx becwright demo # sin instalar · o: uvx becwright demo · pipx run becwright demo
4242
> ```
4343
4444
## Empezar
@@ -54,6 +54,10 @@ becwright init # detecta tu lenguaje, escribe .bec/rules.yaml, inst
5454
Listo. A partir de ahora cada `git commit` corre los chequeos solo y frena un
5555
commit que rompa una regla blocking. No volvés a llamar a becwright a mano.
5656

57+
> **¿Cuál instalación?** `npm install -g` para probarlo o para uso individual;
58+
> `npm install --save-dev becwright` para un repo de equipo, así la versión
59+
> queda fijada en `package.json` y el hook lo encuentra en `node_modules/.bin`.
60+
5761
- **¿Código existente con deuda?** `becwright init --baseline` arranca en
5862
`warning` las reglas que *ya* tienen violaciones (no se frena nada legítimo) y
5963
en `blocking` las limpias. Limpiá la deuda con el tiempo y graduá cada regla.
@@ -67,7 +71,7 @@ commit que rompa una regla blocking. No volvés a llamar a becwright a mano.
6771

6872
```bash
6973
pnpm add -g becwright
70-
pipx install becwright # o: pip install becwright
74+
pipx install becwright # o: pip install becwright / uv tool install becwright
7175
npm install --save-dev becwright # local al proyecto; el hook lo encuentra en node_modules/.bin
7276
```
7377

@@ -76,6 +80,26 @@ Por npm/pnpm **no hace falta Python** — viene un binario autónomo por platafo
7680
cualquier otra plataforma, usá `pipx install becwright`.
7781
</details>
7882

83+
### Sentilo frenar, en 90 segundos
84+
85+
La forma más rápida de confiar en un guardia es verlo frenarte una vez:
86+
87+
```bash
88+
cd tu-proyecto && becwright init # reglas + hook, un comando
89+
90+
echo 'api_key = "AKIAIOSFODNN7EXAMPLE"' >> demo_leak.py
91+
git add demo_leak.py && git commit -m "probar el guardia"
92+
# BLOCK no-hardcoded-secrets (blocking)
93+
# Why it matters: un secreto en el repo queda en la historia de git para siempre...
94+
# >>> Commit BLOCKED: a blocking rule was broken.
95+
96+
git reset demo_leak.py && rm demo_leak.py # deshacer el experimento
97+
git commit -m "..." # los commits normales pasan sin más
98+
```
99+
100+
Ese ciclo — violar, ser frenado *con el porqué*, arreglar, commitear — es todo
101+
lo que becwright hace, para siempre, automáticamente.
102+
79103
## Por qué un guardia, no un cartel
80104

81105
Un agente de IA escribe un módulo y deja una nota: *"esto nunca debe loguear
@@ -266,7 +290,29 @@ Cada check es un módulo que se invoca desde el campo `check`. Funcionan
266290
buscando texto en tus archivos con un patrón — simples y predecibles a
267291
propósito; el verdadero valor está en atar cada regla a su *por qué*. Para
268292
análisis más profundo, apuntá una regla a cualquier herramienta que ya uses
269-
(gitleaks, ruff, semgrep) como su check.
293+
como su check — la regla lleva el *por qué*, la herramienta hace la detección:
294+
295+
```yaml
296+
- id: no-secrets-gitleaks
297+
intent: >
298+
Ningún secreto puede commitearse, según el ruleset completo de gitleaks.
299+
why_it_matters: >
300+
Una credencial filtrada en la historia de git queda expuesta para siempre,
301+
incluso después de un revert.
302+
paths: ["**/*"]
303+
check: "gitleaks detect --no-git --redact --exit-code 1"
304+
severity: blocking
305+
306+
- id: python-passes-ruff
307+
intent: "El código Python debe pasar el ruleset de ruff del equipo antes del commit."
308+
why_it_matters: "Un lint consistente mantiene el review enfocado en la lógica, no en el estilo."
309+
paths: ["**/*.py"]
310+
check: "xargs ruff check --force-exclude"
311+
severity: warning
312+
```
313+
314+
Más patrones listos (semgrep, eslint, rutas congeladas, límites de
315+
arquitectura, CI): **[recetas](documentation/recipes.es.md)**.
270316

271317
| Check | Qué detecta | Lenguaje | Severidad sugerida |
272318
|---|---|---|---|
@@ -353,6 +399,8 @@ La documentación completa vive en [`documentation/`](documentation/README.es.md
353399

354400
- **Recién empezás:** [uso](documentation/usage.es.md) — instalación, los
355401
comandos, códigos de salida y cómo escribir una regla.
402+
- **Reglas para copiar y pegar** (gitleaks/ruff/semgrep como checks, rutas
403+
congeladas, límites de arquitectura, CI): [recetas](documentation/recipes.es.md).
356404
- **Querés agregar tu propia regla:** [escribir checks](documentation/writing-checks.es.md).
357405
- **Compartir reglas entre proyectos:** [portabilidad](documentation/portability.es.md).
358406
- **Curiosidad por cómo funciona adentro:** [arquitectura y flujo](documentation/architecture.es.md).
@@ -406,8 +454,12 @@ de pre-commit — ver más arriba.
406454
**¿Necesito Python?** No. `npm i -g becwright` instala un binario autónomo;
407455
`pipx install becwright` también funciona.
408456

409-
**¿Funciona en Windows?** Sí, vía Git Bash (el hook es un script `sh`, que Git
410-
para Windows provee). La CLI `becwright` en sí es multiplataforma.
457+
**¿Funciona en Windows?** En beta. La CLI y el hook corren bajo Git Bash (que
458+
Git para Windows provee), pero Windows todavía no se ejercita en CI — los
459+
huecos conocidos están en
460+
[#31](https://github.com/DataDave-Dev/becwright/issues/31) y el soporte de
461+
primera clase es el milestone v1.3. Hasta entonces, tratá Windows como
462+
best-effort.
411463

412464
**¿Cómo ignoro una línea?** Poné un comentario `becwright: ignore` en ella.
413465

README.md

Lines changed: 56 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ With becwright, the commit never happens:
3737
> **See it yourself in 5 seconds** — no setup, no git, nothing on your machine is
3838
> touched:
3939
> ```bash
40-
> npx becwright demo # zero-install · or: pipx run becwright demo
40+
> npx becwright demo # zero-install · or: uvx becwright demo · pipx run becwright demo
4141
> ```
4242
4343
## Get started
@@ -53,6 +53,10 @@ becwright init # detects your language, writes .bec/rules.yaml, ins
5353
That's it. From now on every `git commit` runs the checks by itself and stops a
5454
commit that breaks a blocking rule. You never call becwright by hand again.
5555
56+
> **Which install?** `npm install -g` to try it out or for solo use;
57+
> `npm install --save-dev becwright` for a team repo, so the version is pinned
58+
> in `package.json` and the hook finds it in `node_modules/.bin`.
59+
5660
- **Existing codebase with debt?** `becwright init --baseline` starts
5761
already-violated rules as `warning` (nothing legitimate is blocked) and clean
5862
rules as `blocking`. Fix the debt over time, then graduate each rule.
@@ -66,7 +70,7 @@ commit that breaks a blocking rule. You never call becwright by hand again.
6670
6771
```bash
6872
pnpm add -g becwright
69-
pipx install becwright # or: pip install becwright
73+
pipx install becwright # or: pip install becwright / uv tool install becwright
7074
npm install --save-dev becwright # project-local; the hook finds it in node_modules/.bin
7175
```
7276
@@ -75,6 +79,26 @@ platform (`linux-x64`, `linux-arm64`, `darwin-x64`, `darwin-arm64`, `win32-x64`)
7579
On any other platform, use `pipx install becwright`.
7680
</details>
7781

82+
### Feel it block, in 90 seconds
83+
84+
The fastest way to trust a guard is to watch it stop you once:
85+
86+
```bash
87+
cd your-project && becwright init # rules + hook, one command
88+
89+
echo 'api_key = "AKIAIOSFODNN7EXAMPLE"' >> demo_leak.py
90+
git add demo_leak.py && git commit -m "test the guard"
91+
# BLOCK no-hardcoded-secrets (blocking)
92+
# Why it matters: a secret in the repo stays in git history forever...
93+
# >>> Commit BLOCKED: a blocking rule was broken.
94+
95+
git reset demo_leak.py && rm demo_leak.py # undo the experiment
96+
git commit -m "..." # normal commits just pass
97+
```
98+
99+
That loop — violate, get blocked *with the why*, fix, commit — is everything
100+
becwright does, forever, automatically.
101+
78102
## Why a guard, not a sign
79103

80104
An AI agent writes a module and notes *"this must never log session tokens."*
@@ -258,7 +282,29 @@ constraint, not the whole style guide re-read into context.
258282
Each check is a module invoked from the `check` field. They work by searching
259283
the text of your files for a pattern — simple and predictable on purpose; the
260284
real value is in tying each rule to its *why*. For deeper analysis, point a
261-
rule at any tool you already trust (gitleaks, ruff, semgrep) as its check.
285+
rule at any tool you already trust as its check — the rule carries the *why*,
286+
the tool does the detection:
287+
288+
```yaml
289+
- id: no-secrets-gitleaks
290+
intent: >
291+
No secret may ever be committed, as judged by gitleaks' full ruleset.
292+
why_it_matters: >
293+
A leaked credential in git history is exposed forever, even after a revert.
294+
paths: ["**/*"]
295+
check: "gitleaks detect --no-git --redact --exit-code 1"
296+
severity: blocking
297+
298+
- id: python-passes-ruff
299+
intent: "Python code must pass the team's ruff ruleset before commit."
300+
why_it_matters: "Consistent lint keeps review focused on logic, not style."
301+
paths: ["**/*.py"]
302+
check: "xargs ruff check --force-exclude"
303+
severity: warning
304+
```
305+
306+
More ready-made patterns (semgrep, eslint, frozen paths, architecture
307+
boundaries, CI): **[recipes](documentation/recipes.md)**.
262308

263309
| Check | What it detects | Language | Suggested severity |
264310
|---|---|---|---|
@@ -344,6 +390,8 @@ Full docs live in [`documentation/`](documentation/):
344390

345391
- **Just getting started:** [usage](documentation/usage.md) — install, the
346392
commands, exit codes, and how to write a rule.
393+
- **Copy-paste rules for common jobs** (gitleaks/ruff/semgrep as checks, frozen
394+
paths, architecture boundaries, CI): [recipes](documentation/recipes.md).
347395
- **Want to add your own rule:** [writing checks](documentation/writing-checks.md).
348396
- **Sharing rules between projects:** [portability](documentation/portability.md).
349397
- **Curious how it works inside:** [architecture & flow](documentation/architecture.md).
@@ -395,8 +443,11 @@ rule that carries its *why* and travels between repos. You can even run becwrigh
395443
**Do I need Python?** No. `npm i -g becwright` installs a self-contained binary;
396444
`pipx install becwright` also works.
397445

398-
**Does it work on Windows?** Yes, via Git Bash (the git hook is a `sh` script,
399-
which Git for Windows provides). The `becwright` CLI itself is cross-platform.
446+
**Does it work on Windows?** In beta. The CLI and hook run under Git Bash
447+
(which Git for Windows provides), but Windows is not yet exercised in CI —
448+
known gaps are tracked in
449+
[#31](https://github.com/DataDave-Dev/becwright/issues/31) and first-class
450+
support is the v1.3 milestone. Until then, treat Windows as best-effort.
400451

401452
**How do I ignore a single line?** Add a `becwright: ignore` comment on it.
402453

documentation/README.es.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ lenguaje simple y después profundiza, así que podés parar donde deje de serte
1010
**Empezá acá**
1111

1212
- [Uso](usage.es.md) — instalación, comandos y cómo escribir una regla. Leé esto primero.
13+
- [Recetas](recipes.es.md) — reglas para copiar y pegar: gitleaks/ruff/semgrep como checks, rutas congeladas, límites de arquitectura, CI, Husky.
1314
- [Escribir checks](writing-checks.es.md) — el atajo sin código `forbid` y luego checks propios en cualquier lenguaje.
1415
- [Portabilidad](portability.es.md) — compartir una regla entre proyectos con export/import.
1516

documentation/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ prior background assumed.
1010
**Start here**
1111

1212
- [Usage](usage.md) — install, the commands, and how to write a rule. Read this first.
13+
- [Recipes](recipes.md) — copy-paste rules for common jobs: gitleaks/ruff/semgrep as checks, frozen paths, architecture boundaries, CI, Husky.
1314
- [Writing checks](writing-checks.md) — the no-code `forbid` shortcut, then custom checks in any language.
1415
- [Portability](portability.md) — share a rule between projects with export/import.
1516

0 commit comments

Comments
 (0)