Contributing
Contributions are welcome, and the rules are short. The MIT parts are plain inbound-equals-outbound. The BSL engine asks one extra thing — a sign-off and a relicense grant — so a community fix can ship in the same commercial and OEM licenses everything else does. Community pull requests land in the public JuliusBrussee/caveman repo.
The legal model exists to keep the open core sustainable, not to slow you down. Most contributions need nothing more than a Signed-off-by line.
The license model
The stack is split, and so is the contribution model:
- MIT areas — the CLI, the SDKs, the kit, the evals, the extension, the wire contracts, and the provider catalog — use inbound = outbound MIT. Your contribution is MIT; that's the whole agreement.
- BSL areas — the engine, proxy, MCP, shrink, the cavemem Go core, and
shared/platform— require two things: a DCO sign-off and a relicense grant to the Licensor (Julius Brussee), so commercial and OEM licenses can include community contributions. The BSL engine is dual-licensed for OEM; the grant is what makes that possible.
There is no full CLA. The relicense grant is the lightweight alternative.
The DCO
The DCO is the Developer Certificate of Origin. You assert you wrote the change (or have the right to submit it) by adding one trailer to each commit:
Signed-off-by: Your Name <you@example.com>git commit -s adds it for you.
The relicense grant applies to BSL code only
Touching the engine or another BSL package means your sign-off also grants the Licensor the right to relicense that contribution commercially. MIT contributions carry no such grant — they are simply MIT in, MIT out. The public repo's CONTRIBUTING.md is the authoritative statement of both requirements; this page is the orientation.
First useful contribution
If you want a small change that matters, write a new content-type compressor for the engine. The engine detects a payload's type and routes it to a safety-classed compressor; a new compressor teaches it to shrink a kind of content it does not yet handle well.
Build and test
The stack is three toolchains. Each has a one-liner:
go test ./... # the Go services, engine, proxy, and shared platform
pnpm -r test # the TypeScript packages (CLI, SDKs, evals, kit, web)
pytest # the Python optimizer and the Python SDKRun the slice your change touches; the CI runs all three.
The boundary rule
There is one hard architectural rule, and it is enforced:
Public packages stay standalone
Public packages must not import private service code. The local stack runs standalone, on your machine, on your keys. A check enforces it:
make check-boundariesA PR that crosses the boundary fails the check. Keep the open core importing only itself.
What new code is expected to do
Two honesty invariants bind new code everywhere in the open stack, the same way they bind the existing code:
- Byte-safe. A transform never alters model-visible bytes on a problem. Compressors and the proxy pass the original bytes through unchanged on a parse failure, in record mode, or whenever the result is not smaller. The safe path is always "forward what we were given."
- Fail closed. Unknown enum cases resolve to the conservative answer, not the optimistic one — an unknown mode becomes
record, an unknown grader returnspassed: false, an unknown wire protocol fails the compile. When in doubt, prefer the honest negative.
Everything public local tools report is inferred: a local estimate, never verified and never re-projected into a monthly figure.
Your first PR
Fork and branch
Fork JuliusBrussee/caveman, branch off, and make your change. Keep it scoped — one concern per PR.
Test the slice you touched
Run go test ./..., pnpm -r test, or pytest for the affected toolchain, plus make check-boundaries if you touched anything under public/.
Sign off
Commit with git commit -s so each commit carries a Signed-off-by line. For BSL code, that sign-off is also your relicense grant.
Open the PR
Push and open the pull request against the public repo. Describe the change and how you tested it. Community PRs reconcile through that repo.