Markdown 114 lines
<div align="center">
<picture>
<source media="(prefers-color-scheme: dark)" srcset="assets/eeco_logo_dark.png">
<img src="assets/eeco_logo_light.png" alt="eeco" width="280">
</picture>
<h1>Contributing</h1>
<p><i>How to build, which checks must pass, and the rules a change holds to.</i></p>
<p>
<a href="README.md"><b>README</b></a> ·
<a href="VISION.md"><b>Vision</b></a> ·
<a href="docs/COCKPIT.md"><b>Cockpit</b></a> ·
<a href="docs/USAGE.md"><b>Usage</b></a> ·
<a href="docs/ARCHITECTURE.md"><b>Architecture</b></a> ·
<a href="docs/PUBLIC_API.md"><b>Public API</b></a> ·
<a href="EXTENDING.md"><b>Extending</b></a> ·
<b>Contributing</b> ·
<a href="docs/UPGRADING.md"><b>Upgrading</b></a> ·
<a href="VERSIONING.md"><b>Versioning</b></a> ·
<a href="CHANGELOG.md"><b>Changelog</b></a> ·
<a href="SECURITY.md"><b>Security</b></a>
</p>
</div>
---
## Contributing to eeco
eeco is a solo project with a deliberately small contribution surface. This is a
lightweight contract — how to build, which checks must pass, and the rules a
change holds to — not community-health boilerplate. For how to *add* something —
a workflow, a config key, a verb — see [EXTENDING.md](EXTENDING.md).
## Build and checks
eeco builds with the Go toolchain through a `Makefile`:
| Command | What it does |
| -------------------- | ---------------------------------------------------------------------------- |
| `make build` | Build the single `eeco` binary. |
| `make verify` | `go build ./...` + `go vet ./...` + `go test ./...`. |
| `make gates` | Run the `comment-hygiene`, `leak-guard`, and `version-sync` workflows. |
| `make lint` | `golangci-lint` — must report **0 issues**. |
| `make cover-check` | Fail if total statement coverage drops below the ratchet floor. |
| `make bench` | Scanner benchmarks; keep them under the five-second budget. |
| `make sync-guide` | Mirror `docs/USAGE.md` into the in-binary guide after editing it. |
## Definition of Done
A change is done when **all** of these hold:
- **`make verify` green** — build, vet, and tests pass.
- **`make gates` green** — `comment-hygiene`, `leak-guard`, `version-sync`.
- **`make lint` green** — `golangci-lint`, 0 issues.
- **`make cover-check` green** — total statement coverage does not regress.
- **Additive over the public surface** — no change to an item frozen in
[`docs/PUBLIC_API.md`](docs/PUBLIC_API.md) unless a semver bump is explicitly
declared; when one is, the README version badge is bumped **before** the tag.
- **No AI attribution** — no AI-tool fingerprint or `Co-Authored-By` trailer in
any commit, tag, file, or PR body.
- **CHANGELOG entry when user-facing** — a binary- or user-facing change gets a
[CHANGELOG.md](CHANGELOG.md) entry; infra-only changes (CI, scripts) do not.
## Public surface and versioning
From v0.1.0, eeco follows Semantic Versioning over the surface frozen in
[`docs/PUBLIC_API.md`](docs/PUBLIC_API.md): the CLI verbs and flags, the
`eeco go --json` keys, exit codes, config keys, memory frontmatter fields, the
queue / ledger / hook formats, and the builtin workflow names. Nothing outside
that list is covered. Adding to the surface is a MINOR bump; post-1.0, changing
or removing a frozen item is a MAJOR bump with the deprecation window described
in [`VERSIONING.md`](VERSIONING.md). While eeco is pre-1.0 (`v0.x`) a MINOR MAY
change or remove a frozen item with a CHANGELOG migration note — see
[`VERSIONING.md`](VERSIONING.md) §2.1. Keep changes additive by default.
## Trust boundaries
Three invariants are sacred and are pinned by the boundary suite
(`*_boundary_test.go`):
- **The engine never writes the tracked tree.** Only the command-layer
`initgit.go` / `historygit.go` write git, and only to the workspace's own
private history — never the host repository.
- **Hooks stay reversible.** Every hook records its install in a ledger and
removes byte-identically; disabling a hook restores the prior state exactly.
- **AI stays gated.** No AI call happens without consent and budget, and when
memory or input is malformed the AI path degrades instead of failing the
command.
A change that touches these areas keeps the boundary suite green. Treat a
boundary-test failure as a design error, not a test to update.
## Working habit
Big or design-forked changes get a short planning pass before code; small,
mechanical changes can be planned and built in one go. Either way: edit on a
branch, get the Definition of Done green, keep the change additive (or declare
the bump), add a one-line CHANGELOG entry when it is user-facing, and open a PR.
## Pull requests
Clone, branch, and make your change. Run `make verify`, `make gates`,
`make lint`, and `make cover-check` until they are green; intent-add any new
files (`git add -N <path>`) before `leak-guard` so it scans them. Open the PR
with the [template](.github/PULL_REQUEST_TEMPLATE.md) and link any
[issue](.github/ISSUE_TEMPLATE).
---
[← Prev: Extending](EXTENDING.md) · [Next: Upgrading →](docs/UPGRADING.md)