Caveman 开源贡献指南:DCO 签名、MIT/BSL 双轨许可与 PR 前置检查
Caveman 是一个通过"史前人类式"压缩语言把 AI 编码助手的 token 消耗降低约 65% 的 Claude Code skill 与配套压缩引擎。本文基于仓库贡献文档 CONTRIBUTING.md 及其引用的 LICENSING.md、docs/CONTRIBUTING_PROFILES.md,系统讲清向该项目提交代码的完整路径:从 DCO 提交签名的含义,到 MIT 与 BSL-1.1 按目录划分的许可边界,再到维护者的审查关注点和提交 PR 前的自查清单,并深入源码说明"新增一个压缩器"这一核心贡献类型的真实代码契约。读完本文,你能独立判断某次改动落在哪个许可区域、如何正确签名提交,以及如何在动手前满足项目的字节安全与测试要求。
项目接受哪些贡献
CONTRIBUTING.md 开宗明义:PR 欢迎五类贡献——新的压缩器(compressors)、集成(integrations)、agent recipe、bug 修复和文档。其中内容类型压缩器是被单独点名的贡献方向,因为每一个新压缩器都让 Caveman 对一整类新的 payload 形态产生价值。文档列举的候选方向包括 CSV、HTML、SQL dump、notebook 输出和 OpenAPI spec,并给出明确的工作方式:从 engine/ 目录下现有的一个压缩器起步,复制它的形状。
从源码结构看,这个"复制它的形状"有严格的接口依据。所有压缩器实现同一个接口,定义在 engine/compressors/compressor.go:
// Compressor compresses one content type. Every compressor is structural,
// deterministic, idempotent, and fail-closed: on any parse problem it returns
// ok=false and the caller forwards the original bytes unchanged.
type Compressor interface {
// ContentType is the type this compressor handles (e.g. "json").
ContentType() string
// SafetyClass is the compressor's inherent class on the S0–S4 ladder.
SafetyClass() safety.Class
// Compress returns the compressed bytes with ok=true on success.
Compress(input []byte) (out []byte, ok bool)
}
接口的注释即是对贡献者的硬约束:每个压缩器必须是结构性的、确定性的、幂等的、fail-closed 的——任何解析问题都必须返回 ok=false,由调用方把原始字节原样转发出去。这正是 CONTRIBUTING 中"byte-safe"要求的实现层落点,详见后文 PR 前置检查一节。
同文件中的 Default() 注册表展示了当前引擎内置的全部压缩器,这也是新压缩器"起步参考"的候选清单:
- 自动检测可达:
json、log、code(构建期选择 cgo/tree-sitter 或纯 Go go/ast 实现)、diff、searchresult、text、html、tabular、config、terminal; - 仅通过强制
Options.Type可达:tool-schema、无损tool-schema、toon、axtree、repetition。
新压缩器只需实现三个方法,经 Registry.Register 注册后即可被内容类型路由消费;包级注释也明确说明"加一个压缩器就是一个新文件加它的测试",因为压缩器是纯字节变换,不数 token、不存恢复句柄、不碰网络——这些职责由 engine core 在压缩器外围承担。
DCO:用一行签名替代 CLA
该项目不要求签署 CLA 或填写任何表格,而是采用 Developer Certificate of Origin(DCO)机制。DCO 是一行承诺:这段代码是你写的,或者你有权将其贡献出来。操作方式是对每个 commit 添加 sign-off:
git commit -s -m "your message"
-s 参数会在 commit message 末尾追加一个 Signed-off-by: Your Name <your@email> 的 trailer。docs/CONTRIBUTING_PROFILES.md 中对纯 profile 贡献也重复了同一要求,说明 DCO 签名是覆盖全仓库、不分 MIT 区还是 BSL 区的统一前置条件。
许可划分:MIT 与 BSL-1.1 按目录双轨运行
Caveman 采用按目录分裂的许可模型,这是理解任何贡献行为边界的关键。LICENSING.md 是逐目录许可的权威来源,根目录 LICENSE 是 MIT 文本加一段范围说明(指向 Engine-linked 目录使用 LICENSE.BSL),LICENSE.BSL 则是引擎相关代码的 BSL-1.1 规范文本。
MIT 目录:进出的许可对称
以下区域为 MIT:packages/{agent,create-caveman-agent,cli,sdk,subagent-tax}/、packages/shared/contracts/、shared/provider-catalog/、extension 外壳、skill 本体。规则简单:inbound = outbound——你的贡献以同样的 MIT 条款许可出去,无附加义务。
BSL-1.1 目录:贡献附带再许可授予
以下区域为 BSL-1.1:engine/、proxy/、cacheengine/、rewriter/、browse/、mcp/、shrink/、cavemem 的 Go core、shared/platform/。CONTRIBUTING.md 明确指出,向这些区域贡献时你同时授予 Julius Brussee 以商业或 OEM 条款再许可你的贡献的权利。其目的是保持 open-core 模型的连贯性:社区对引擎的改进可以随商业产品和 OEM 伙伴出货,而不是让代码库分裂成两半。你的贡献在公开仓库中保持 BSL-1.1,并和引擎其余部分在同一个 Change Date 日落转为 Apache-2.0。
对照 LICENSE.BSL 的参数段可以确认具体条款:
| 参数 | 取值 |
|---|---|
| Licensor | Julius Brussee |
| Licensed Work | Caveman Engine (c) 2026 |
| Additional Use Grant | 允许内部评估、本地开发、CI 测试、集成以及自有第一方流量的自托管生产使用;不允许以托管/管理/嵌入式服务形式向第三方提供功能,此类用途需商业许可 |
| Change Date | 2030-06-21 |
| Change License | Apache License, Version 2.0 |
LICENSING.md 进一步把 Change Date 表述为"2030-06-21 与该版本首次以 BSL 公开发布满四年之日孰早"。
如果你不舒适 BSL 的再许可授予,CONTRIBUTING.md 给出的出路很直接:贡献 MIT 部分。
逐目录许可速查
以下为 LICENSING.md 中许可表的完整内容(路径相对仓库根目录):
| 路径 | 许可 | 说明 |
|---|---|---|
skills/ |
MIT | 既有 Caveman skill 保持 MIT 不变 |
packages/agent/ |
MIT | Agent 运行时、构建编译器、Claude lane、框架适配器与 coding-agent API |
packages/create-caveman-agent/ |
MIT | 零运行时依赖的 Agent SDK 初始化器 |
packages/cli/ |
MIT | 入口/上手层;会启动 BSL 二进制但不包含引擎代码 |
packages/sdk/typescript/ |
MIT | 薄客户端与结构化 SDK 表面 |
packages/sdk/python/ |
MIT | 薄客户端;发行名 caveman-sdk |
packages/subagent-tax/ |
MIT | 本地零 provider 调用的 harness 前缀度量工具 |
extension/ |
MIT 外壳 | manifest、popup、content script 与 UI 为 MIT;内嵌 engine.wasm 是 BSL-1.1,因此包含它的外壳产物就组合整体携带 BSL 条款 |
packages/shared/contracts/ |
MIT | 公开 wire schema 与生态契约 |
shared/provider-catalog/ |
MIT | 公开 provider/model 元数据与 catalog schema |
mem/js/、mem/py/ |
MIT | cavemem 的薄 JS/Python 客户端 |
engine/ |
BSL-1.1 | 核心压缩 IP 与 CCR |
cacheengine/ |
BSL-1.1 | Provider 原生 prompt-cache 规划器与 wire 引擎 |
rewriter/ |
BSL-1.1 | 引擎关联的反思改写器与恢复门 |
browse/ |
BSL-1.1 | 本地浏览器驱动;内嵌引擎,vendored MIT chromedp 模块 |
proxy/ |
BSL-1.1 | 独立网关与 provider 适配器 |
mcp/ |
BSL-1.1 | Go 二进制内嵌引擎 |
shrink/ |
BSL-1.1 | Go 二进制/包内嵌引擎的 tool-schema 压缩器 |
mem/ Go core |
BSL-1.1 | Go core 内嵌引擎;JS/Python 客户端仍为 MIT |
shared/platform/ |
BSL-1.1 | 静态链接进 BSL Go 二进制 |
该文件还给出新模块的默认规则:任何 import、链接、内嵌或以 Engine-linked 运行时一部分形式出货的新模块,默认为 BSL-1.1,除非后续决策明确将其归类为 MIT 采用面。这对评估"我的新文件该放哪、受什么约束"是直接的判断依据。
变更落在哪里:PR 审查与生成物规则
所有变更以 pull request 形式提交到本仓库。维护者会针对受影响目录检查四件事:许可范围、测试、生成产物(generated artifacts)、安全边界。
Profile-only 变更走窄流程
只改 agent profile 的 PR 遵循更窄的流程,详见 docs/CONTRIBUTING_PROFILES.md。一个纯 profile PR 是向 agents/profiles/ 添加一个 <id>.json,且该 harness 必须满足:说一种既有 wire_protocol、用一种既有 injection.method、使用既有命令或 memory hook 方法(或省略 hooks)、不需要新的 CLI 安装器或网关适配器。标准操作序列:
node agents/compile.mjs
npm install --ignore-scripts --no-audit --no-fund --no-package-lock --prefix packages/cli
npm --prefix packages/cli run build
node --test packages/cli/tests/agent-registry.runtime.mjs packages/cli/tests/agent-shortcut.runtime.mjs packages/cli/tests/porcelain.runtime.mjs
提交时需同时带上 profile 文件与重新生成的 agents/agents.json 和 packages/cli/src/agents.generated.ts。该文档还列出了 profile 编译器的四条安全边界(injection.env 键名白名单正则、环境值只允许指定模板 token、profile 路径必须留在 ~/.<profile-id>/ 内、profile id 与二进制名不得与保留命令冲突),这些控制由 node agents/compile.mjs 强制执行,没有 force 开关也没有逐 profile 例外。
生成文件与源同 PR
CONTRIBUTING.md 有一条容易被忽略但很硬的规则:生成文件必须与其源放在同一个 PR 中提交,并且保留 commit 作者身份与 DCO 签名。上面 profile 流程中"提交 profile + 重新生成的两个文件"正是这条规则的具体实例——CI 会重跑编译器来核对生成物是否与源一致,缺了生成文件更新就是 CI 红灯。
提交 PR 前的自查清单
CONTRIBUTING.md 给出三条提交前检查,结合仓库各技术栈的实际测试入口,可以落地为如下可执行清单:
1. 构建并测试你碰过的包
文档原话是按目录选择命令:go test ./...、pnpm test 或 pytest。对照仓库实际配置:
- Go 模块(
engine/、proxy/、mcp/、shrink/等,模块名见 go.mod):go test ./...; - TypeScript 工作区:根 package.json 的 test 脚本为
node --test --test-force-exit tests/installer/*.test.mjs tests/hooks/*.test.mjs;子包如 packages/agent/package.json 的 test 脚本是tsc类型检查加node --test运行tests/*.runtime.mjs,packages/cli/package.json 则先跑一系列生成脚本再执行测试; - Python(
evals/、benchmarks/等):pytest。
原则是"测你碰过的包",不必为一次局部改动跑全仓。
2. 保持 byte-safe:宁可不压,不可压坏
这是压缩器贡献的核心纪律,原文要求:压缩器必须 round-trip 或优雅降级(degrade gracefully),绝不能静默损坏 payload;任何解析问题,把字节原样通过。
这条纪律在源码中是接口级契约而非口号。engine/compressors/compressor.go 中 Compress 方法注释写明:解析问题(malformed input、不支持的形态)时返回 (nil-or-input, false),"caller MUST forward the original unchanged"。包级注释进一步说明字节安全是由压缩器的 safety class(S0–S4 阶梯)推导出来的,而不是对每个压缩器单独假设。配套实现如 engine/compressors/invariants.go 展示了这种保守设计的极端形态:当被省略行无法提取字段、或枚举会退化为"看起来完整实则不全"的列表时,标记整体不出、摘要整体不生成——宁可少省一点 token,也不暗示一个未经核实的事实。
3. 贴合周边风格,PR 小而聚焦
"Match the surrounding style. Small, focused PRs review fastest."——与周边代码风格保持一致、保持 PR 小而聚焦。从各压缩器"一类型一文件 + 对应 *_test.go"的布局(如 engine/compressors/tabular.go 配 engine/compressors/tabular_test.go)可以推断出项目的风格基线:新压缩器同样应遵循单文件实现加同目录测试的结构。
有问题的渠道
CONTRIBUTING.md 给出的官方沟通渠道是:开一个 discussion,或发邮件至 hello@caveman.so。docs/CONTRIBUTING_PROFILES.md 对 profile 类贡献重复了同一渠道,说明这两个入口覆盖所有贡献类型。
小结
向 Caveman 贡献的路径可以压缩为四步:先按 LICENSING.md 的逐目录表判断目标目录属于 MIT 还是 BSL-1.1 区域,理解 BSL 区域附带的再许可授予(不舒适就转向 MIT 部分);每次提交用 git commit -s 完成 DCO 签名;动手前对齐目标目录的接口契约与测试入口,压测 byte-safe 底线;最后保持 PR 小而聚焦,生成文件与源同 PR 提交。对新贡献者而言,MIT 区域(CLI、SDK、contracts、provider catalog、profile)的门槛最低,而向 engine/ 添加一个遵循 fail-closed 契约的内容类型压缩器,则是文档点名推荐、且能直接扩大 Caveman 覆盖面的高价值方向。
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