Files
holocron/plugins/core/skills/provider-adapter-author/SKILL.md
Defame1297 59f27dbd94 fix(core): close five ways validate-adapter.sh graded an adapter it had not read
The adapter check shipped green on files it should have failed, and failed files it
should have passed. Each defect is a residual of the fix that closes #115.

A fenced, indented or HTML-commented `@AGENTS.md` counted as an import, though
Claude Code resolves none of them — the adapter deferred to nothing and the gate
said so approvingly. Import matching now runs against a character mask that marks
fenced blocks and HTML comments inert, and applies CommonMark's four-space rule.
The mask is deliberately not applied to prose pointers, where four-space
indentation is ordinary list continuation.

The encoding fix reached only BOM-carrying UTF-16/32. BOM-less UTF-16LE/BE and
UTF-32LE are valid UTF-8, so they still produced the exact false diagnosis the fix
was written to remove: "no reference to AGENTS.md" on a file whose first line is
`@AGENTS.md`. A NUL-byte check is the complete signal. BOM stripping is no longer
positional, which also drops the mirror-image false FAILs on a doubled or mid-file
BOM.

`@NOTAGENTS.md`, `@zzzAGENTS.md` and `@docs/does/not/exist/AGENTS.md` all passed:
the pattern had no path-segment boundary and the target was never resolved on disk.
Both now hold, and a zero-byte or blank target is reported rather than credited.
Unresolved candidates print as `Near miss:` lines so the author sees why a line was
not counted.

`--no-import-syntax` still used substring matching, so `Do NOT read AGENTS.md; it
is obsolete.` passed as a pointer. That is #115's own defect surviving in the flag's
other mode. A mention must now carry a deference cue and must not be negated.

An unreadable file passed `isfile()`, raised, and exited 1 with a traceback and no
FAIL line — the one exit code no document covered, while Step 3 says to re-run
until it exits 0. It now exits 3 with a diagnostic, and the README states all four
codes and what to do about each instead of "exits non-zero on any failure".

Tests 18 to 42. Two of the new cases initially survived their own mutation and were
strengthened: `@NOTAGENTS.md` was being rejected by the disk check before the token
boundary ran, and stripping that boundary leaves the fragment `NOT`, which the
negation cue then rejects for an unrelated reason.

Refs: #115
2026-09-01 12:38:04 +00:00

3.6 KiB

name, description, allowed-tools, metadata
name description allowed-tools metadata
provider-adapter-author Use when a provider file (CLAUDE.md, .cursor rules, copilot-instructions) duplicating the repo's AGENTS.md should be cut to a thin adapter — "make CLAUDE.md just import AGENTS.md". Not writing the AGENTS file -> `agentsmd-author`. Not auditing the AGENTS file -> `agentsmd-audit`. Bash Read Edit Write
category source_keys version
docs
adr-0002-0003-two-tier-claude-md
0.1.1

Gotchas

  • Assume a provider has no cross-file import mechanism until you have confirmed it has one. Claude Code is the exception, not the rule: a CLAUDE.md may consist of nothing but @path lines, while the same @AGENTS.md line in a Cursor rule or a Copilot instructions file is inert text no tool resolves. Pass --no-import-syntax to scripts/validate-adapter.sh for those providers.

  • Works standalone or composed-into by agentsmd-author — behave identically either way; do not assume a caller skill exists. Detect the provider file, confirm AGENTS.md, and run the closeout validator yourself in both cases (references/provider-matrix.md).

Step 1 — Detect

Find the provider instruction file to convert. Before searching, read references/provider-matrix.md — skip it only when the target is already a known root CLAUDE.md, which is the common case.

Then confirm AGENTS.md exists at the repo root. If it does not, stop and tell the user to run agentsmd-author first — there is nothing to adapt to.

Step 2 — Diff and rewrite

Read the provider file and AGENTS.md side by side. Separate the provider file's content into two buckets: lines that restate what AGENTS.md already owns (universal rules, conventions, project overview) versus lines that are genuinely provider-specific (tool syntax, IDE behavior, model-specific instructions). Rewrite the provider file:

  • Providers with import syntax (Claude Code): replace the redundant bucket with an @AGENTS.md (or correct relative path) import on a line of its own, keep the provider-specific bucket below it. An import folded into a sentence is not the thin-adapter shape and scripts/validate-adapter.sh will not credit it — nor one inside a code fence, an indented block, or an HTML comment, nor one whose path does not resolve to a real, non-empty file on disk.
  • Providers without import syntax (Cursor, Copilot, etc.): replace the redundant bucket with a short sentence pointing at AGENTS.md ("See AGENTS.md at the repo root for ..."), keep the provider-specific bucket. A bare or negated mention is not a pointer and will not be credited.

The provider file is the only file this skill ever writes. Never create or edit AGENTS.md — not in this step, not in any step, whatever the payoff looks like.

Strip only what is genuinely redundant. Provider-specific material stays even when it is short — the goal is thin, not empty.

Step 3 — Self-validate

Run the bundled check before finishing — this is the skill's own closeout gate; there is no separate paired audit skill for this concern:

bash scripts/validate-adapter.sh [--no-import-syntax] [--max-lines N] <adapter-file> <agents-md-file>

Fix any FAIL by editing the provider file, and re-run until it exits 0. Exits 2 and 3 are not FAILs and nothing was graded under either, so neither is a reason to touch the adapter: 2 means the invocation or the input is wrong (a bad, missing, or extra argument, an unknown option, or a file that is not UTF-8), and 3 means a named file exists but could not be read.

Step 4 — Report

State which file was converted, what was removed versus kept, and the validator's final result.