Contributing
Thanks for helping out. ccvm is a small, security-focused project, so a few house rules keep it that way.
Read this first
This site’s Security and Developing sections are the authoritative engineering docs: the security invariants that must not regress, the rationale behind the settled design decisions (and which ones not to relitigate), and the gotchas that cost time to rediscover. Read the relevant pages before changing the guest, the wrapper, or the boot path.
CLAUDE.md in the repo root is the terse operational version — the must-not-regress checklist plus a
routing directive into this site. The README is
deliberately newcomer-facing — keep deep/technical detail here, not in the README.
Definition of done
A behaviour change is done when:
nix flake checkis green. It builds the guest image, shellchecks the wrapper, builds the docs (failing on dead internal links), and runs the host-side guarantee tests (secret hygiene, config staging, verbatim argv, mode selection). CI runs this on every PR.bash tests/boot.shpasses on a Nix+KVM box — if you touched the guest, wrapper, or boot path. It boots a stub-claudeVM and asserts the things that need a real guest (argv reaches claude, rw vs. overlay file visibility, egress, the encrypted disk). This is not in CI yet (it needs a KVM runner), so paste theN passed, M failedline in your PR. Defaults to TCG software emulation, so it runs anywhere — just slowly.- A human
ccvm --shellpass (resize,vim,less, vi-mode) — if it touches the terminal path. Terminal fidelity is verified by hand, not automated.
See Build / test / debug for the full loop, including the fast stub-claude
iteration pattern.
Security invariants
Treat any change that weakens a Security invariant as a bug: no secret to disk/argv/seed, the host key stays pinned, only the CWD is shared. The host-side tests grep the seed for the API key and the OAuth credential — keep them passing.
Conventions
- Commit trailer (exact):
Co-authored-by: Claude <noreply@anthropic.com>for AI-assisted commits (lowercaseauthored-by, bareClaude). - Format before committing:
nix fmt(treefmt —nixfmtfor Nix,shfmtfor the shell scripts). CI enforces it viachecks.formatting. See Conventions for the full set.
macOS host support — help wanted
macOS host support is on the roadmap and is community-driven: the maintainer has no Apple
hardware. Help from nix-darwin folks — or anyone willing to do the porting work — would be very
welcome. The hard parts are the host-side bits that assume Linux: KVM/TCG acceleration selection, the
clipboard bridge’s host reader (wl-paste / xclip → pbpaste), and QEMU’s accel/networking flags.
The guest itself is a NixOS system and is unaffected. If you’re interested, open an issue to
coordinate.
License
By contributing you agree your contributions are licensed under the MIT License (see the repo’s
LICENSE).