Files
holocron/docs/adr/0018-agent-audit-single-file-invocation.md
Defame1297 92c13b997f feat(kyberforge): add agent-audit skill (closes #11)
## Why

agent-author produces paired agent definition files (Claude Code .md +
Copilot .agent.md) but had no companion audit skill to validate them.
agent-audit fills that gap, giving the same structured PASS/FAIL report
that skill-audit provides for SKILL.md files.

## Implementation Notes

- validate.sh uses scope detection (walk up for plugin.json / .git) to
  locate the counterpart file and determine whether plugin-silently-ignored
  fields (hooks, mcpServers, permissionMode) should be flagged
- CC-only and silently-ignored field lists are read from
  references/field-inventory.md at runtime rather than hardcoded —
  provenance back to the research corpus; see ADR-0019
- Single-file invocation (pass either file, counterpart derived) chosen
  over directory or name+root — see ADR-0018
- 12 bats tests cover provider detection, scope detection, all FAIL paths,
  and clean-pair pass

## Impact

- kyberforge bumped to v1.1.2
- agent-author close step should be updated to reference agent-audit (#11)
- Provenance/sources chain check deferred to #60

ADR: docs/adr/0018-agent-audit-single-file-invocation.md
ADR: docs/adr/0019-agent-audit-field-inventory-reference.md
Refs: #11
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0147vXtL5sP6vorDdqXGJJU9
2026-07-04 10:06:37 +00:00

1.8 KiB

agent-audit takes a single file path and derives the counterpart by scope detection

agent-audit validates agent definition file pairs (Claude Code .md + Copilot .agent.md). The skill accepts a path to either file and derives the counterpart using scope detection rather than requiring the caller to name both files or supply a root directory.

Considered options

Directory input (rejected) — analogous to skill-audit <skill-dir>. Rejected because agents have no per-agent directory. At plugin scope both files are flat in agents/; at project scope they are in completely different directories (.claude/agents/ and .github/agents/). No single directory contains both files across all scopes.

<name> <root> signature (rejected) — mirrors new-agent.sh <name> <root>. Rejected because it requires the caller to supply two pieces of information when one (the file path) is sufficient. The file path already implies the agent name (filename stem) and the root (found by walking up). Forcing the caller to re-supply what the script can infer is the kind of convention knowledge the script exists to encapsulate.

Consequences

  • The unit of validation is the pair. A missing counterpart is always a FAIL — an orphan file is incomplete by definition.
  • Scope detection walks up from the input file: first directory containing plugin.json → plugin scope; first directory containing .git without plugin.json → project scope; path under ~ with neither → user scope.
  • At user scope the derivation crosses filesystem locations (~/.claude/agents/ ↔ ~/.copilot/agents/); the script must handle the home directory case explicitly.
  • The invocation signature is the public contract. Changing it is a breaking change to any caller — treat it as such.