# Contributing ## Where to start Issues labelled [good first issue](https://github.com/vshulcz/deja-vu/labels/good%20first%20issue) are bounded, and each one names the case it is wrong on, so you can reproduce before you change anything. ## Build and test deja requires Go 1.25 and has no runtime Go dependencies. Before opening a pull request, run: ```sh go test ./... -race -count=1 go vet ./... golangci-lint run go build ./cmd/deja ``` Run `gofmt -s` on changed Go files. Every package touched by a change must keep at least 90% statement coverage for new packages, and never less than the floor CI enforces for the package you touched (`.github/workflows/ci.yml`, "Per-package coverage floor"). Those floors are where each package stands today, not where it should be: raise one when you improve it, and treat lowering one to make a build pass as the thing the gate exists to stop. Measure each package directly so aggregate coverage does not hide a regression: ```sh go test ./internal/sources/ -coverprofile=coverage.out go tool cover -func=coverage.out ``` Replace `internal/sources` with each package changed. CI prints each package's figure beside its floor only after the whole suite has run, so the two commands above are the quicker check — run them before opening the PR and there will be no surprises. Do not add low-value tests only to move the number; explain a genuinely unreachable branch in the pull request instead. ## Hermetic tests Tests must not read or modify a contributor's real agent configuration or history. - Use `t.TempDir()` for files and directories. - Set both `HOME` and `USERPROFILE` with `t.Setenv`. - Also set every location variable the code path reads: relevant `DEJA_*` variables and, when applicable, `CODEX_HOME`, `GEMINI_CLI_HOME`, `CURSOR_CONFIG_DIR`, `CLAUDE_CONFIG_DIR`, or `AIDER_CHAT_HISTORY_FILE`. - Keep paths valid on Windows. Guard Unix-only behavior with `runtime.GOOS` and skip it on unsupported platforms. - Check cleanup errors where practical. In particular, do not leave a bare error-returning call in a `defer`. Use table-driven tests from the standard library. The project does not use testify or other test frameworks. ## Benchmarking When measuring ranking or latency changes (`deja bench` or `internal/bench`): 1. Build the control binary from a clean checkout with `go build -trimpath ./cmd/deja` and score both binaries against the same frozen store in one sitting (or set `DEJA_NOW` so recency decay does not drift between runs). 2. Separate cold-cache and warm-cache timings; discard the warmup pass when reporting steady-state latency. 3. Do not pipe `go test` or a benchmark command into `tail` or another filter without `set -o pipefail`, so a failing run cannot exit 0. 4. Verify that a new regression test or benchmark assertion actually fails with the change reverted before trusting a green run. 5. Check behaviour on real multi-session transcripts as well as synthetic fixtures; uniform synthetic lengths hide pooling and tie-breaking regressions. ## Adding or updating a harness parser The [source parser registry](docs/ARCHITECTURE.md#source-parsers) maps harnesses to their implementation under `internal/sources`. Follow the integration steps in [Add a new harness](docs/ARCHITECTURE.md#add-a-new-harness); a parser alone is not enough. The registry entry is what wires discovery and incremental indexing, and install support and user documentation are separate paths. Fixtures must be synthetic and minimal. Put reusable cross-package samples under `fixtures/synthetic`; keep parser-specific cases near their tests. Use stable IDs and timestamps, retain only fields needed to exercise the format, and replace credentials and identifying paths. SQLite fixtures should be built from a checked-in script such as `fixtures/synthetic/make_opencode_db.sh`, not copied from a local agent database. A parser change should cover discovery, normal parsing, malformed or truncated input, and incremental behavior where the format is append-only. Add an index integration test and install/doctor coverage when those commands recognize the harness. If an upstream format changed, use the [format drift report](https://github.com/vshulcz/deja-vu/issues/new?template=format-drift.yml). For a new harness, use the [parser request](https://github.com/vshulcz/deja-vu/issues/new?template=parser-request.yml) before contributing real session data. ## Pull requests and review - Keep changes small and explain the user-visible behavior. - Add or update tests and documentation with the implementation. - Do not commit private history, generated local indexes, or machine-specific logs. - No CLA. The Windows suite runs on `main`, on the weekly canary, and on pull requests that touch filesystem, parser or installer paths (or carry the `windows` label). Note that a directory mode bit (`chmod 0500`) denies nothing on Windows or to root; a test that needs an unwritable path should place a regular file where the parent directory would be, which fails consistently on every platform. A pull request is ready to merge when CI is green, affected packages meet the coverage bar, tests are hermetic on supported platforms, documentation matches the behavior, and review comments are resolved. Maintainers may ask for a smaller change when unrelated refactoring makes behavior difficult to review.