| name | harness |
| description | Bootstrap or align a repo with the harness-templates contract: the 5-script quality harness (check, pre-commit, ci, audit, post-edit) plus the behavior contract (task sizing, human-owned commits, Gherkin-first, arch-config integration guard). Use when starting a new python/bun/go/rust/monorepo project, adding a quality harness to an existing repo, or asked to match ~/Code/harness-templates conventions. Triggers: "add a harness", "set up check/ci/pre-commit", "align with harness-templates", "bootstrap quality gates", "add the behavior contract", "wire the engineering principles".
|
Harness Template
Give a repo the same contract as ~/Code/harness-templates. The contract
has two layers:
- Layer 1 — quality harness (always): the 5 scripts
check,
pre-commit, ci, audit, post-edit.
- Layer 2 — behavior contract (greenfield: automatic; existing repo:
opt-in):
AGENTS.md/CLAUDE.md instructions plus arch-config-guard,
which warns during check/stop-hook and blocks pre-commit/pre-push/ci
unless HARNESS_ALLOW_ARCH_CONFIG=1 is set after review. See
behavior-contract.md.
Source of truth
Always read first. Do not restate the contract from memory.
~/Code/harness-templates/README.md — Layer-1 contract + getting started
~/Code/harness-templates/<lang>/AGENTS.md and …/CLAUDE.md — same
per-language commands + behavior contract, byte-identical. Claude Code
reads CLAUDE.md; Codex (and other AGENTS.md-consuming tools) read
AGENTS.md. Both files carry the full content; the harness
agents-md-drift check enforces no drift, and sync-agents-md writes
AGENTS.md ← CLAUDE.md after edits. Copy verbatim; do not paraphrase.
~/Code/harness-templates/<lang>/.claude/settings.json — Claude hooks
~/Code/harness-templates/<lang>/.codex/hooks.json — Codex Stop hook
~/Code/harness-templates/<lang>/.codex/hooks/codex-stop-hook.sh —
Codex stdout-to-JSON wrapper for Stop hooks
~/Code/harness-templates/python/harness.py run() — canonical quiet output
Never edit anything under ~/Code/harness-templates/.
Decide first
- Empty dir → copy a template verbatim (see per-language reference).
Layer 2 comes through
AGENTS.md/CLAUDE.md and the runner's
arch-config-guard — keep it.
- Existing repo with a runner (just/make/npm scripts/cargo) → adapt
Layer 1; reuse the existing runner. Do not add a second one.
Layer 2 is opt-in — ask before wiring it because it adds explicit
agent instructions and arch-config integration failures.
- Polyglot / multi-project → use
monorepo/ Makefile dispatch.
When auditing or repairing a repo that already has some harness pieces,
read adoption-checklist.md
before language-specific references. Use it to find missing commands,
incorrect command substages, noisy success output, and incomplete hook/docs
wiring, then apply the smallest compatible fix.
Language detection
Claude/Codex hook + Stop-hook shape: settings-json.md.
The Stop hook runs stop-hook; stop-hook runs post-edit, then the
read-only complexity gate (plus the dead-code gate where the language ships
one) in parallel.
Behavior contract: behavior-contract.md.
Layer 1 — the 5-script contract
| Script | When | What | Fixes? |
|---|
check | After edits | fix + format + typecheck + test + suppression ratchet | yes |
pre-commit | Git pre-commit hook | same, staged files only | yes |
pre-push | Before push | read-only push gate: lint + format check + acceptance + arch over the whole tree, in parallel | no |
ci | CI pipeline | read-only gates (lint + typecheck + dep audit + complexity + acceptance + arch) run in parallel, captured and printed in submission order; then tests/coverage + crap (advisory) | no |
audit | CI pipeline | dependency vulnerability audit | no |
post-edit | Stop hook helper | format if source files changed | yes |
stop-hook | Agent Stop hook | post-edit + complexity + deadcode (python/bun) | yes |
Quality subcommands also callable standalone: complexity, crap,
acceptance, coverage (Go also keeps test-cov), mutation, arch,
arch-config-guard, suppressions, and deadcode (python/bun).
arch-config-guard warns in check/stop-hook and fails
pre-commit/pre-push/ci when protected arch config paths changed unless
HARNESS_ALLOW_ARCH_CONFIG=1 is set. deadcode flags unused code and runs in ci +
stop-hook: python via vulture (app sources only, --min-confidence 60,
allowlist false positives in vulture_allowlist.py), bun via knip (unused
files/exports/deps, configured by knip.json, fetched on demand via
bunx). Go and rust have no deadcode target — their linters already
flag dead code (golangci-lint unused, clippy dead_code under
-D warnings). Python test runs unittest, or py_compile over quality
targets when no tests/test*.py files exist. Bun test, coverage, mutation, and
crap warn and skip when no Bun test files exist. complexity runs
uvx lizard@1.22.2 (CCN≤15, args≤8, length≤100) — all 4 templates, so
uvx must be on PATH. crap is advisory by default (warns; pass
--enforce to hard-fail) and runs in ci.
Suppression counts (# noqa, // @ts-ignore, //nolint, #[allow]) are
ratcheted by .harness-baseline. Growth fails check/ci; the only writer is
suppressions --update-baseline, which requires human sign-off. coverage.min
in the same file is the default coverage floor unless --min=N is passed.
Property-based tests run inside the normal test step — no extra script.
Each template carries the language's PBT dev-dep (hypothesis / fast-check /
rapid / proptest) and seeds a property suite over its own CRAP and parser
helpers as the worked example. The behavior contract's law-like rule
points agents at that suite.
Layer 2 — the behavior contract
Greenfield copies inherit it through AGENTS.md/CLAUDE.md and the runner.
For an existing repo, wire it only when the user opts in. Full porting + onboarding steps:
behavior-contract.md. In short:
AGENTS.md and CLAUDE.md both carry the ## Behavior contract
section. The two files hold the same content (the templates'
agents-md-drift check enforces no drift).
arch-config-guard protects the repo's architecture config at integration
time: warning mode in check/stop-hook, strict mode in
pre-commit/pre-push/ci, reviewed override via
HARNESS_ALLOW_ARCH_CONFIG=1.
After wiring Layer 2, onboard the user — state plainly that commit/push
ownership is instruction-only, while arch-config changes are blocked by the
runner gates until reviewed.
Adapt rules (existing repos)
- Merge into existing
AGENTS.md / CLAUDE.md, configs, and lockfiles.
Never overwrite. Never reduce an existing contract file to a stub —
AGENTS.md-consuming tools read it literally, so a stub delivers no
contract.
- Both
AGENTS.md and CLAUDE.md should hold the same full content:
- Both files exist → merge the contract into both; wire the drift check.
- Only
AGENTS.md exists → add CLAUDE.md with identical content.
- Only
CLAUDE.md exists → add AGENTS.md with identical content.
- Neither exists → create both.
- Keep the repo's task runner; reuse its invocation prefix in the
command list.
- Template runner files (
harness.py, harness.ts, harness.go,
cargo harness) are for greenfield/copy flow — not the default for
repos that already have a runner.
- Layer 2 is opt-in: never wire behavior-contract instructions or the
arch-config integration guard into a repo that did not ask for them.
- The contract's law-like rule (property tests) needs the language's PBT
dev-dep: hypothesis (python), fast-check (bun), rapid (go), proptest
(rust). Wire it when porting the contract — or on the first law-like
change — and model the suite on the template's seeded example.
Runner output contract
Quiet by default. Mirror ~/Code/harness-templates/python/harness.py run():
- One short line per step on success.
- Capture stdout/stderr; print only on failure.
- On failure: print failing command + full captured output, then exit.
--verbose escape hatch streams raw command output.
- Zero external deps — stdlib/runtime only.
Verify (end-to-end)
Layer 1:
check passes from a fresh tree.
ci does not mutate tracked files (git status clean after).
- Pre-commit hook fires on a staged change (
.git/hooks/pre-commit exists).
audit passes.
stop-hook runs via Stop hook and includes post-edit formatting (Claude/Codex hooks wired per
settings-json.md).
- Suppression growth above
.harness-baseline fails; suppressions --update-baseline updates it.
arch-config-guard warns in check/stop-hook and fails
pre-commit/pre-push/ci unless HARNESS_ALLOW_ARCH_CONFIG=1 is set.
- Runner imports nothing outside stdlib/runtime.
Layer 2 (only if wired):
AGENTS.md and CLAUDE.md include the same full behavior contract text.
- Commit/push ownership and Gherkin-first rules are present as instructions.