Prerequisites
- Go, at the version
go.moddeclares. That is the only hard requirement. CI resolves it fromgo.modrather than pinning a number. - No cgo. pikopod builds static binaries with
CGO_ENABLED=0, including its SQLite layer, which is the pure-Go driver. A change that needs cgo needs a discussion first. - Python 3, only if you regenerate synthetic test fixtures.
go build, so if you change anything platform-sensitive, run the suite on your own machine and say so in the pull request.
Set up
Build and test loop
-race. Keep it that way.
The e2e suite lives in
e2e/ and runs as part of go test ./.... CI additionally runs the fixture licensing guard, go vet, the parity suites, and a zero-cgo build matrix across linux, darwin and windows on amd64 and arm64.
Where local state goes
Running from the repo writes./pikopod.yaml (from init) and ./pikopod-data/. Both are gitignored. To keep an experiment out of the way:
Project structure
cmd/pikopod is thin cobra wiring. Everything else lives in internal/.
Parity goldens
testdata/parity/ holds committed golden files. They are maintainer-regenerated. Do not hand-edit them. If your change legitimately moves a golden: leave it as it is, expect the parity job to be red, and say in the pull request which golden moved and why. A maintainer regenerates on your branch from the code.
Test fixtures and licensing
Fixtures undertestdata/parity/importer/specs/ are license-checked in CI. Every file needs an entry in that directory’s SOURCES.md. No provider content lands without an explicit grant. When a test needs a real-world shape you cannot license, generate a synthetic fixture:
House rules
- Nothing internal may alter the data plane. The agent serves before it observes, never retries, and isolates every capture stage.
- Redaction happens before the disk. The canary test in
internal/agentseeds sentinels into every position and sweeps every persisted byte. It must pass. - A field on the IR that nothing reads is deleted, not parked. The reader audit fails the build otherwise.
- Refuse rather than guess. If a check cannot be proven, report that it could not be proven.
- Errors are a contract. Use
errfmt.New(what, why, fix, docs), and make sure the doc anchor exists. - Exit codes are API.
0clean,1the check ran and failed,2tool or configuration error. - Every model call is opt-in and confined to three places. Adding a fourth means adding a row to the security page in the same pull request.
Release
Releases are cut by tag and built by GoReleaser: static binaries for macOS, Linux and Windows on amd64 and arm64, an SBOM per archive,SHA256SUMS signed with cosign, SLSA provenance, deb and rpm packages, a container image on GHCR, and a Homebrew formula.