Files
holocron/plugins/kyberforge/.apm/skills/agent-audit/README.md
Claude Code AI - Gitea MCP 598a7c326a refactor(skills): retrofit the corpus to the ADR-0020 context contract (#129)
Retrofits all 39 skills to ADR-0020's description/body context contract, then fixes what six rounds of independent review found in that retrofit — including four ways the hot gate itself failed open.

Closes #99, #107, #108, #110, #111, #114, #115, #120.

## The retrofit (waves 1-5)

| | Start | Now |
|---|---|---|
| Description FAILs (>400 chars) | 26 | **0** |
| Body FAILs (>900 words, body-only) | 9 | **0** |
| Dangling routing targets | 2 | **0** |
| `Kyberforge.CompositionNote` | 10 | **0** |
| Preload tax | 21,005 chars | **~10,500** |

Under the 12,000-char success criterion. Per-wave detail is on #99.

## The review fixes

**The gate failed open four ways, three of them found after the retrofit shipped.** An unrecognised follower token made a dangling target vanish. A skill directory with no `SKILL.md` resolved as a valid target, so a commit could be green locally and red in a fresh clone — three existing fixtures were relying on that, one of which made the install-leak A/B pass vacuously. Then the free-standing `/name` sweep turned out to be gated on the sentence carrying a boundary marker, so route notation in any other sentence was invisible — not an ERROR, not a SUGGESTION, not an INFO — which left the documented "`/name` always blocks" promise false from a second direction. All four fixed and pinned.

**Two checks were silently not running.** `validate-provenance.sh` checks 7-8 were dead across nine skills. Waking them exposed a deeper problem: they assume `Research doc:` names a source index, but 30 of 121 entries point at topic content documents, so every new check-7 INFO was a false positive and check 8 was saved from a false-FAIL flood only by an *unannounced* skip. Checks 7/8 are now scoped to source indexes and every skip announces itself (#121).

**The retrofit's own anti-goal, four times.** ADR-0020 warns that a blunt gate gets satisfied by deleting content rather than relocating it. `diagnose` and `skill-audit` relocated prose and then read it unconditionally; `prototype` and `vale-config` deleted rules outright that survived nowhere. All four addressed.

## Verification

- `bash tests/run-tests.sh --strict` — 24 suites, 0 skipped, 0 failed
- `bash tests/run-bats.sh` — 325 tests, 0 failures
- `pre-commit run --all-files` — 17/17
- `pre-commit run --hook-stage pre-push --all-files` — 16/16, with `apm marketplace check` and `apm pack --check-clean` run against the remote, not skipped
- `scripts/skill-size-check.sh` over all 39 skills — rc 0, 0 ERROR/FAIL, SUGGESTION-only
- Preload tax measured at **10,498 chars**, max description 390 — both inside budget
- Every new test proven non-vacuous by a deliberate mutation of the behaviour it covers

**Per-commit sync, stated accurately:** the ten commits from the latest review round each pass `check-plugin-content-sync` in isolation, verified by checking each out in a detached worktree with a clean between. The earlier gitea window (`dfacf05..bedbd1d`, nine commits) does **not** — its mirror was regenerated in one batch at `bbc7300`. An earlier revision of this description claimed the property held for every commit; it does not, and a bisect through that window lands on a red commit. **Squash-merge** to collapse it, or accept that this range is not bisectable.

## Version bump

Six plugins and the catalog take a **patch**, not a minor. The branch is **89 commits — 40 `fix` / 30 `refactor` / 12 `docs` / 5 `chore` / 2 `test` — zero `feat`, zero `!`, zero `BREAKING CHANGE`** — and adds no skill, agent, command or hook. (Two earlier revisions of this section cited a stale histogram, most recently 78 commits; the figures above are measured at HEAD.) Both rules this repo ships (`forge/references/version-bump.md`, landing in this PR, and `git-commits/references/conventional-commits-spec.md`) make that a patch, and the catalog set is unchanged at 7 entries.

Not settled by that: four published files were removed from the installed tree, three moved, and `caveman` gained `disable-model-invocation`, retiring its old triggers. Under a strict reading those are major-class and currently ship under `refactor:` with no marker. Whether the deployed skill surface is a public contract is written down nowhere — worth deciding, but it outlives this PR.

## Deliberately not in scope

#112 (cherry-pick ownership, now resolved in favour of `git-commits`), #113 (`rtk git` normalisation), #116 (research fan-out), #101 (audit-skill merge), #122 (non-spec skill-root files), #123 (no PRD producer) stay open. #117 is the one worth reading: the contract's remedy is to move prose into `references/`, which is exactly where neither the size gate nor Vale looks — and the blind spot is wider than #117 currently records, since there is no root `.vale.ini` at all, so every ADR, `CONTEXT.md` and `README.md` is unlinted too.

That blind spot let this branch carry two `level: error` `Kyberforge.SentenceOpenerThereIs` violations into `references/` files it created — `provider-adapter-author/references/provider-matrix.md:31` and `agent-audit/references/finding-criteria.md:95`. Both are reworded in `afadaae`, confirmed by routing each file through the audit's own `vale-wrap.sh` (1 error each before, 0 after). Five further occurrences sit in `references/` files already on `main`; those are the pre-existing corpus and stay with #117, which is the real fix.

Also unfixed and not this PR's: `apm install` appends a duplicate `SessionStart` entry to `.claude/settings.json`, so a fresh clone cannot get pre-push green without an edit AGENTS.md warns against. Reproduces identically on `main`.

Co-authored-by: Defame1297 <gitea@rkdr.net>
Reviewed-on: https://git.dev.rkdr.net/Defame1297/holocron/pulls/129
Co-authored-by: Claude Code AI - Gitea MCP <claude@noreply.git.dev.rkdr.net>
Co-committed-by: Claude Code AI - Gitea MCP <claude@noreply.git.dev.rkdr.net>
2026-09-01 13:47:46 +00:00

6.2 KiB

agent-audit

Audits an agent definition for correctness and quality against the Claude Code and Copilot agent references and the house context-budget contract (ADR-0020) — a single vendor-neutral file at plugin/APM scope, or a Claude Code and Copilot file pair at project/user scope.

What it does

  1. Runs scripts/validate.sh and scripts/validate-provenance.sh for structural and provenance checks, plus scripts/vale-wrap.sh — a Vale prefilter that deterministically flags non-imperative description openers, composition and architecture notes, vague wording, padding phrases, "There is/are" sentence openers, and CC-specific "Use proactively" phrasing in a Copilot or vendor-neutral description
  2. Reads the agent file, and its counterpart when one exists, then loads the contract for its scope
  3. Applies qualitative checks across description, body, delegation and comment discipline, loading one rubric from references/ per group
  4. Outputs a compact findings report — findings only, grouped by dimension, each with Why and Fix — and a result block with handoff to agent-author

Two things follow from ADR-0020 and are easy to get backwards. Agents take the same description gates a skill takes — 250 characters SUGGESTION, 400 FAIL, since a name + description is preloaded into every session either way — and no body word gate at all, because an agent body becomes the system prompt of a fresh context rather than competing with the caller's live conversation. Body length is judged through the delegation check instead: an agent body that restates a procedure owned by a skill it can invoke is a FAIL, because a plugin-scope agent has no sibling references/ directory to disclose to and can only delegate.

At plugin/APM scope the audit accepts the single .apm/agents/<name>.agent.md file — there is no counterpart, and pair consistency does not apply. validate.sh hard-FAILs any frontmatter field outside the vendor-neutral allowlist, since apm compile copies frontmatter verbatim to both harnesses and an unsafe field cannot be silently dropped for just one of them. The allowlist lives in the apm-agent-allowlist section of references/field-inventory.md, is read from there as data by the script, and is deliberately not restated anywhere else in this skill (ADR-0009).

At project/user scope the audit accepts either file in a CC .md / Copilot .agent.md pair, derives the counterpart automatically, and validates both, including the field-leakage checks in each direction.

Usage

/agent-audit

Pass the path to either agent file as the argument.

Files

File Purpose
SKILL.md Skill instructions for agents
assets/vale/.vale.ini Vale config: scopes Kyberforge to **/agents/*.md, Kyberforge+KyberforgeCopilot to **/*.agent.md
assets/vale/styles/Kyberforge/CompositionNote.yml Flags composition and architecture notes in a description ("cross-cutting", "entry point", "composes", "rather than duplicating") that belong in README.md
assets/vale/styles/Kyberforge/DescriptionOpener.yml Flags descriptions opening with "This..." instead of an imperative "Use when..."
assets/vale/styles/Kyberforge/PaddingPhrase.yml Flags generic "see references/ for info" pointers instead of specific file references
assets/vale/styles/Kyberforge/SentenceOpenerThereIs.yml Flags sentences opening with "There is/are" instead of naming the subject directly
assets/vale/styles/Kyberforge/VagueWording.yml Flags vague capability wording ("helps with", "utilize", "assists with", "used for") in descriptions
assets/vale/styles/KyberforgeCopilot/ProactivePhrase.yml Flags CC-specific "Use proactively" phrasing with no effect in Copilot descriptions
references/README.md Directory documentation for references/
references/finding-criteria.md Every dimension's FAIL and SUGGESTION criteria — the one Step 3 file read on every run; it decides which rubrics below are worth loading
references/description-quality.md Rubric for the description dimension — why the description is the expensive part, the hand-invoked contract, the three-part shape, indirect triggers, and near-miss exclusions
references/body-and-delegation.md Rubric for the body, delegation and comment-discipline dimensions — the core test, the delegation FAIL, why agents take no body word gate, and what an agent body is for
references/scope-plugin-apm.md Scope contract for a single vendor-neutral APM agent file — allowlist, dimension routing, and the dimensions that do not apply
references/scope-project-user.md Scope contract for a CC / Copilot pair — counterpart derivation, provider field rules, pair consistency
references/validation-scripts.md Loaded only when a Step 1 script fails or cannot run — scope-detection walk-up, manual fallback checks, known script failures
references/field-inventory.md Authoritative field lists read as data by validate.sh: valid CC and Copilot agent fields, and the vendor-neutral plugin/APM-scope allowlist
references/sources.md Research provenance for skill content
scripts/README.md Directory documentation for scripts/
scripts/validate.sh Structural validator — required fields, name format, placeholder detection, the ADR-0020 description budget, and the field rules for the detected scope
scripts/validate-provenance.sh Provenance chain validation against sources.md at the package root (plugin/APM scope only)
scripts/vale-wrap.sh Drop-in vale wrapper that works around a frontmatter-description NLP scope limitation
tests/README.md (source-only) Bats test dependency and run instructions
tests/validate.bats (source-only) Bats tests for validate.sh
tests/validate-provenance.bats (source-only) Bats tests for validate-provenance.sh

Rows marked (source-only) exist in the authoring source (.apm/skills/agent-audit/) but are not present in an installed plugin: scripts/sync-plugin-content.sh strips <category>/<name>/tests when it generates the flat mirror, because these are dev-time fixtures no plugin host needs to discover (ADR-0017). Run them from a repo checkout, not from an install.