- Go 1.25+
- Git
- Make
git clone git@github.com:unbound-force/replicator.git
cd replicator
make check # builds, vets, and runs all testsmake build # Build binary to bin/replicator
make test # Run all tests
make vet # Run go vet
make check # Vet + test (use this before submitting PRs)
make coverage # Run tests with race detection and print coverage
make check-coverage # Enforce per-package coverage ratchets locally- Standard library only: Use
testingpackage. No testify, gomega, or external assertion libraries. - Assertions: Use
t.Errorf/t.Fatalfdirectly. - Naming:
TestXxx_Description(e.g.,TestCreateCell_Defaults). - Database tests: Use
db.OpenMemory()for in-memory SQLite. - Filesystem tests: Use
t.TempDir()for temporary directories. - HTTP tests: Use
httptest.NewServerfor mock servers. - No shared state: Each test creates its own fixtures.
- Git tests: Guard with
if testing.Short() { t.Skip("requires git") }.
Always run tests with -count=1 to disable caching.
- Create a branch: Speckit features use
NNN-feature-name, OpenSpec changes useopsx/change-name. - Spec first: Non-trivial changes require a spec (either Speckit under
specs/or OpenSpec underopenspec/changes/). When in doubt, use a spec. - Conventional commits: Use
type: descriptionformat (feat, fix, docs, chore, refactor, test). - CI must pass: Run
make checklocally before pushing. - One concern per PR: Keep changes focused and minimal.
gofmtandgoimportsfor formatting- GoDoc comments on all exported functions and types
- Error wrapping:
fmt.Errorf("context: %w", err) - Use
errors.Isfor sentinel errors (not string comparison) - Import grouping: stdlib, then third-party, then internal
- JSON tags required on serialized struct fields
- No global mutable state
See AGENTS.md for the full project structure, constitution, behavioral constraints, and specification framework.
By contributing, you agree that your contributions will be licensed under the MIT License.