design(core): no provider-file audit path — "is my CLAUDE.md OK?" reaches a write-only skill #128

Closed
opened 2026-08-31 08:08:53 +00:00 by Claude · 1 comment
Collaborator

Found during the #99 ADR-0020 retrofit and the follow-up audit pass on refactor/adr0020-skill-retrofit. The routing was made honest there; the gap itself is a build decision and was deliberately left open.

The gap

core has three skills. Two of them read, one of them writes:

skill allowed-tools
agentsmd-audit Bash Read
agentsmd-author Bash Read Write Edit
provider-adapter-author Bash Read Edit Write

agentsmd-audit and agentsmd-author both route every provider-file concern to provider-adapter-author. agentsmd-author does it emphatically — its Gotchas say:

Never write to a provider file yourself, in any circumstance… That holds even when the user asks for one in the same breath as AGENTS.md, and even when the file is merely stale or missing a pointer rather than duplicating anything. Detect it and hand off.

But provider-adapter-author is write-only in behaviour, not just in tools: its whole procedure is detect → rewrite down to a thin adapter → self-validate. There is no read-only path through it. So a user asking "is my CLAUDE.md OK?" was routed to something whose only behaviour is to rewrite it.

What was changed on the branch, and what was not

The two boundary clauses were reworded to name the operation rather than the domain:

  • agentsmd-audit: Not converting a provider file -> provider-adapter-author.
  • agentsmd-author: Not converting CLAUDE.md -> provider-adapter-author.

The route is now honest — it promises conversion, which is what the target does — and the gap is visible rather than silently mis-served. Nothing now claims provider-file auditing is covered. Nothing covers it either.

The likely answer

plugins/core/.apm/skills/provider-adapter-author/scripts/validate-adapter.sh already is the deterministic provider-file audit. Its own header calls it a "Self-check gate": given an adapter file and an AGENTS.md, it checks the file is non-empty, actually references AGENTS.md (as a native @import line, or as a plain-text pointer under --no-import-syntax for providers with no import mechanism), does not duplicate AGENTS.md's content, and stays under a line budget. Exit 0 or 1. That is a complete read-only verdict on a provider file, sitting inside a writer as a post-write assertion.

Promoting it into its own read-only skill is the honest long-term shape: a Bash Read skill that runs the script and reports, with agentsmd-audit's and agentsmd-author's provider-file clauses repointed at it, and provider-adapter-author keeping the script as its self-check.

Explicitly not the answer: a read-only mode flag on provider-adapter-author. A skill whose allowed-tools include Write and Edit cannot make a read-only promise the harness enforces — the same class of unenforceable prose guarantee tracked separately for the plugin agents. A mode flag also puts the two behaviours behind one description, which is precisely what ADR-0020's boundary-clause contract exists to prevent.

Open question before building

ADR-0020's "Merging siblings" criteria cut the other way and should be applied deliberately, not skipped. core would go from three skills to four, two of which (agentsmd-audit, the new provider auditor) are both read-only audits with adjacent descriptions in a small plugin — exactly the near-miss sibling density the boundary contract has to work hardest against. The alternative is folding provider-file auditing into agentsmd-audit and widening its scope, which costs a skill but buys one description instead of two competing ones. Decide that before writing anything.

Files

  • plugins/core/.apm/skills/provider-adapter-author/scripts/validate-adapter.sh — the existing deterministic check
  • plugins/core/.apm/skills/agentsmd-audit/SKILL.md — description boundary clause
  • plugins/core/.apm/skills/agentsmd-author/SKILL.md — description boundary clause, and the Gotchas hand-off rule
  • docs/adr/0020-skill-description-and-body-context-contract.md — "Merging siblings"
  • #115 — validate-adapter.sh's --no-import-syntax no-op, fixed on this branch; the same script
  • #101 — the other open sibling-merge question in this repo (skill-audit + agent-audit)
  • #99 — the retrofit during which this surfaced
