Commit Graph

5 Commits

Author SHA1 Message Date
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
a8cd5e881d fix(core): strip a BOM before the adapter import check, and split usage exits
Narrowing has_reference to bool(import_lines) meant a UTF-8 BOM hid the import
line, since the BOM is not \s: a CLAUDE.md whose first line is @AGENTS.md failed
with 'no reference to AGENTS.md' and was told to add the line already in front of
it. Decoding is now strict too, so a non-UTF-8 adapter gets an encoding
diagnostic instead of being mangled and then graded on the mangling.

Usage errors move to exit 2. They shared exit 1 with real findings, while the
skill tells the agent to fix any non-zero exit by editing the provider file.

The whole-line import rule is kept deliberately -- accepting an inline @AGENTS.md
would also accept one inside backticks, which is the silent-drop failure the
validator exists to catch -- and the message now says so.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EJJrm5YmacbwMdzZpXcoti
2026-08-31 19:46:07 +00:00
1c3af75642 fix(core): make --no-import-syntax actually change the adapter validation
Both branches of the flag reduced to the same expression, so the option was
inert: a caller who asked for the no-import form got the import-form check
anyway and a passing result that meant nothing.

Two further defects in the same validator: --max-lines failed silently when
given a value it could not use, and the Fix text told the agent to edit
AGENTS.md when the offending content is the provider adapter's. The boundary
clauses now name the operation being routed rather than the file type, which
was ambiguous where both skills touch the same file.

Addresses #115.
2026-08-31 08:01:45 +00:00
c59e4bf0c5 refactor(core): retrofit provider-adapter-author to the ADR-0020 contract
Description 833 -> 239 chars, body 370 -> 387 words, Gotchas 41% -> 20%.
The file-type enumeration moves to a new references/provider-matrix.md;
the composition note was already in README.md.

Three defects a clean-context audit found, all fixed:

The 'never edits AGENTS.md' prohibition had become a justification clause
on the false branch of a conditional, so the common path never read a
sentence binding it. That matters because the bundled validator's own
remediation text tells the agent to move content into AGENTS.md, so a
size FAIL actively invited the prohibited edit. Restored as a standing
imperative, plus a counter at the step where the trap fires.

A Gotcha asserted that validate-adapter.sh fails without
--no-import-syntax. The flag is a no-op -- both branches reduce to the
same expression. Reverted to an instruction; the script defect is #115.

The boundary clauses used pronouns to dodge the #110 regex, and 'Not
auditing it' resolved to CLAUDE.md as readily as to AGENTS.md -- routing
'audit my CLAUDE.md' to a skill whose own description declines it.

Refs #99
2026-08-30 15:06:50 +00:00
6fd6876264 feat(core): add provider-adapter-author skill
Converts a target repo's provider-specific instruction file (CLAUDE.md,
.cursor/rules, copilot-instructions.md, etc.) into a thin adapter over
AGENTS.md, mirroring this repo's own two-tier CLAUDE.md pattern
(ADR-0002/0003). Self-validates via a bundled deterministic script
(scripts/validate-adapter.sh) rather than a separate paired audit skill.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 17:19:17 +00:00