AGENTS.md@toolkit/skillet · git:20261001.7c50d2d · 2026-10-01 · sha256 7784823a4074b752

AGENTS.md@toolkit/skillet git:20261001.7c50d2dA

Immutable. This exact content never changes and is served at /api/v1/blob/7784823a4074b752.

# ai-skillet contributor guidance

Keep the CLI synchronous and library-owned: `src/main.rs` parses process arguments and maps errors to exit codes, while
behavior belongs in `src/lib.rs` and focused modules.

The supported public surface is `map`, `doctor`, `doctor --dependencies-only`, and `--version`. Preserve the documented
exit codes and deterministic text, JSON, and DOT output contracts.

Use the nightly minimal Rust toolchain configured in `toolkit/`. Before proposing a change, run the narrowest relevant
locked Cargo check. Keep macOS and Linux compatibility; do not add runtime services, plugin systems, config files, shell
hooks, or completion generation without an explicit product decision.

From `toolkit/`, `cargo test -p ai-skillet --locked` is the focused package gate and `just rust-check` is the aggregate
Rust gate. `just install-cli` installs every workspace binary under `~/.local`; do not run it for ordinary verification.

## CLI reference

`ai-skillet` inspects and maintains catalogs of agent skills.

### Status

Version 1.0.0 provides synchronous, no-network `map` and `doctor` engines. JSON reports use the clean Rust schema
version 1. The schema preserves the Python tools' consumer contracts, but output is not byte-compatible with the Python
implementation.

### Commands

```text
ai-skillet map [OPTIONS]
ai-skillet doctor [OPTIONS]
ai-skillet --version
```

`doctor --dependencies-only` limits diagnostics to skill-dependency declarations. Repeatable `doctor --skill <NAME>`
filters diagnostics and safe fixes by canonical skill directory name.

A catalog root that exposes `skills/` must provide a `README.md` with an exact `## Skills` section and a Markdown table.
The required first column is `Skill` and lists every active skill name; additional columns are optional and ignored by
the inventory validator. Conventional installed roots named `.agents`, `.claude`, or `.codex` do not require a catalog
README inventory.

Skills in ordinary source-catalog `skills/<name>` paths must provide `agents/openai.yaml`. Conventional installed
exposures beneath `.agents/skills`, `.claude/skills`, or `.codex/skills` may omit that file. When an installed exposure
provides it, doctor still validates the extended `policy.allow_implicit_invocation` contract and can safely update a
mismatch.

### Doctor validation contract

`ai-skillet doctor --root <skill-or-catalog-root>` is the canonical deterministic, offline local validator for the
supported extended skill dialect. For an explicit targeted audit, pass a catalog root with one or more filters:

```sh
ai-skillet doctor --root '.agents/skills' --skill 'land-search'
```

A direct `skills/<name>` root is shorthand for auditing only that directory while resolving bare dependencies against
sibling skills in the owning `skills` directory. This applies equally to source catalogs and `.agents`, `.claude`, or
`.codex` installed exposures, including directory symlinks. A standalone skill outside a `skills/<name>` layout does not
infer an owning catalog; bare dependencies must still resolve from explicitly supplied roots. Targeted audits omit
catalog-wide README inventory diagnostics, and `--fix-safe` modifies only selected skills.

Doctor accepts this one top-level field union:

