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
This commit is contained in:
2026-08-31 19:46:07 +00:00
parent 00daf285ec
commit a8cd5e881d
9 changed files with 162 additions and 31 deletions

View File

@@ -21,3 +21,12 @@ silently drops every rule the adapter was supposed to defer to.
Detection is a search, not a lookup: a repo may hold more than one of these, and each one converts
independently against the same `AGENTS.md`.
## Standalone and composed runs behave identically
This skill is reached two ways: invoked directly by a user, and composed into by `agentsmd-author`
once it has written or updated the repo's `AGENTS.md`. Behave identically either way — do not
assume a caller skill exists. Detect the provider file yourself, confirm `AGENTS.md` yourself, and
run the closeout validator yourself, rather than treating any step as already done by the caller or
as something the caller will do afterwards. There is no handshake to rely on and no state passed
in beyond the file paths.