git:20260921.e8da9da to git:20261001.7c50d2d

61 added, 70 removed. Audit A to A.

# 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.
+ 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.
+ 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 at the monorepo root. 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.
+ 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 the monorepo root, `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.
+ 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.
+ 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.
+ `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.
+ 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.
+ 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:
+ `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
+ 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`.
+ - 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`.
+ 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.
+ 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
+ - 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.
+ - 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.
+ - 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.
+ 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 |
+ | 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 |
+ | 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.
+ 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 monorepo selects nightly Rust with the minimal profile plus `clippy` and `rustfmt`.
+ 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 the monorepo root, `just install-cli` installs all five workspace binaries under `~/.local`.
+ From `toolkit/`, `just install-cli` installs all five workspace binaries under `~/.local`.
### License
MIT. See [LICENSE.md](../LICENSE.md).