- Portable [Agent Skills](https://agentskills.io/specification): `name`, `description`, `license`, `compatibility`,
  `metadata`, and `allowed-tools`.
- [Claude Code extensions](https://code.claude.com/docs/en/skills#frontmatter-reference): `when_to_use`,
  `argument-hint`, `arguments`, `disable-model-invocation`, `user-invocable`, `disallowed-tools`, `model`, `effort`,
  `context`, `agent`, `background`, `hooks`, `paths`, and `shell`.
- Repository extensions: `coordination` and `skill-dependencies`.

Unknown top-level fields are errors. `metadata` must be a string-to-string mapping; `metadata.install-targets`
additionally accepts only `claude-code`, `codex`, or `claude-code codex`. Tool, argument, and path fields accept a
string or a list of strings, while `hooks` must be a mapping. Claude Boolean fields accept `true`/`false`, `yes`/`no`,
`on`/`off`, or `1`/`0`; other YAML shapes are not coerced. `context` accepts only `fork`, `effort` accepts `low`,
`medium`, `high`, `xhigh`, or `max`, and `shell` accepts `bash` or `powershell`. `agent` and `background` require
`context: fork`.

`coordination: exempt` requires this exact sentence in ordinary Markdown body prose:

```text
This skill is coordination-exempt: skip the ai-coord gate for its declared work.
```

Inline code, fenced or indented code, blockquotes, and clearly headed `Example` or `Examples` sections do not count as
declarations and do not trigger missing-frontmatter errors.

New schema diagnostics use these stable codes:

- Unknown field: `FRONTMATTER_UNKNOWN_FIELD`.
- Invalid types: `LICENSE_INVALID_TYPE`, `ALLOWED_TOOLS_INVALID_TYPE`, `WHEN_TO_USE_INVALID_TYPE`,
  `ARGUMENTS_INVALID_TYPE`, `DISALLOWED_TOOLS_INVALID_TYPE`, `MODEL_INVALID_TYPE`, `EFFORT_INVALID_TYPE`,
  `BACKGROUND_INVALID_TYPE`, `HOOKS_INVALID_TYPE`, `PATHS_INVALID_TYPE`, `SHELL_INVALID_TYPE`, and
  `METADATA_VALUE_INVALID_TYPE`. Existing field-specific type codes remain unchanged.
- Invalid values: `EFFORT_INVALID_VALUE` and `SHELL_INVALID_VALUE`, alongside the retained compatibility, context,
  coordination, and install-target codes.
- Cross-field errors: `AGENT_CONTEXT_REQUIRED` and `BACKGROUND_CONTEXT_REQUIRED`.
- Explicit defaults: `disable-model-invocation: false` and `user-invocable: true` restate the effective defaults and are
  accepted without findings, so catalogs that require explicit booleans stay clean.

These diagnostics add findings without changing JSON schema version 1, deterministic finding order, exit codes, or the
existing `--fix-safe` boundary.

### Conformance contract

| Area         | Required contract                                                                                                                                                     | Intentional version 1 behavior                                                                          |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| CLI          | Usage and operational errors exit 2; doctor findings exit 1; safe-fix failures exit 3                                                                                 | Operational errors are emitted once with no generic duplicate                                           |
| Map output   | Deterministic text, JSON, and DOT; skills, roots, edges, duplicates, unresolved references, hashes, and portfolio exposures remain available                          | Declared and inferred evidence remain independent; missing filters warn while returning an empty report |
| Discovery    | Explicit roots, broad-root exclusions, portfolio roots, ignored entries requested directly, symlink exposures, and paths containing newlines are supported            | Local dependencies resolve across every scanned root                                                    |
| Streaming    | Large files and newline-free lines are scanned with bounded buffers; snippets are bounded match text                                                                  | No ripgrep child process or cancellation lifecycle is required                                          |
| Doctor       | The complete supported frontmatter union plus every metadata, dependency, coordination, resource, README, prompt-hygiene, and CLI-version finding family is validated | YAML and OpenAI policy diagnostics are structural; safe fixes are isolated and atomic                   |
| Dependencies | Bare and external identifiers, uniqueness, self-reference, resolution, and target-name ordering are validated                                                         | External owner/repository case is preserved; repository names ending in `.git` are rejected             |

The integration tests in `tests/conformance.rs`, `tests/map.rs`, `tests/doctor.rs`, and `tests/catalog.rs` are the
executable contract. Python captures are migration evidence, not golden output fixtures.

### Development

The toolkit workspace selects nightly Rust with the minimal profile plus `clippy` and `rustfmt`.

```sh
cargo test -p ai-skillet --locked
just rust-check
```

From `toolkit/`, `just install-cli` installs all five workspace binaries under `~/.local`.

### License

MIT. See [LICENSE.md](../LICENSE.md).