DataDave-Dev/becwright

GitHub: DataDave-Dev/becwright

becwright 是一款确定性的 pre-commit 守卫工具,通过可执行的规则阻断 AI 生成的违规代码提交,确保代码质量约束被真正执行而非被无视。

Stars: 3 | Forks: 7

becwright

# becwright [![CI](https://static.pigsec.cn/wp-content/uploads/repos/cas/ad/ad5834178f7599af9fdda11629d49cae07f2997beec49821b2920eff5bfd50e7.svg)](https://github.com/DataDave-Dev/becwright/actions/workflows/ci.yml) [![npm](https://img.shields.io/npm/v/becwright?logo=npm)](https://www.npmjs.com/package/becwright) [![npm 下载量](https://img.shields.io/npm/dm/becwright?logo=npm&label=downloads)](https://www.npmjs.com/package/becwright) [![PyPI](https://img.shields.io/pypi/v/becwright?logo=pypi&logoColor=white)](https://pypi.org/project/becwright/) [![Python 版本](https://img.shields.io/pypi/pyversions/becwright?logo=python&logoColor=white)](https://pypi.org/project/becwright/) [![许可证: MIT](https://img.shields.io/badge/license-MIT-green)](LICENSE) **AI 编码 agent 的执行层。** (*bec-wright* — "wright" 意为制造者,就像 *playwright*) 运行规则,而不是被无视的笔记。你的 `CLAUDE.md` 是一个*指示牌*; becwright 则是*守卫* —— 它会针对代码运行你的规则,并在规则被破坏时阻止 提交,无论是由哪个模型(或人)编写的。 确定性的,而非概率性的 · 任何语言 · 无需 Python · 阻止提交**并且**给出*原因*。 自食其力(Dogfooded) —— 此仓库的每一次提交都由 becwright 自己在 CI 中的 [`.bec/rules.yaml`](.bec/rules.yaml) 把关。 ## 之前 / 之后 你的 agent 编写了 `checkout.py` —— 一个硬编码的 API key,一个对促销字符串的 `eval()` —— 并留下一张便条“*以后再清理*”。没人去清理。它就这样上线了。 有了 becwright,这种提交永远不会发生:

becwright blocking a commit live: git commit runs, two blocking rules fire with their why, the commit is stopped

