# Vat Audit

> Use when running vat audit to validate Claude plugins, agent skills, or marketplaces. Covers the audit command, --compat flag for surface compatibility analysis, --exclude for noise filtering, and interpreting audit output.

- Skill: `jdutton/vat-audit` (Agent Skill)
- Install (CLI): `npx skillmds@latest add jdutton/vat-audit`
- Raw SKILL.md: https://api.skillmd.com/api/skills/jdutton/vat-audit/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: jdutton (https://skillmd.com/u/jdutton)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/jdutton/vat-audit

---


# VAT Audit: Validating Plugins, Skills & Marketplaces

## Running the Audit

```bash
# Audit current directory (recursive by default)
vat audit

# Audit a specific directory
vat audit ./plugins/

# Audit your entire Claude installation
vat audit --user

# Exclude noisy directories
vat audit --exclude "dist/**" --exclude "node_modules/**"

# Verbose: show all resources, not just those with issues
vat audit --verbose

# Compatibility analysis: which Claude surfaces each plugin supports
vat audit ./plugins/ --compat
```

## What Gets Detected (Automatic)

Running `vat audit <path>` recursively walks the directory and auto-detects:

| Found | Detected as |
|---|---|
| `.claude-plugin/plugin.json` in a dir | Claude Plugin |
| `.claude-plugin/marketplace.json` in a dir | Claude Marketplace |
| `SKILL.md` file | Agent Skill |
| `agent.yaml` + `SKILL.md` | VAT Agent |
| `installed_plugins.json` | Registry file |

Recursion is the default — you do not need `--recursive`.

## Auditing a remote git repo

`vat audit` accepts a git URL in addition to a local path. VAT shallow-clones into a temp directory, audits the clone, and **always cleans up on exit** — including on errors and SIGINT.

```bash
# Audit a public repo (HTTPS)
vat audit https://github.com/foo/bar.git

# GitHub shorthand
vat audit foo/bar

# Pin to a branch or tag
vat audit foo/bar#main
vat audit https://github.com/foo/bar.git#v1.2.3

# Narrow to a monorepo subpath
vat audit foo/bar#main:plugins/baz

# A GitHub web URL also works
vat audit https://github.com/foo/bar/tree/main/plugins/baz
```

Output is preceded by a provenance header — `# Audited: <url> @ <ref> (commit <sha>)` — emitted as YAML comments so `vat audit <url> | yq` parses cleanly. Audited paths are repo-relative, never tempdir-relative.

**Authentication is pure passthrough to your local `git`.** SSH URLs use your SSH agent / keys; HTTPS URLs use whatever credential helper your `git` is configured with. VAT itself reads no tokens. If `git clone <url>` works on your machine, `vat audit <url>` works.

**Inspection.** Pass `--debug` to preserve the cloned tempdir for post-mortem inspection (its location is printed to stderr at exit). You are responsible for cleanup when using this flag.

For the full URL form table and edge cases, see `packages/cli/docs/audit.md` (the "Auditing a remote git repo" section).

## Audit vs configured VAT projects

Audit is the general-purpose command — you may point it at any path, configured or not. When it encounters a SKILL.md inside a configured VAT project, it walks UP to that skill's nearest-ancestor `vibe-agent-toolkit.config.yaml` and respects the skill's per-skill packaging rules (`excludeReferencesFromBundle`, `linkFollowDepth`, `files`) to avoid false flags — but it never composes configs across project boundaries. Per-skill rules from one project do not bleed into skills in another project. For gated, configured-project-level validation, use the lifecycle commands (`vat skills validate`, `vat verify`) and run them from within the project directory.

## Compatibility Analysis (`--compat`)

```bash
vat audit ./plugins/ --compat
```

Output per plugin:
```yaml
plugin: mission-control
compatibility:
  claude-code:
    compatible: true
    evidence: []
  cowork:
    compatible: true
    evidence: []
  claude-desktop:
    compatible: false
    evidence:
      - type: python-script
        file: hooks-handlers/handler.py
        detail: Python execution not available in claude-desktop
```

Use this before a release to determine which surfaces each plugin supports.

## Exit Codes

`vat audit` is **advisory** — it reports every issue it detects but never blocks on validation severity:

- `0` — always, when the audit completes, regardless of errors or warnings in the report.
- `2` — system error (path not found, permission denied, etc.) — the audit could not run.

For gated checks that exit `1` on validation errors, use `vat skills validate` or `vat skills build` instead. Those commands apply `validation.severity` and honor `validation.allow` from config.

## CI Usage

```yaml
# vibe-validate.config.yaml
steps:
  - name: Plugin and skill validation
    command: vat audit plugins/ --exclude "**/__pycache__/**"
```

## Interpreting Output

```yaml
root: /abs/path/you/pointed/audit/at   # the ONE absolute path in the document
status: warning
summary:
  filesScanned: 23
  success: 21
  warnings: 2
  errors: 0
files:
  - path: plugins/my-plugin                                          # relative to root
    issues:
      - location: plugins/my-plugin/.claude-plugin/plugin.json       # relative to root
```

**`root` is the coordinate system for the whole document.** Every `path` and every issue `location` is forward-slashed and relative to it, so `join(root, location)` is the file to open and a `location` identifies a file uniquely even when a run spans several projects with the same internal layout. `root` is the *invocation scan root*, deliberately not each skill's governing-config root — per-skill packaging rules still come from the nearest-ancestor `vibe-agent-toolkit.config.yaml`, but that discovery has no say in how a path is spelled. `--user` states the shared Claude config dir; a URL audit omits `root` and the provenance header names the base instead.

Severity taxonomy in audit output:
- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations
- **Warnings:** Skill too long, description too short, best practice violations

Audit always exits `0` regardless — surface-level severity drives display grouping only.

**Hiding codes from audit output.** Audit ignores `validation.allow` by design (it is the read-only report), but it does honor `validation.severity`. Set a code to `ignore` in `vibe-agent-toolkit.config.yaml` to suppress it from the audit output:

```yaml
skills:
  config:
    my-skill:
      validation:
        severity:
          LINK_TO_NAVIGATION_FILE: ignore   # hidden from audit output
```

**Per-instance allow entries.** For per-path suppression with an audit trail, use `validation.allow` and run `vat skills validate` or `vat skills build` — those commands apply `allow` and gate the build. See `docs/validation-codes.md` for the full code reference and the VAT agent-authoring skill for configuration patterns.

