Back to Discover

harness-anchor

prompt

Redtropig

A warn-only runtime layer for Claude Code agents. Keeps feature state, scope and handoffs on disk so they survive compaction, and requires an evidence path before a done claim. Never blocks a tool call. Companion to superpowers; bash + git, no MCP.

View on GitHub
14 starsMITSynced Aug 2, 2026

Install to Claude Code

/plugin marketplace add Redtropig/harness-anchor

README

harness-anchor

validate license: MIT

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.

What the agent sees

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>

The failure modes it's built around

"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.

What it deliberately does not do

  • Never blocks. No hook returns deny or block. They inject context the agent can correct itself with — feedback loops, not gates.
  • Never auto-refactors. /gc reports 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.

Install

claude /plugin marketplace add Redtropig/harness-anchor
claude /plugin install harness-anchor@harness-anchor-local

Start a session; the banner above should appear in the agent's context. (harness-anchor-local is the marketplace id, not a dev build.)

Quick start

/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

Commands

CommandWhat it does
/anchorScaffold the state files (never overwrites without explicit approval)
/index-project(Re)build PROJECT-TOC.md from git-tracked sources
/statusRead-only snapshot: active feature, counts, git tree, TOC freshness, handoff head
/verifyFresh-context subagent runs build + lint + tests, reports evidence paths (--fix = bounded ≤2-cycle auto-fix)
/test-planFresh-context coverage-gap analysis: obligations from code + spec, plus paths outside the runner's scope
/gcFresh-context drift scan against golden-rules.md + slop heuristics. Report-only (not git gc)
/session-endWrite handoff, append progress.md, offer archival + commit
/cpp-initC/C++: tune init.sh, drop .clang-format / .clang-tidy / lint.sh / sanitizer-build.sh
/sanitizeC/C++: build under ASan+UBSan, run tests, report with a log evidence path

Full manual — arguments, prerequisites, outputs: docs/commands.md.

Skills (14, auto-triggered — you never invoke these)

  • State & navigationproject-indexing, feature-state-keeper, init-verification
  • Evidence & verificationanti-hallucination-gates, self-correction-loop, test-coverage-design
  • Governance & contextcapturing-golden-rules, context-budget-discipline, docs-lookup
  • C/C++cpp-build-systems, cpp-static-analysis, cpp-formatting, cpp-sanitizers
  • Metausing-harness-anchor, injected at every session start

Subagents (5)

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.

Hooks (5, all warn-only)

EventWhat it does
SessionStartInjects the state banner and a slimmed meta-skill (≤3000 tokens; C/C++ and per-OS sections dropped when they don't apply)
PostToolUseNudges 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
UserPromptSubmitFlags scope-jump phrasing, surfaces the active feature for confirmation
PreCompactRecords compaction forensics for the post-compaction notice
StopNudges 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.

Design notes

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.

C/C++ projects

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.

Platforms

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.

Verifying the plugin

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 cap

CI 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.

Rendered live from Redtropig/harness-anchor's GitHub README — not stored, always reflects the source repo.

1 Plugin

NameDescriptionCategorySource
harness-anchorWarn-only, zero-dependency runtime harness layer for Claude Code (companion to superpowers): persistent state, scope control (prompt + action side), Default-FAIL verification & coverage gates, entropy governance (golden-rules + drift detection), and first-class C/C++ engineering (CMake/Meson/Make/Bazel + clang-tidy + sanitizers)../

0 Comments

Login required
Log in to post a comment or update on this repo.

No comments yet — be the first to share an update.