## 开始使用 安装一次,按项目设置。**两步即可完成。** ``` npm install -g becwright # self-contained binary, no Python (or: pipx install becwright) cd your-project becwright init # detects your language, writes .bec/rules.yaml, installs the hook ``` 就是这样。从现在起,每次 `git commit` 都会自动运行检查,并阻止 违反阻断性规则的提交。你再也不需要手动调用 becwright 了。 - **有技术债的现有代码库?** `becwright init --baseline` 会将 已经违反的规则设为 `warning`(不会阻止任何合法操作),并将干净的规则设为 `blocking`。随时间推移修复技术债,然后逐个提升规则级别。 - **已经有 `CLAUDE.md` 了?** `becwright init --from-claude-md` 会将 它识别出的禁令(secrets、`eval`、`debugger`、`console.log` 等) 转化为可执行的规则。基于判断的指导则保留在 `CLAUDE.md` 中。 可与 `--baseline` 组合使用。
其他安装方式:pnpm、pip、项目本地安装 → ``` pnpm add -g becwright pipx install becwright # or: pip install becwright / uv tool install becwright npm install --save-dev becwright # project-local; the hook finds it in node_modules/.bin ``` 通过 npm/pnpm 安装**不需要 Python** —— 每个平台(`linux-x64`、`linux-arm64`、`darwin-x64`、`darwin-arm64`、`win32-x64`) 都会附带一个独立的二进制文件。 在其他任何平台上,请使用 `pipx install becwright` 并搭配 Python 3.10 或更高版本。
### 在 90 秒内感受它的阻断 信任一个守卫最快的方法就是看它阻止你一次: ``` cd your-project && becwright init # rules + hook, one command echo 'api_key = "AKIAIOSFODNN7EXAMPLE"' >> demo_leak.py git add demo_leak.py && git commit -m "test the guard" # BLOCK no-hardcoded-secrets (blocking) # 为什么这很重要:repo 中的 secret 会永远留在 git history 中…… # >>> Commit BLOCKED:违反了 blocking 规则。 git reset demo_leak.py && rm demo_leak.py # undo the experiment git commit -m "..." # normal commits just pass ``` 这个循环 —— 违反规则、被阻止并*附带原因*、修复、提交 —— 就是 becwright 永远、自动所做的一切。 ## 为什么要守卫,而不是指示牌 AI agent 编写了一个模块,并注明“*绝对不能记录 session token*。” 几个月后,另一个 agent 重新生成了它,压根没读这条注释,导致 token 出现在了日志里。直到生产环境爆发问题才有人察觉。 指示牌是在*请求*;守卫是在*检查*。就在你的工作保存之前,becwright 会针对 代码运行你的规则:✅ 全部通过 → 提交成功; ❌ 某条规则被破坏 → 它会阻止你,指明规则及其*原因*,并一直等待直到 你修复它。`CLAUDE.md` 中的注释是**概率性**的 —— 它取决于 agent 是否阅读并遵守。becwright 规则是**确定性**的 —— 无论哪个模型进行了更改,它都会针对真实 代码运行并返回通过/失败的结果: | | CLAUDE.md 中的注释 | becwright 规则 | |---|---|---| | 它的作用 | *请求*被遵守 | *验证*已被遵守 | | 依赖于 | Agent 阅读并遵守 | 无需依赖 —— 直接针对代码运行 | | 结果 | 很可能遵守 | 保证遵守 | | 类比 | “限速”标志 | 路面上的减速带 | 这两个层次是互补的:`CLAUDE.md` 用于预防(因此 95% 的代码第一次就能写对), becwright 则是为漏网的 5% 提供的安全网。
对 commit 和 hook 不熟悉? — 一盒词汇表 **commit** 是在 git 中保存的代码快照。**hook** 是 git 在特定时刻自动运行的 小型脚本 —— becwright 使用的是 *pre-commit* hook,它会在 commit 保存之前触发。 你永远不需要手动运行它;git 会自动完成。
## 核心概念:BEC (Bound Executable Constraint,绑定可执行约束) BEC 是一种具有三个特性的约束,目前没有任何现成的工件能同时具备: - **绑定** —— 规则从诞生之初就与其*意图*和创建它的决策(即*原因*)相 绑定;它不是一条没有上下文的松散规则。 - **可执行** —— 它包含一个可运行并返回通过/失败结果的检查;它不是 一段仅仅指望人们遵守的散文。 - **可移植** —— 它可以从一个 repo 导出到另一个 repo, 就像一个包(这是长期产生网络效应的关键)。 `.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 to them can steal a user's session. paths: ["src/**/*.py"] exclude: ["src/logging_setup.py"] # optional: globs carved out of paths check: "becwright run no_token_in_logs" severity: blocking # blocking = stops the commit | warning = only warns ``` 完整的字段参考:[`documentation/usage.md`](documentation/usage.md)。 ## 你能得到什么 - **阻断提交,而不仅仅是警告** —— `blocking` 会阻止 `git commit`; `warning` 仅作通知;`advisory` 用于承载判断性规则(例如 LLM 审查器), 它们只报告而不阻断,并且有明确标签让你知道哪些是有保证的。 - **任何语言** —— 引擎会匹配文件 glob 并运行命令;无需编写代码的 `forbid` 正则表达式适用于 Python、JS/TS、Go、Rust 或任何其他语言。 - **每一条规则都附带其存在的原因**,在触发时会立刻显示。 - **可移植的规则** —— 将 BEC `export` 为单个 `.bec.yaml`,在 另一个 repo 中 `import` 它;自定义检查也会随代码一起移动,并受到信任门控的保护。 - **离线目录** —— `becwright search` / `add` 可安装现成的规则, 打包在工具内部。 - **适应你的配置** —— 原生 git hook、pre-commit 框架、Husky,或者是 一个必需的 GitHub Action,它能够堵住 `--no-verify` 的漏洞。 - **为 AI agent 准备就绪** —— Claude Code 插件、`check --json` 以及 MCP server,以便 agent 可以查询和扩展规则。 - **微小且值得信赖** —— 仅有一个依赖(`pyyaml`),没有 `eval`/`exec`, 在其自身的 repo 的 CI 中进行了自测。 ## 命令 | 命令 | 作用 | |---|---| | `becwright demo` | 展示 becwright 阻断一个示例的错误提交(无需设置,无需 git) | | `becwright init` | 生成初始的 `.bec/rules.yaml` 并安装 hook | | `becwright init --baseline` | 同上,但将已违反的规则设为 `warning`(采用时不会阻断操作) | | `becwright init --from-claude-md` | 从 repo 的 `CLAUDE.md` 中派生规则(尽最大努力) | | `becwright list` | 列出内置的检查 | | `becwright check` | 对暂存区的文件运行规则 | | `becwright check --diff ` | 仅对相较于 `` 发生更改的文件运行规则(用于 CI/PR) | | `becwright why [id]` | 显示规则背后的意图及原因 —— repo 的决策记忆(`--json` 供 agent 使用) | | `becwright validate` | 验证 `.bec/rules.yaml` 而不运行任何检查(适用于编辑器和 CI) | | `becwright doctor` | 诊断配置:规则文件、检查、hook 和 hook 管理器 | | `becwright search [query]` | 列出内置目录中现成的 BEC | | `becwright add ` | 将目录中的 BEC 安装到 `.bec/rules.yaml`(离线) | | `becwright install` / `uninstall` | 安装 / 移除原生 hook | | `becwright export ` | 将 BEC 导出到 `.bec.yaml` 文件 | | `becwright import ` | 从另一个 repo 导入 BEC | ## 已经在使用 pre-commit 或 Husky? becwright 无需执行 `becwright install` 即可插入使用。 **[pre-commit](https://pre-commit.com)** —— 添加到 `.pre-commit-config.yaml`: ``` repos: - repo: https://github.com/DataDave-Dev/becwright rev: v1.0.0 hooks: - id: becwright ``` **Husky**(JS/TS repo) —— 在 `.husky/pre-commit` 中: ``` npx becwright check ``` 无论哪种方式,becwright 都会读取 `.bec/rules.yaml` 并在 破坏性规则未被遵守时阻断提交。运行一次 `becwright init` 以生成规则脚手架 —— 它会检测 Husky、pre-commit 框架或自定义的 `core.hooksPath`,跳过 其自身的 hook,并打印出你需要添加的确切代码行。 ## 作为必需的 CI 检查 (GitHub Action) 提交 hook 存在于每个开发者的机器上 —— 而 `git commit --no-verify` 可以跳过它。一个**必需的 CI 检查是无法被跳过的**:在每次 Pull Request 上运行 becwright 使得规则成为基础设施,而不是一种建议。 添加 `.github/workflows/becwright.yml`: ``` name: becwright on: pull_request jobs: becwright: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 with: fetch-depth: 0 # full history so the merge-base with the PR base exists - uses: DataDave-Dev/becwright@v1.0.0 ``` 默认情况下,它仅针对 PR 相较于 base branch **更改的文件**进行检查 —— 预先存在的技术债永远不会导致构建失败,因此它可以干净地应用在庞大的 代码库中。在分支保护中将此检查设为*必需*,规则就会变得 不可商量。输入项(`base`、`version`、`python-version`、`args`)位于 [Marketplace 页面](https://github.com/marketplace/actions/becwright);或者跳过 该 action,直接在任何工作流步骤中运行 `becwright check --diff origin/main`。 ## 与 AI agent 配合使用 becwright 是一张确定性的安全网,用于捕捉 AI agent 疏忽遗漏的内容。这里有一个 Claude Code 插件,agent 可以为你安装并驱动它: ``` /plugin marketplace add DataDave-Dev/becwright /plugin install becwright@becwright ``` 它会添加一个 `becwright` 技能和一个 `/becwright` 命令。详见 [`integrations/claude-code/`](integrations/claude-code/)。 要获取结构化的结果,`becwright check --json` 会打印出机器可读的 摘要,而 `becwright mcp`(`pipx install "becwright[mcp]"`)会运行一个 MCP server,以便任何 agent 都能检查规则、从你的 `CLAUDE.md` 中提出新规则建议,并在写入前进行预览。详见 [`documentation/mcp.md`](documentation/mcp.md)。 双向的信号传递保持精简:`becwright why --json` 在 agent 编写代码*之前*, 将其绝不能违反的决策传递给它;而被阻断的提交 则会返回那条被破坏的规则、它的*原因*以及确切的代码行 —— 这种特定的 约束,而不是把整个风格指南重新塞进上下文中。 ## 内置检查 每个检查都是从 `check` 字段调用的模块。它们通过在 你的文件文本中搜索模式来工作 —— 这种设计故意保持简单且可预测; 真正的价值在于将每条规则与其*原因*绑定在一起。如果需要更深入的分析,可以 将规则指向任何你已信任的工具作为其检查 —— 规则携带*原因*, 而由工具执行检测: ``` - id: no-secrets-gitleaks intent: > No secret may ever be committed, as judged by gitleaks' full ruleset. why_it_matters: > A leaked credential in git history is exposed forever, even after a revert. paths: ["**/*"] check: "gitleaks detect --no-git --redact --exit-code 1" severity: blocking - id: python-passes-ruff intent: "Python code must pass the team's ruff ruleset before commit." why_it_matters: "Consistent lint keeps review focused on logic, not style." paths: ["**/*.py"] check: "xargs ruff check --force-exclude" severity: warning ``` 更多现成的模式(semgrep、eslint、冻结路径、架构 边界、CI):**[配方](documentation/recipes.md)**。 | 检查 | 检测到的内容 | 语言 | 建议的严重性 | |---|---|---|---| | `forbid` | 你传入的任何正则表达式 (`--pattern`) | 任意 | 视情况而定 | | `require` | *必须*出现的正则表达式 (`--pattern`)(例如许可证头) | 任意 | 视情况而定 | | `max_lines` | 超过 `--max` 行的文件 | 任意 | `warning` | | `filename` | 匹配 `--forbid` 或不匹配 `--require 的文件名 | 任意 | 视情况而定 | | `no_token_in_logs` | 日志调用中的 token/凭证 | Python | `blocking` | | `hardcoded_secrets` | AWS key、私钥、`password = "..."` 字面量 | 任意 | `blocking` | | `debug_remnants` | 遗忘的 `breakpoint()`、`pdb.set_trace()`、`import pdb` | Python | `blocking` | | `dangerous_eval` | `eval()` / `exec()` 调用 | 任意 | `blocking` | | `conflict_markers` | 遗留的 git 合并冲突标记 (`<<<<<<<`) | 任意 | `blocking` | | `wildcard_imports` | `from x import *` | Python | `warning` | 不想自己写规则?目录内置在 becwright **内部** —— 只需一条命令,无需 URL,离线可用: ``` becwright search # list every BEC in the catalog becwright add no-token-in-logs # install one; becwright shows it first ``` 完整列表(Python、JS/TS、Go、Rust —— 更多语言 [正在开发中](https://github.com/DataDave-Dev/becwright/milestone/2))位于 [`src/becwright/becs/`](src/becwright/becs/)。 ## 你的第一条自定义规则(任何语言) 编写规则最快的方法 —— 无需编写代码 —— 就是使用 `forbid` 检查, 如果正则表达式出现在文件中,该检查就会失败: ``` rules: - id: no-debugger-js intent: > Do not leave 'debugger;' in JavaScript/TypeScript code. why_it_matters: > A forgotten 'debugger' halts execution and should not reach production. paths: ["**/*.js", "**/*.ts"] check: "becwright run forbid --pattern '\\bdebugger\\b'" severity: blocking ``` `forbid` 接受 `--pattern REGEX`、`--ignore-case` 和 `--message TEXT`。如需 更细致的检查,可以使用任何语言编写脚本(从 stdin 读取文件列表, 以 0/1 退出),并将 `check` 指向它 —— 参见 [编写检查](documentation/writing-checks.md)。 ## 在 repo 之间共享 BEC BEC 是**可移植的**:一个包就是一个独立的 `.bec.yaml` 文件( 规则 + 如果是自定义的话还包含检查的代码)。 ``` becwright export no-token-in-logs -o no-token-in-logs.bec.yaml # source repo becwright import no-token-in-logs.bec.yaml # target repo (file or URL) ``` 在导入时,becwright **会显示检查的代码并请求确认** —— 导入一个 BEC 就等于导入了将在每次 commit 时运行的代码。在 自动化环境中请使用 `--yes`。详情: [可移植性](documentation/portability.md)。 ## becwright 的对比 becwright 不是 linter,也不仅仅是一个 hook 运行器 —— 它是使 *规则*变得可移植并与其原因绑定的那一层,并据此阻断提交。 | | becwright | pre-commit / Husky | gitleaks / linters | CLAUDE.md / .cursorrules | |---|:---:|:---:|:---:|:---:| | 运行真正的检查 | ✅ | ✅ (运行其他工具) | ✅ | ❌ 散文 | | 阻断提交 | ✅ | ✅ | ✅ | ❌ | | 携带*原因* (意图) | ✅ | ❌ | ❌ | ⚠️ 未强制执行 | | repo 之间的可移植规则 | ✅ `export`/`import` | ⚠️ 复制配置 | ⚠️ | ⚠️ | | 任何语言,无需按工具开发插件 | ✅ `forbid` 正则表达式 | ⚠️ | ❌ 特定工具 | n/a | becwright 是对这些工具的**补充**,而不是替代:将 gitleaks 或 linter *作为* becwright 检查来运行,或者将 becwright *加在* pre-commit / Husky *内部*。 ## 文档 完整文档位于 [`documentation/`](documentation/): - **新手入门:** [用法](documentation/usage.md) — 安装、 命令、退出代码以及如何编写规则。 - **用于常见任务的复制粘贴规则** (gitleaks/ruff/semgrep 作为检查、冻结路径、架构边界、CI):[配方](documentation/recipes.md)。 - **想要添加你自己的规则:** [编写检查](documentation/writing-checks.md)。 - **在项目之间共享规则:** [可移植性](documentation/portability.md)。 - **好奇它的内部工作原理:** [架构与流程](documentation/architecture.md)。 - **将其与 AI agent 连接:** [MCP & JSON 输出](documentation/mcp.md)。 ## 稳定性 becwright 是**稳定** (`1.0`) 的:`rules.yaml` schema、bundle 格式、检查 名称、CLI 退出代码、`check --json` 结构和 MCP 签名只会在 大版本更新时被破坏,并且会提前提供一个次版本的弃用通知。在 CI 中锁定一个版本,`1.x` 升级 永远不会破坏你的规则。完整的契约和政策: [稳定性与版本控制](documentation/stability.md)。 ## 路线图 becwright 刻意保持小型化。近期的发展方向位于 [里程碑](https://github.com/DataDave-Dev/becwright/milestones): **v1.1** 将目录扩展到更多语言(Ruby、PHP、Java、C#、Shell —— 每一个都是 [良好的首个问题](https://github.com/DataDave-Dev/becwright/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22)), **v1.2** 改善规则编写的开发者体验 (DX)(简化的检查语法、用于 `rules.yaml` 的 JSON Schema),**v1.3** 使 Windows 成为受支持的一等公民。 为了保持简单和确定性,被**刻意排除在范围外**的功能包括:基于 AST 的 分析、深度的按语言划分的工具套件以及对 BEC 的加密签名。 ## 常见问题 **为什么不直接用 Ruff / Black / pre-commit?** 使用它们吧 —— becwright 并不与 它们竞争。Black 负责格式化,Ruff 负责检查代码,pre-commit 负责*运行*工具。它们都没有为你提供一条 *绑定其原因*、能够阻断提交并且可以迁移到另一个 repo 的规则。becwright 就是那一层,而且它非常乐意将 Ruff 或 gitleaks 作为其 检查之一来运行。不同的工作,同一个 pipeline。 **这是一个年轻的项目 —— 为什么要信任它来管理我的提交?** 因为需要信任的东西非常 少:仅有一个依赖(`pyyaml`),没有 `eval`/`exec`,检查就是 简单的正则表达式,不到一分钟就能看完,并且采用 MIT 许可证。而且它是 自测过的(自食其力) —— becwright 自己的提交就是由 becwright 把关的。如果它出了问题,这个 repo 根本无法构建。 **agent 可以直接删除规则吗?** 可以 —— 但是删除规则会在 diff 中留下 一行可见的修改,这在代码审查 (review) 时会被标记出来,而无视 `CLAUDE.md` 中的注释 则不会留下任何痕迹。一个你必须公开删除的守卫,胜过一个你可以悄悄绕过的指示牌。 **`pre-commit` 不是已经做到这一点了吗?** 它运行工具;但它并没有为你提供一条 携带*原因*并在 repo 之间迁移的规则。你甚至可以在 pre-commit *内部*运行 becwright —— 见[上文](#already-using-pre-commit-or-husky)。 **我需要 Python 吗?** 不需要。`npm i -g becwright` 安装的是一个独立的二进制文件; `pipx install becwright` 也同样有效。 **它在 Windows 上能运行吗?** 目前处于测试阶段。CLI 和 hook 可以在 Git Bash 下运行 (Git for Windows 提供了该环境),但 Windows 尚未在 CI 中进行测试 —— 已知的缺陷记录在 [#31](https://github.com/DataDave-Dev/becwright/issues/31) 中,而成为 受支持的一等公民是 v1.3 里程碑的目标。在此之前,请将 Windows 视为尽力而为的支持状态。 **我该如何忽略单行代码?** 在其上添加一条 `becwright: ignore` 注释。 **导入 BEC 安全吗?** becwright 在安装前会显示检查的代码并要求 确认。请像对待任何不受信任的脚本一样对待不受信任的 bundle。 ## 贡献 欢迎做出贡献 —— 参见 [CONTRIBUTING.md](CONTRIBUTING.md) 和 [行为准则](CODE_OF_CONDUCT.md)。发现了安全问题?请遵循 [安全政策](SECURITY.md)。[更新日志](CHANGELOG.md) 记录了每一次 发布。 ## 许可证 [MIT](LICENSE) © Alonso David De Leon Rodarte
标签:AI辅助编程, Git钩子, IPv6支持, MITM代理, pre-commit, SOC Prime, TCP/UDP协议, 云安全监控, 开发工具, 暗色界面, 逆向工具, 静态分析