Found during the #99 ADR-0020 retrofit and the follow-up audit pass on `refactor/adr0020-skill-retrofit`. The routing was made honest there; the gap itself is a build decision and was deliberately left open. ## The gap `core` has three skills. Two of them read, one of them writes: | skill | `allowed-tools` | |---|---| | `agentsmd-audit` | `Bash Read` | | `agentsmd-author` | `Bash Read Write Edit` | | `provider-adapter-author` | `Bash Read Edit Write` | `agentsmd-audit` and `agentsmd-author` both route every provider-file concern to `provider-adapter-author`. `agentsmd-author` does it emphatically — its Gotchas say: > Never write to a provider file yourself, in any circumstance… **That holds even when the user asks for one in the same breath as AGENTS.md, and even when the file is merely stale or missing a pointer rather than duplicating anything.** Detect it and hand off. But `provider-adapter-author` is write-only in behaviour, not just in tools: its whole procedure is detect → rewrite down to a thin adapter → self-validate. There is no read-only path through it. So a user asking "is my CLAUDE.md OK?" was routed to something whose only behaviour is to rewrite it. ## What was changed on the branch, and what was not The two boundary clauses were reworded to name the **operation** rather than the domain: - `agentsmd-audit`: `Not converting a provider file -> provider-adapter-author.` - `agentsmd-author`: `Not converting CLAUDE.md -> provider-adapter-author.` The route is now honest — it promises conversion, which is what the target does — and the gap is visible rather than silently mis-served. Nothing now claims provider-file *auditing* is covered. Nothing covers it either. ## The likely answer `plugins/core/.apm/skills/provider-adapter-author/scripts/validate-adapter.sh` already **is** the deterministic provider-file audit. Its own header calls it a "Self-check gate": given an adapter file and an `AGENTS.md`, it checks the file is non-empty, actually references `AGENTS.md` (as a native `@import` line, or as a plain-text pointer under `--no-import-syntax` for providers with no import mechanism), does not duplicate `AGENTS.md`'s content, and stays under a line budget. Exit 0 or 1. That is a complete read-only verdict on a provider file, sitting inside a writer as a post-write assertion. Promoting it into its own read-only skill is the honest long-term shape: a `Bash Read` skill that runs the script and reports, with `agentsmd-audit`'s and `agentsmd-author`'s provider-file clauses repointed at it, and `provider-adapter-author` keeping the script as its self-check. **Explicitly not the answer: a read-only mode flag on `provider-adapter-author`.** A skill whose `allowed-tools` include `Write` and `Edit` cannot make a read-only promise the harness enforces — the same class of unenforceable prose guarantee tracked separately for the plugin agents. A mode flag also puts the two behaviours behind one description, which is precisely what ADR-0020's boundary-clause contract exists to prevent. ## Open question before building ADR-0020's "Merging siblings" criteria cut the other way and should be applied deliberately, not skipped. `core` would go from three skills to four, two of which (`agentsmd-audit`, the new provider auditor) are both read-only audits with adjacent descriptions in a small plugin — exactly the near-miss sibling density the boundary contract has to work hardest against. The alternative is folding provider-file auditing into `agentsmd-audit` and widening its scope, which costs a skill but buys one description instead of two competing ones. Decide that before writing anything. ## Files - `plugins/core/.apm/skills/provider-adapter-author/scripts/validate-adapter.sh` — the existing deterministic check - `plugins/core/.apm/skills/agentsmd-audit/SKILL.md` — description boundary clause - `plugins/core/.apm/skills/agentsmd-author/SKILL.md` — description boundary clause, and the Gotchas hand-off rule - `docs/adr/0020-skill-description-and-body-context-contract.md` — "Merging siblings" ## Related - #115 — `validate-adapter.sh`'s `--no-import-syntax` no-op, fixed on this branch; the same script - #101 — the other open sibling-merge question in this repo (`skill-audit` + `agent-audit`) - #99 — the retrofit during which this surfaced
Claude added this to the Skills & Agents milestone 2026-08-31 08:08:53 +00:00
Claude added the Kind/Enhancement
Reviewed
Confirmed
1
Priority
Low
4
labels 2026-08-31 08:08:53 +00:00
Owner

Wont fix, Not a significant enough gap

Wont fix, Not a significant enough gap
Defame1297 added
Reviewed
Won't Fix
3
and removed
Reviewed
Confirmed
1
labels 2026-09-01 20:10:55 +00:00
Sign in to join this conversation.