A warn-only runtime layer for Claude Code agents.
superpowers gives an agent process
(brainstorm → plan → TDD → review). harness-anchor gives it environment and
state discipline: where am I, what is the active feature, what counts as
"done", and what to do when stuck.
It never blocks a tool call. It keeps state on disk, injects it back at session start, and makes the agent show its evidence before it claims anything.
Every session opens with this — real output, from an anchored project:
<harness-anchor-state>
Plugin: harness-anchor v0.18.0
Project root: /home/you/invoice-service
Active feature: feat-3: PDF export pipeline
Project type: generic
Platform: linux
TOC freshness: fresh (8243585b3b97b927cd16672b6095d9270ccc3a3f)
Golden rules: 3 rule(s) — /gc scans changed code against them
Last session handoff (first 10 lines):
# Session Handoff
Last updated: 2026-07-30
Active feature: feat-3
Next action: wire the renderer into the CLI, then run scripts/lint.sh
</harness-anchor-state>
"Done." — with nothing run. Every criterion starts false. A feature cannot
reach status: pass while its evidence is null, and feature_list.schema.json
rejects that combination — the gate is a schema, not a good intention. Evidence
means a path you can open: a build log, test output, a lint report.
"That's not installed." — after checking one place. The same contract runs
in reverse. Asserting absence requires the scope searched and the date checked —
searched PATH + VS-bundled LLVM, not found (as of 2026-07-31). An empty
command -v proves nothing: VS-bundled LLVM needs vcvars, and Homebrew's is
keg-only.
State that lived in the chat, and a compaction ate it. Feature status, progress and handoff live in files, not scrollback. Four warn-only sentinels fire at the danger moments: context filling, compaction imminent, just-compacted, session stopping.
The change that quietly grew. One active feature at a time. Scope jumps are caught on the prompt side ("also, could you…") and on the action side — a new module written while a feature is still in progress.
- Never blocks. No hook returns
denyorblock. They inject context the agent can correct itself with — feedback loops, not gates. - Never auto-refactors.
/gcreports drift and stops there. - Never installs anything. bash + git. JSON parsing walks a python3 → python → py -3 → node → pure-bash chain, and degrades honestly when none of them exist.
- Never floods your context. SessionStart injects ≤3000 tokens — banner, project index, meta-skill; C/C++ and per-OS sections are dropped when they don't apply, and depth loads on demand.
claude /plugin marketplace add Redtropig/harness-anchor
claude /plugin install harness-anchor@harness-anchor-localStart a session; the banner above should appear in the agent's context.
(harness-anchor-local is the marketplace id, not a dev build.)
/anchor # scaffold the state files
/index-project # build PROJECT-TOC.md from git-tracked files
bash init.sh # health-check the environment
# ...work...
/session-end # write handoff, append progress.md, offer archival + commit| Command | What it does |
|---|---|
/anchor |
Scaffold the state files (never overwrites without explicit approval) |
/index-project |
(Re)build PROJECT-TOC.md from git-tracked sources |
/status |
Read-only snapshot: active feature, counts, git tree, TOC freshness, handoff head |
/verify |
Fresh-context subagent runs build + lint + tests, reports evidence paths (--fix = bounded ≤2-cycle auto-fix) |
/test-plan |
Fresh-context coverage-gap analysis: obligations from code + spec, plus paths outside the runner's scope |
/gc |
Fresh-context drift scan against golden-rules.md + slop heuristics. Report-only (not git gc) |
/session-end |
Write handoff, append progress.md, offer archival + commit |
/cpp-init |
C/C++: tune init.sh, drop .clang-format / .clang-tidy / lint.sh / sanitizer-build.sh |
/sanitize |
C/C++: build under ASan+UBSan, run tests, report with a log evidence path |
Full manual — arguments, prerequisites, outputs: docs/commands.md.
- State & navigation —
project-indexing,feature-state-keeper,init-verification - Evidence & verification —
anti-hallucination-gates,self-correction-loop,test-coverage-design - Governance & context —
capturing-golden-rules,context-budget-discipline,docs-lookup - C/C++ —
cpp-build-systems,cpp-static-analysis,cpp-formatting,cpp-sanitizers - Meta —
using-harness-anchor, injected at every session start
verification-runner (/verify), coverage-analyst (/test-plan) and
drift-analyst (/gc) are fresh-context evaluators — separating who writes the
code from who grades it is what keeps the grade honest. coverage-analyst is
the code-aware pass TDD deliberately cannot do: it derives test obligations from
the code as written, and flags paths the test runner never reaches.
cpp-build-doctor diagnoses build failures from compiler output.
Those four are read-only by frontmatter, not by convention — an evaluator that
can edit what it grades has an incentive to make the finding go away.
index-curator is the one that can write, and only to PROJECT-TOC.md.
| Event | What it does |
|---|---|
SessionStart |
Injects the state banner and a slimmed meta-skill (≤3000 tokens; C/C++ and per-OS sections dropped when they don't apply) |
PostToolUse |
Nudges on repeated identical calls, error streaks, context watermarks, scope creep and feature checkpoints; runs clang-tidy on C/C++ edits when compile_commands.json exists. One nudge per call, with a cooldown |
UserPromptSubmit |
Flags scope-jump phrasing, surfaces the active feature for confirmation |
PreCompact |
Records compaction forensics for the post-compaction notice |
Stop |
Nudges a progress.md update, a handoff refresh, and flushing chat-only memory |
Every hook fails silent on missing tools and carries a ≤5s watchdog — on timeout
it emits nothing and exits 0. scripts/validate-anchor.sh asserts the watchdog
is present in each hook the manifest registers, so a new one cannot ship without it.
Grounded in Anthropic's Effective Harnesses for Long-Running Agents and the learn-harness-engineering five-subsystem model: harness-anchor supplies State, Verification, Scope and Lifecycle; superpowers supplies process.
docs/design.md carries the full mapping and the reasoning behind each choice — warn-only hooks, the two-directional evidence contract, state budgets and archival, why heavy operations are commands rather than hooks — with the alternative that was rejected in each case.
The build system is auto-detected (CMake / Meson / Make / Bazel); nothing to
configure. /cpp-init drops .clang-format, .clang-tidy, scripts/lint.sh
and scripts/sanitizer-build.sh. PostToolUse runs clang-tidy on edited files
when compile_commands.json exists. /sanitize builds under ASan+UBSan and
runs the tests; cpp-build-doctor reads compiler output when a build breaks.
Sanitizer coverage is platform-bound, and the skill says so instead of assuming:
TSan and LSan do not exist on Windows — skills/cpp-sanitizers/platform/windows.md
carries the substitute table.
Linux, macOS and Windows; the self-tests run on all three in CI.
Windows runs on the Git-Bash baseline — Git for Windows, which Claude Code
already requires, supplies the bash and coreutils the hooks need, and
hooks/run-hook.cmd dispatches to it (WSL bash is deliberately excluded: hooks
must see Windows paths). LF checkout is pinned by .gitattributes, System32's
incompatible find / sort / timeout are shielded by a PATH prepend, and
C:\ paths are normalized at hook entry.
With no JSON engine at all, the banner, project typing and version stay real — plugin-controlled formats parse in pure bash — while ledger-derived checks skip and say so rather than reporting a false zero.
bash scripts/validate-anchor.sh # plugin self-consistency
bash scripts/validate-manifests.sh # manifest name/version sync
bash tests/windows-compat.sh # static Windows invariants (runs anywhere)
bash scripts/measure-context.sh # SessionStart injection vs the 12000-char capCI runs these on every push and PR across Linux, macOS and Windows — hook contracts, unit tests, compatibility gates, and a ShellCheck gate that fails on warning severity. Test scripts are discovered by glob, not from a hard-coded list. (The Windows leg deliberately runs a curated core subset.)
Stuck? docs/troubleshooting.md.
Works alongside superpowers (recommended,
not required) and any docs MCP — docs-lookup prefers first-party sources over
general search.
MIT — see LICENSE. Release history: CHANGELOG.md.