v0.16.0 — post-evaluation hardening: tool discovery + doc-drift detection
The first release driven by an end-to-end evaluation of the plugin itself. A C++ test project was built to be hard on an agent, an agent-under-test worked it with harness-anchor active, and the run was graded against a two-dimensional rubric (task outcome 40% / plugin-attributable behaviour 60%). It scored 91.2/100 with zero anti-hallucination violations — and the places it lost points are what this release fixes.
PATH is not proof of absence
The sharpest finding. The agent ran where clang-tidy, got nothing back, wrote "no clang-tidy/clang-format on this machine" into the project's AGENTS.md, and silently skipped three capabilities for the rest of the session.
The tools were installed. They ship bundled inside Visual Studio and simply aren't on PATH until vcvars runs. The same session had already hit this exact shape with cl.exe and correctly fallen back to vswhere — it owned the technique and didn't reapply it. All three zeros in the 39-row capability matrix trace back to that single moment.
New scripts/cpp-tool-discovery.sh resolves a tool through PATH and the platform's known install locations — VS-bundled LLVM and Ninja on Windows, keg-only Homebrew llvm on macOS, versioned /usr/lib/llvm-* on Linux. cpp-static-analysis, cpp-formatting and /cpp-init now route availability judgements through it, and are required to phrase absence as "searched PATH + <locations>, not found" rather than "not installed on this machine". The first is a falsifiable claim about a search; the second is an unfalsifiable claim about the world, and it tends to get written somewhere every later session reads.
The script is never silent: a missing tool still produces a line, and that line enumerates its own search scope.
Documentation that should have changed and didn't
/gc reported clean while a README line — "Cancellation is safe to call at any time" — had been made false by the very change under review, which taught cancel() to reject terminal-state jobs.
Two independent structural causes, where fixing either alone still misses it: the scan was bounded to changed files and the README was unchanged; and the doc-drift heuristic only matched docs referencing renamed or removed symbols, while cancel still existed with a changed contract.
New scripts/doc-drift-scan.sh reverse-associates the symbols a change touched to *.md lines mentioning them. It attributes body-only changes to the enclosing symbol via git diff -U0 hunk headers — necessary here, because cancel()'s signature never moved. drift-analyst now covers stale claims alongside dangling references, and states its own blind spot in its header so a clean section is not misread as "the docs were verified".
Also in this release
cpp-build-systemsescalates tocpp-build-doctorafter a second failed attempt at the same build failure, not only on "anything cryptic". Fixing a link error on the first try and moving on stays the expected path./anchorcloses by recommending/cpp-initwhen the project is C/C++ and its config is missing. Being correctly described in a command list turned out not to mean being remembered at the right moment./cpp-initrecords resolved tools portably: a tool already onPATHkeeps its bare name, sincescripts/lint.shandAGENTS.mdare git-tracked and a machine-local path there breaks the next machine and CI.- Fixed:
tests/skill-triggering/run-test.shwas missing--verbose, which newerclaudeCLI versions reject at argument-parse time — every triggering case had been failing identically regardless of content. - Fixed:
doc-drift-scanreported a silent clean onmainand on uncommitted work — the two most common/gccontexts.
Known limitations
Stated plainly, because a release about honest reporting should be honest about itself:
doc-drift-scan's pathspec is C/C++-only. It therefore cannot fire on the harness-anchor repository at all, which is bash and markdown. Its only execution witness is its own unit test on a synthetic fixture.- Four paths in that script still exit 0 with no output on either stream. The instances found were fixed; the class was not.
- It has no watchdog. Measured 184 seconds on 160 symbols × 60 markdown files.
- The LLVM version-suffix ladder is hard-coded through 22. On a box where only
clang-tidy-23exists offPATH, it would reportNOT_FOUND— and the skill text upgrades that into a licence to call the tool unavailable. - The mandated phrasing is enforced by instruction, not mechanically. Nothing greps agent output.
All five are logged for 0.17.0.
Verification
validate-anchor 157/0 · cpp-tool-discovery 12/0 · doc-drift-scan 10/0 · windows-compat 19/0 · posix-compat 4/0 · check-coverage 27/0 · validate-manifests 3/0 · shellcheck --severity=warning clean — all re-run on main at the tagged commit.
Live behavioural proof. The new adversarial prompt was run against a real model with --plugin-dir pointed at this version, and the transcript shows the agent reasoning "where clang-tidy returning nothing doesn't actually prove the tool is absent, especially on Windows" — then invoking the discovery script and finding it. That is the evaluation's failure, reversed.
Full changelog: v0.15.0...v0.16.0