Headroom 贡献指南全解:从 PR 工作流、Real behavior proof 到本地开发环境与架构原则
Headroom 是一个在工具输出、日志、文件与 RAG 块到达 LLM 之前对其进行压缩的上下文优化层,代码库由 Python SDK、Rust 工作区(crates/)与配套代理、MCP 服务器组成。本文基于仓库根目录的 CONTRIBUTING.md 完整展开:先讲清"哪类贡献应该走哪条路径",再逐条拆解 bug 修复的证据要求、新功能规范(spec)与供应链审查清单;最后结合仓库中的真实配置文件(.pre-commit-config.yaml、.commitlintrc.json、Makefile、.github/PULL_REQUEST_TEMPLATE.md)讲透本地开发环境搭建、git hooks 机制与 Ruff/pytest 代码规范,帮助你在提交 PR 前把验证工作做在本地做完,而不是交给评审人。
一、贡献入口:哪类改动走哪条路径
CONTRIBUTING.md 开篇就定调:这些规则存在是因为"跳过它们被坑过",而不是官僚主义。参与贡献即表示同意 CODE_OF_CONDUCT.md。文档用一张表明确了不同贡献类型的入口:
| 类型 | 应该怎么做 |
|---|---|
| 缺陷或小修复 | 直接开 PR(必须带复现步骤 + 测试) |
| 新功能 / 架构级改动 | 先开 issue 或在 Discord 里问,拿到维护者认可后再动手 |
| 纯重构 | 不要提。除非维护者明确要求、且作为某个具体修复的一部分 |
只为修复已知 main 分支失败而改测试/CI |
不要提,团队已在跟踪 |
| 新增依赖或版本升级 | PR 中必须附书面理由(见第四节) |
| 提问 | 去 Discord #help 频道 |
此外有一条硬性限制:每位作者的开放 PR 上限为 10 个,先把已开的 PR 合掉再开新的。
这条分流表的意图很明确:维护者的精力优先花在"有复现、有测试的缺陷修复"上,而对方向未对齐的功能开发、无收益的重构、重复的 CI 修补直接关门。读源码结构可以看到,仓库的 PR 模板 .github/PULL_REQUEST_TEMPLATE.md 把这套要求固化成了勾选清单——从"Testing"的实测输出粘贴框,到"Real Behavior Proof"的四要素,再到"Review Readiness"的自评审框,PR 模板本身就是贡献规则的机器可读版本。
二、两条指导原则:验证是你的事,供应链是真威胁
文档"Guiding principles"一节给出两条总纲:
- 验证是作者的工作,不是评审人的工作(Verification is the author's job, not the reviewer's)。
- 供应链是真实威胁——任何依赖变更都要经过人工审查,每一次,没有例外。
第 2 条在仓库里能读到具体的工程背景:pyproject.toml 对核心依赖做了大量带注释的版本锁定与排除,例如 ast-grep-cli>=0.30.0,!=0.44.1(0.44.1 是一个携带恶意二进制的供应链污染构建),[tool.uv.constraint-dependencies] 里逐项列出针对传递依赖的 CVE 最低版本约束(pygments、gitpython、lxml-html-clean、cryptography 等)。这些注释本身就是"依赖变更必须写明理由"这条规则在日常维护中的落地形态。
三、Bug 修复与"Real behavior proof"
3.1 缺陷 PR 的两个必备件
每个 bug-fix PR 必须包含:
- 一个复现——最小代码、失败的测试,或明确的复现步骤;
- 一个在修复前失败、修复后通过的测试(单元、集成或 e2e 均可)。
如果确实无法编写测试,必须在 PR 中明确说明,并解释你实际是如何验证的。
3.2 每个外部 PR 都要求"真实行为证明"
原文的表述很直白:"We can't merge what we can't verify."(我们无法合并无法验证的东西)。PR 正文必须包含一个 Real behavior proof 小节,覆盖四个要点:
- 测试所用的环境(操作系统、Python 版本、配置、provider/模型);
- 打补丁之后运行过的确切命令或步骤;
- 修复后的证据 + 观察到的结果;
- 你没有测试什么。
证据的合格线也有明确区分:
- ✅ 算数的:截图、录屏、终端输出、复制的实时输出、关联的工件、脱敏后的运行日志;
- ❌ 单独不算数的:单元测试、mock、快照、lint、类型检查、绿色 CI——"它们只能证明测试通过了,不能证明功能是真的在工作"。测试当然要写,但不能替代真实运行证据。
缺少这一节的 PR 可能被自动关闭(autoclosed)。
对应地,.github/PULL_REQUEST_TEMPLATE.md 中已经把这一节模板化:
## Real Behavior Proof
- Environment:
- Exact command / steps:
- Observed result:
- Not tested:
模板还额外要求"Testing"一节里粘贴真实命令输出(pytest、ruff check .、mypy headroom 的勾选与输出),以及一段"Runtime Rollout Safety"清单(功能是否受 rollout 通道管理、默认行为是否改变、kill switch 与回滚路径)——后者对代理这类会拦截真实流量的组件尤为重要。
四、新功能:先规范后代码
功能开发在写代码之前必须走完三步:
- 开一个 feature-request issue(或在 Discord 提出);
- 实现之前先拿到核心维护者的认可(一个 👍);
- 附一份简短的 spec,至少覆盖:
- API 表面(公共函数、配置项、CLI 参数);
- 对现有行为的改变;
- 用户故事——Given / When / Then,黄金路径 + 一个边缘用例;
- 失败模式(Failure modes);
- 恢复 / 韧性(Recovery / resilience);
- 安全考量。
文档的收尾一句话值得记住:"Short and concrete beats long."(短而具体胜过长而空泛)。这套 spec 结构与代码库中可见的架构文档风格一致,例如 RUST_DEV.md 对 Rust 重写各阶段的阻塞项、已知回归、后端选择(InMemoryCcrStore / SqliteCcrStore / RedisCcrStore)都采用"状态 + 证据(测试文件路径)+ 处置结论"的写法,正是"具体、可验证"规范的示范。
五、依赖与供应链审查清单
人工维护者会审查每一个依赖变更。新增或升级包的 PR 必须回答四个问题:
- 为什么是这个包(而不是自己实现 / 用已有依赖);
- 谁在维护它(活跃度、发布节奏、安全记录);
- 安装面(传递依赖、原生代码、安装期/运行期是否需要网络);
- 为什么是这个版本——被允许的理由只有三种:bug 修复、安全补丁、必须的新功能。纯粹为了版本好看而做的升级(cosmetic bump)会被直接关闭。
六、PR 工作流:从分支到标题的完整链路
6.1 七步流程
- Fork 仓库,从
main拉分支; - 安装 Node 18+,然后执行
uv sync --extra dev,再执行make install-git-hooks——这一步会把仓库的预提交检查装到每个 commit 上、把 commitlint 装到每条 commit message 上、把 ci-precheck 装到每次 push 上; - 一个 PR 只做一个逻辑变更;
- 补测试;
- 本地跑:
uv run pytest、uv run ruff check .、uv run ruff format .; - 不要手改
CHANGELOG.md——release-please 会根据你的 Conventional Commit PR 标题自动生成它,所以一个清晰的fix(...)/feat(...)标题本身就是你的 changelog 条目;CI 中有守卫会拒绝手动编辑; - 开 PR:清晰的描述 +
Real behavior proof+ 所需的 spec/理由,并在"Review Readiness"勾选完成前保持 draft 状态。
6.2 标题与 commit message 格式
PR 标题遵循 Conventional Commits:feat:、fix:、docs:、test:、refactor:。commit message 格式在本地由仓库的 commit-msg hook 强制,CI 中再次校验。
仓库里的 .commitlintrc.json 定义了完整的规则:继承 @commitlint/config-conventional,type-enum 允许的 13 种类型为 build、chore、ci、docs、deps、feat、fix、parity、perf、refactor、revert、style、test(注意 parity 是 Headroom 特有的类型,对应 Rust 移植中的 Python 行为对齐工作);同时放开了 body-max-line-length、footer-leading-blank 和 subject-case 三项默认约束。
评审合入的条件:CI 全绿、一位维护者 review、覆盖率持平或提升。
6.3 本地 git hooks:把 CI 搬进你的终端
make install-git-hooks 背后是 scripts/install-git-hooks.sh,它安装三层钩子:
- pre-commit:每次提交时运行 .pre-commit-config.yaml 中的检查;
- commit-msg:每次提交时运行 commitlint 校验 Conventional Commit 格式;
- pre-push:每次 push 前运行
make ci-precheck,即与 GitHub Actions 完全相同的门禁。
脚本注释里记录了引入 pre-push 的动机:某次 push 连中五个 CI 失败(cargo fmt 漂移、多余的 x86_64-apple-darwin wheel、两个 CI 分支缺少 Rust 扩展、commitlint 警告被当错误处理),而 pre-commit 钩子的引入则是因为有 PR 在 ruff 钩子从未安装给贡献者的情况下带着导入顺序违规合入了主干。
.pre-commit-config.yaml 中的具体钩子包括:
sync-plugin-versions(scripts/sync-plugin-versions.py,提交时同步各插件清单中的版本号);verify-ruff-version(校验 Ruff 版本与锁文件一致,防止本地/CI 版本漂移);commitlint(commit-msg 阶段);check-merge-conflict(带--assume-in-merge,连 rebase 残留冲突标记也能抓到);- ruff(
--fix)与 ruff-format,均为 v0.16.3,排除experiments/目录; - mypy v1.14.1,
pass_filenames: false整库跑mypy headroom。
Makefile 中的 ci-precheck 目标则聚合了三类本地门禁:
make ci-precheck # 全部 CI 门禁(rust + python + commitlint)
make ci-precheck-rust # cargo fmt --check + clippy + cargo test --workspace
make ci-precheck-python # 构建 Rust 扩展后,跑 smart_crusher 受影响的一组 pytest 文件
make ci-precheck-commitlint # npx commitlint --from origin/main --to HEAD
设计意图写在 Makefile 注释里:如果 make ci-precheck 是绿的,git push 就不会在 CI 变红。其中 ci-precheck-python 会先执行 scripts/build_rust_extension.sh,因为 SmartCrusher 等转换器会硬导入 PyO3 编译出的 headroom._core。pre-push 钩子内置了逃生通道 git push --no-verify,但脚本明确标注"每一次跳过都是对 CI 翻车的一次掷骰子"。
七、开发环境搭建
7.1 标准本地环境
文档给出的初始化序列:
git clone https://github.com/headroomlabs-ai/headroom.git
cd headroom
python -m venv .venv && source .venv/bin/activate
node --version # Node 18+ required for commitlint hooks
python -m pip install --upgrade pip
python -m pip install -e ".[dev,relevance,proxy]"
python -m pytest
两个适用前提值得注意:
- Node 18+ 是硬要求,因为 commitlint 钩子依赖
npx; - Headroom 使用 pyproject.toml 中声明的
maturin构建后端(build-backend = "maturin"),一个 wheel 同时包含headroom/下的 Python 源码和 Rust 编译产物headroom/_core.so(由 crates/headroom-py 的 cdylib 注入)。老版本pip可能因为找不到setup.py而失败可编辑安装——先升级pip,或改用uv sync --extra dev。
extras 的选择与验证目标相关:dev 提供 pytest/ruff/mypy 等开发依赖,relevance 提供 fastembed 语义相关性栈,proxy 提供 FastAPI/uvicorn/MCP 等代理服务器依赖(见 pyproject.toml 的 [project.optional-dependencies])。
7.2 Dev Containers
仓库为 VS Code / Codespaces 提供两套配置:
- .devcontainer/devcontainer.json——基础环境:文档标注为 Python 3.12、
uv、Node.js、gh。对照配置文件实际内容,容器还固定了 Node 20 与 Rust 1.95.0(带 rustfmt/clippy 组件,与 rust-toolchain.toml 的 stable 版本钉选一致),并把代理端口 8787 设为自动转发的转发端口; - .devcontainer/memory-stack/devcontainer.json——通过 docker compose 额外拉起 Qdrant + Neo4j 两个 sidecar,转发 8787(代理)、6333/6334(Qdrant REST/gRPC)、7474/7687(Neo4j Browser/Bolt);按文档说明,在容器内连接时使用
qdrant:6333与neo4j://neo4j:7687。
容器内日常命令统一为:uv run ruff check .、uv run pytest 等。
7.3 Rust 侧的常用命令
本仓库是 Python + Rust 双栈,贡献涉及 crates/ 时应熟悉 RUST_DEV.md 与 Makefile 中的目标:
| 目标 | 作用 |
|---|---|
make test |
cargo test --workspace |
make test-parity |
运行 headroom-parity 的 parity-run,对 tests/parity/fixtures 下的 Python 录制输出做 Rust 行为比对 |
make bench |
cargo bench --workspace |
make build-proxy |
release 构建 headroom-proxy 并 strip,打印产物体积 |
make build-wheel |
maturin build --release -m crates/headroom-py/Cargo.toml |
make fmt / make lint |
cargo fmt --all / cargo fmt --check + cargo clippy --workspace -- -D warnings |
default-members 会把 headroom-py 排除在裸 cargo test --workspace 之外,避免 PyO3 cdylib 在无 Python 宿主时被当作可执行目标运行。
八、可选的自动化 Review
仓库内置了 .github/copilot-instructions.md,让维护者可以按需启用 GitHub Copilot 代码评审,而不必为每个 PR 增加工作流计费噪音。文档给出的操作路径是:在仓库的 Settings → Rules → Rulesets → Automatically request Copilot code review 中开启或关闭,并建议除非维护者明确需要额外的评审流量,否则保持关闭。
九、编码标准与架构原则
9.1 编码标准
- Ruff 统一负责 lint 与 format,行宽 100,PEP 8。pyproject.toml 的
[tool.ruff]将target-version钉在py310,lint 规则集为E/W/F/I/B/C4/UP(pycodestyle、pyflakes、isort、bugbear、comprehensions、pyupgrade),并把headroom声明为 known-first-party; - 公共函数必须带类型注解,docstring 用 Google 风格。pyproject.toml 的
[tool.mypy]全局开启disallow_untyped_defs,仅对 handler mixin、动态导入较多的模块(headroom.proxy.handlers.*、tokenizers.*、providers.litellm等)做了按模块豁免; - 覆盖新行为 + 边缘用例,新增代码追求 >80% 覆盖率;
- Python 3.10+(
requires-python = ">=3.10",classifiers 覆盖到 3.14),可选功能一律放在 extras 后面,核心安装保持轻量。
9.2 架构原则
文档最后两条原则是对代码风格要求之上更硬的约束:
- 安全优先:绝不丢弃 user/assistant 内容、绝不破坏 tool call/response 配对、畸形内容原样透传、宁可漏报(false negative)也不误伤;
- 性能:transform 在 P99 < 50ms,可选依赖懒加载,先 profile 再优化。
这两条与测试目录的命名可以直接对应上验证方式:tests/test_compress_passthrough.py 验证"压缩失败时透传"、tests/test_lossless_*.py 系列验证无损优先的压缩策略、tests/test_compression_safety_rails.py 验证安全护栏——"绝不破坏 tool call 配对"这类原则在仓库里都有对应的回归测试承接。
十、贡献者如何被署名
贡献者会在三处获得署名:CHANGELOG、GitHub contributors 页面、release notes。而由于 changelog 由 release-please 从 Conventional Commit 标题生成,你的 PR 标题就是最终面向所有用户的署名载体——把 fix(...) / feat(...) 标题写清楚,既是格式要求,也是内容要求。
要点回顾:Headroom 的贡献流程以"验证是作者的责任"为纲——bug 修复要带复现和翻转测试,外部 PR 要带 Real behavior proof(环境、确切命令、证据、未测项),新功能要带六要素 spec,依赖变更要带供应链四问;本地侧则用 make install-git-hooks 把 ruff/mypy/commitlint/ci-precheck 三层门禁装进每个 commit 与 push,配合 Dev Container(Python + Node 20 + Rust 1.95,可选 Qdrant/Neo4j sidecar)即可获得与 CI 一致的开发体验。按这套流程执行,你的 PR 在提交时就已经通过了评审人将要做的大部分验证。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0624
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00