Skip to content
Pl. 10Documentation

Five commands, one config file.

Guignet needs Bun ≥ 1.3 and git. No npm, node or pnpm. Every command accepts --json and prints exactly one JSON object on stdout.

Platforms

macOS and Linux are fully supported.

macOS · Linux

Supported

The complete treatment: taskpolicy / nice priority demotion, PSI or kern.memorystatus memory pressure, load-average admission.

Windows via WSL2

Recommended

The recommended route on Windows. Gets the full POSIX treatment, identical to native Linux.

Native Windows

Experimental

Shell, tree-kill, priority demotion and the memory gate all have native paths, but the CPU load gate is unavailable by construction — os.loadavg() is zero on Windows. guignet doctor says so before you start.

Quickstart

Config, then pipeline.

Create .guignet/config.json in the target repository. Each stage is idempotent and resumable, so you can stop and re-enter the pipeline anywhere.

.guignet/config.json
{
  "testCmd": "bun test",
  "setupCmd": "bun install",
  "repoVisibility": "public"
}
zsh — the pipeline
$ guignet doctor # validate the repo + suite discovery handshake$ guignet mine # reconstruct tasks from git history$ guignet gate # replay validity → the admitted suite$ guignet run --config run.json # execute attempts$ guignet score # verdicts + metrics + contamination$ guignet report # → .guignet/reports/<ts>/guignet-report.html

Exit codes

0
ok
1
failure
2
usage
3
soft-blocked

Run config

A run names the model and the budget.

run.json
{
  "runId": "2026-08-01-sonnet",
  "adapter": "claude-code",
  "model": "sonnet",
  "nAttempts": 3,
  "maxTotalDollars": 10
}

maxTotalDollars

A hard, run-wide spend cap.

Once the summed cost of completed attempts reaches the cap, no further attempt starts. In-flight attempts finish, so the overshoot is bounded by one pool width.

Capped attempts write nothing — resume with a raised cap to run exactly the remainder. It is resume-aware: attempts already on disk count against it, except under --force, where every attempt is being replaced and the cap budgets the fresh re-run alone.

Config reference

Every key in .guignet/config.json

KeyMeaning
testCmdhow the repository runs its tests (verifier commands scope to it)
setupCmdone-time environment setup, e.g. bun install
subdirpackage root inside a monorepo
repoVisibilitypublic / private / mixed / unknown — frames the cutoff split (contamination vs knowledge freshness)
cutoffsper-model training-cutoff overrides (ISO dates)
preservePathsextra worktree paths preserved across replay resets, beside the always-kept node_modules (e.g. .venv, a vendored dir a test needs)
gateReplaysvalidity replay count k (default 2)
testCwdwhere setup/verifier/agent run: subdir (default) or repo — use repo for workspace test runners (vitest projects, pnpm/nx) that must execute at the repository root
host.priorityscheduling priority for all spawned work: low (default — yields to your foreground) / normal
host.maxLoadPerCorerun-pool admission threshold: add concurrency only while load1 ≤ this × cores (default 1.5)
spinesuite event emission: auto (default, only if .suite/ exists) / on / off

Development

The harness checks its own firewall.

bun run check runs the typecheck, the import-boundary firewall that keeps ground truth out of the mining path, and the test suite. The boundary check is CI-enforced — a leak fails the build, not a review.

zsh — guignet
$ bun install$ bun run check # typecheck + import-boundary firewall + tests

Licensed MIT. The harness has to be inspectable, or nobody runs it on private code.