@vibe-agent-toolkit/vat-development-agents 0.1.30-rc.1 → 0.1.30-rc.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,16 +8,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
8
8
  ## [Unreleased]
9
9
 
10
10
  ### Changed
11
- - **BREAKING: Unified validation framework replaces `ignoreValidationErrors`.** Every overridable integrity check now flows through a single `validation` block (`severity` + `accept`) under `skills.defaults` / `skills.config.<name>` in `vibe-agent-toolkit.config.yaml`. The previous non-overridable error tier (`OUTSIDE_PROJECT_BOUNDARY`, `LINK_TARGETS_DIRECTORY`, `LINKS_TO_NAVIGATION_FILES`) is removed and replaced by unified `LINK_*` codes that accept the same overrides as everything else. Project-config schemas are now strict — configs containing the removed `ignoreValidationErrors` field (or any other unknown key) fail at parse time with `"Unrecognized key(s) in object"` instead of silently dropping, so upgrades surface the migration work immediately. See [jdutton/vibe-agent-toolkit#83](https://github.com/jdutton/vibe-agent-toolkit/issues/83) for full design rationale and the canonical code reference at `docs/validation-codes.md`.
11
+ - **BREAKING: Unified validation framework replaces `ignoreValidationErrors`.** Every overridable integrity check now flows through a single `validation` block (`severity` + `allow`) under `skills.defaults` / `skills.config.<name>` in `vibe-agent-toolkit.config.yaml`. The previous non-overridable error tier (`OUTSIDE_PROJECT_BOUNDARY`, `LINK_TARGETS_DIRECTORY`, `LINKS_TO_NAVIGATION_FILES`) is removed and replaced by unified `LINK_*` codes that accept the same overrides as everything else. Project-config schemas are now strict — configs containing the removed `ignoreValidationErrors` field (or any other unknown key) fail at parse time with `"Unrecognized key(s) in object"` instead of silently dropping, so upgrades surface the migration work immediately. See [jdutton/vibe-agent-toolkit#83](https://github.com/jdutton/vibe-agent-toolkit/issues/83) for full design rationale and the canonical code reference at `docs/validation-codes.md`.
12
12
  - **BREAKING: `PACKAGED_UNREFERENCED_FILE` and `PACKAGED_BROKEN_LINK` now block the build.** Previously logged at info level without affecting exit code; now default severity `error` with `vat skills build` exiting `1`. Downgrade via `validation.severity: { PACKAGED_UNREFERENCED_FILE: warning }` if needed.
13
- - **BREAKING: Expired `accept` entries no longer silently re-fire the underlying error.** The acceptance still applies; VAT emits a new `ACCEPTANCE_EXPIRED` warning to surface the stale date for re-review. Opt in to strict expiry with `validation.severity: { ACCEPTANCE_EXPIRED: error }`.
14
- - **`vat audit` is now advisory.** Audit always exits `0` regardless of validation severity, honors `validation.severity` for display grouping only, and ignores `validation.accept`. Use `vat skills validate` or `vat skills build` for gated checks with per-path acceptance.
13
+ - **BREAKING: Expired `allow` entries no longer silently re-fire the underlying error.** The allow entry still applies; VAT emits a new `ALLOW_EXPIRED` warning to surface the stale date for re-review. Opt in to strict expiry with `validation.severity: { ALLOW_EXPIRED: error }`.
14
+ - **`vat audit` is now advisory.** Audit always exits `0` regardless of validation severity, honors `validation.severity` for display grouping only, and ignores `validation.allow`. Use `vat skills validate` or `vat skills build` for gated checks with per-path allow entries.
15
15
 
16
16
  ### Added
17
- - **New validation codes** — `LINK_OUTSIDE_PROJECT`, `LINK_TARGETS_DIRECTORY`, `LINK_TO_NAVIGATION_FILE`, `LINK_TO_GITIGNORED_FILE`, `LINK_MISSING_TARGET`, `LINK_TO_SKILL_DEFINITION`, `LINK_DROPPED_BY_DEPTH`, `ACCEPTANCE_EXPIRED`, `ACCEPTANCE_UNUSED`. Full reference at `docs/validation-codes.md` with defaults, descriptions, and fix hints. `LINK_TO_SKILL_DEFINITION` fires only for cross-skill SKILL.md references; transitive self-references (a bundled resource linking back to the skill's own SKILL.md) are treated as no-ops.
17
+ - **New validation codes** — `LINK_OUTSIDE_PROJECT`, `LINK_TARGETS_DIRECTORY`, `LINK_TO_NAVIGATION_FILE`, `LINK_TO_GITIGNORED_FILE`, `LINK_MISSING_TARGET`, `LINK_TO_SKILL_DEFINITION`, `LINK_DROPPED_BY_DEPTH`, `ALLOW_EXPIRED`, `ALLOW_UNUSED`. Full reference at `docs/validation-codes.md` with defaults, descriptions, and fix hints. `LINK_TO_SKILL_DEFINITION` fires only for cross-skill SKILL.md references; transitive self-references (a bundled resource linking back to the skill's own SKILL.md) are treated as no-ops.
18
18
  - **`LINK_MISSING_TARGET`** closes a previously silent walker drop path: links to non-existent (non-deferred) files are now reported at the walker with a clear message, rather than only surfacing post-build as a generic `PACKAGED_BROKEN_LINK`.
19
- - **`ACCEPTANCE_UNUSED`** — analogous to ESLint's unused-disable — surfaces `accept` entries that match no emitted issues.
20
- - **Per-path `validation.accept`** with required `reason` and optional `expires` date, providing an audit trail for legitimate exceptions.
19
+ - **`ALLOW_UNUSED`** — analogous to ESLint's unused-disable — surfaces `allow` entries that match no emitted issues.
20
+ - **Per-path `validation.allow`** with required `reason` and optional `expires` date, providing an audit trail for legitimate exceptions. `paths` is optional and defaults to `["**/*"]` (the whole skill) — so concerns that apply to an entire skill can omit the paths array entirely.
21
21
  - **Canonical code reference** at `docs/validation-codes.md`, test-locked against the code registry so new codes cannot ship without documentation.
22
22
 
23
23
  ### Migration
@@ -25,7 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
25
25
  | Old | New |
26
26
  |---|---|
27
27
  | `ignoreValidationErrors: { CODE: "reason" }` | `validation.severity: { CODE: ignore }` |
28
- | `ignoreValidationErrors: { CODE: { reason, expires } }` | `validation.severity: { CODE: ignore }` for code-wide silence, OR `validation.accept: { CODE: [{ paths, reason, expires }] }` for scoped acceptance with re-review on expiry |
28
+ | `ignoreValidationErrors: { CODE: { reason, expires } }` | `validation.severity: { CODE: ignore }` for code-wide silence, OR `validation.allow: { CODE: [{ paths, reason, expires }] }` for scoped allow entries with re-review on expiry |
29
29
 
30
30
  ## [0.1.29] - 2026-04-16
31
31
 
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "vibe-agent-toolkit",
3
3
  "description": "Development agents and skills for building with vibe-agent-toolkit",
4
- "version": "0.1.30-rc.1",
4
+ "version": "0.1.30-rc.2",
5
5
  "author": {
6
6
  "name": "vibe-agent-toolkit contributors"
7
7
  }
@@ -74,7 +74,7 @@ Use this before a release to determine which surfaces each plugin supports.
74
74
  - `0` — always, when the audit completes, regardless of errors or warnings in the report.
75
75
  - `2` — system error (path not found, permission denied, etc.) — the audit could not run.
76
76
 
77
- 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.accept` from config.
77
+ 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.
78
78
 
79
79
  ## CI Usage
80
80
 
@@ -102,7 +102,7 @@ Severity taxonomy in audit output:
102
102
 
103
103
  Audit always exits `0` regardless — surface-level severity drives display grouping only.
104
104
 
105
- **Hiding codes from audit output.** Audit ignores `validation.accept` 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:
105
+ **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:
106
106
 
107
107
  ```yaml
108
108
  skills:
@@ -113,4 +113,4 @@ skills:
113
113
  LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output
114
114
  ```
115
115
 
116
- **Per-instance acceptance.** For per-path suppression with an audit trail, use `validation.accept` and run `vat skills validate` or `vat skills build` — those commands apply `accept` and gate the build. See `docs/validation-codes.md` for the full code reference and the VAT agent-authoring skill for configuration patterns.
116
+ **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.
@@ -298,7 +298,7 @@ Use `stripPrefix` to remove a common directory prefix (e.g., `"knowledge-base"`)
298
298
  | `{{link.resource.fileName}}` | Target filename (if resolved) |
299
299
  | `{{skill.name}}` | Skill name from frontmatter |
300
300
 
301
- **`validation`** — Unified framework for overriding default severity and accepting specific issue instances:
301
+ **`validation`** — Unified framework for overriding default severity and allowing specific issue instances:
302
302
 
303
303
  ```yaml
304
304
  # In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>
@@ -306,27 +306,29 @@ validation:
306
306
  severity:
307
307
  LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links
308
308
  LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs
309
- accept:
309
+ allow:
310
310
  PACKAGED_UNREFERENCED_FILE:
311
311
  - paths: ["templates/runtime.json"]
312
312
  reason: "consumed programmatically at runtime"
313
313
  expires: "2026-09-30"
314
+ SKILL_LENGTH_EXCEEDS_RECOMMENDED:
315
+ - reason: "whole-skill concern; paths defaults to ['**/*']"
314
316
  ```
315
317
 
316
318
  Two sub-keys, each covering a different override granularity:
317
319
 
318
320
  - **`severity`** — Class-level. Raise any code to `error` (blocks build), lower to `warning` (emits, non-blocking), or `ignore` (fully suppressed). Applies to every instance of that code.
319
- - **`accept`** — Per-instance. Suppress specific `(code, path)` matches with a required `reason` and optional `expires` date. Use for legitimate exceptions that don't warrant code-wide silencing.
321
+ - **`allow`** — Per-instance. Suppress specific `(code, path)` matches with a required `reason` and optional `expires` date. `paths` is optional (defaults to `["**/*"]` — the whole skill). Use for legitimate exceptions that don't warrant code-wide silencing.
320
322
 
321
323
  Things adopters typically adjust:
322
324
 
323
325
  - Downgrade `LINK_DROPPED_BY_DEPTH` to `ignore` when intentionally linking out to external docs.
324
- - Accept specific files under `PACKAGED_UNREFERENCED_FILE` when they're consumed programmatically by CLI scripts at runtime.
325
- - Raise `ACCEPTANCE_EXPIRED` to `error` for zero-tolerance expiry policies.
326
+ - Allow specific files under `PACKAGED_UNREFERENCED_FILE` when they're consumed programmatically by CLI scripts at runtime.
327
+ - Raise `ALLOW_EXPIRED` to `error` for zero-tolerance expiry policies.
326
328
 
327
- Expired `accept` entries still apply — VAT emits `ACCEPTANCE_EXPIRED` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused `accept` entries surface as `ACCEPTANCE_UNUSED` (analogous to ESLint's unused-disable).
329
+ Expired `allow` entries still apply — VAT emits `ALLOW_EXPIRED` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused `allow` entries surface as `ALLOW_UNUSED` (analogous to ESLint's unused-disable).
328
330
 
329
- Full code reference at `docs/validation-codes.md`. `vat audit` is advisory: it applies `severity` for display grouping only, ignores `accept`, and always exits 0. Use `vat skills validate` or `vat skills build` for gated checks.
331
+ Full code reference at `docs/validation-codes.md`. `vat audit` is advisory: it applies `severity` for display grouping only, ignores `allow`, and always exits 0. Use `vat skills validate` or `vat skills build` for gated checks.
330
332
 
331
333
  ## Testing Agents
332
334
 
@@ -7,7 +7,7 @@ export const meta = {
7
7
  description: "Use when authoring SKILL.md files, designing agent architectures, or configuring packaging options. Covers SKILL.md structure, agent archetypes, orchestration patterns, and validation override patterns."
8
8
  };
9
9
 
10
- export const text = "\n# VAT Agent Authoring: SKILL.md, Archetypes & Patterns\n\n## SKILL.md Structure\n\nA SKILL.md file is the definition file for a VAT agent skill. It tells Claude what the skill\ndoes and how to use it. All SKILL.md files must have YAML frontmatter:\n\n\`\`\`markdown\n---\nname: my-skill\ndescription: One sentence: what this skill does and when to use it (max 200 chars)\n---\n\n# My Skill\n\nRest of the skill documentation...\n\`\`\`\n\nRequired frontmatter fields:\n- \`name\` — unique identifier, kebab-case, matches the skill\'s directory name\n- \`description\` — trigger description used for skill routing; be specific about activation conditions\n\nBest practices for \`description\`:\n- Start with \"Use when...\" to make activation conditions explicit\n- Include the key commands or concepts the skill covers\n- Keep under 200 characters\n\n## Agent Archetypes\n\nVAT supports four agent archetypes for different use cases.\n\n### Archetype 1: Pure Function Tool\n\n**When to use:** Stateless validation, transformation, computation — no LLM needed.\n\n**Characteristics:** Deterministic output, fast execution, easy to test.\n\n**Example use cases:** Input validation, data transformation, format conversion, rules-based logic.\n\n\`\`\`typescript\nexport async function validateInput(input: MyInput): Promise<ValidationResult> {\n if (input.text.length < 5) {\n return { status: \'error\', error: \'too-short\' };\n }\n return { status: \'success\', data: { valid: true } };\n}\n\`\`\`\n\n### Archetype 2: One-Shot LLM Analyzer\n\n**When to use:** Single LLM call for analysis, classification, or generation.\n\n**Characteristics:** One LLM call per execution, stateless, handles LLM errors.\n\n**Example use cases:** Sentiment analysis, text classification, entity extraction, creative generation.\n\n\`\`\`typescript\nexport async function analyzeSentiment(text: string, context: AgentContext) {\n const response = await context.callLLM([\n { role: \'user\', content: \`Analyze sentiment: \"${text}\"\` }\n ]);\n\n const parsed = JSON.parse(response);\n return { status: \'success\', data: parsed };\n}\n\`\`\`\n\n### Archetype 3: Conversational Assistant\n\n**When to use:** Multi-turn dialogue, progressive data collection across sessions.\n\n**Characteristics:** Multiple LLM calls, maintains session state, phases (gathering → ready → complete).\n\n**Example use cases:** Customer support chatbots, product advisors, interview agents, multi-step forms.\n\n\`\`\`typescript\nexport async function conversationalAgent(\n message: string,\n sessionState: SessionState\n) {\n if (sessionState.phase === \'gathering\') {\n return {\n reply: \"Can you tell me more about X?\",\n sessionState: { ...sessionState },\n result: { status: \'in-progress\' }\n };\n }\n\n return {\n reply: \"Here\'s your result!\",\n sessionState: { ...sessionState, phase: \'complete\' },\n result: { status: \'success\', data: finalResult }\n };\n}\n\`\`\`\n\n### Archetype 4: External Event Integrator\n\n**When to use:** Waiting for external events (approvals, webhooks, third-party APIs).\n\n**Characteristics:** Emits event, blocks waiting for response, timeout handling, mockable for testing.\n\n**Example use cases:** Human-in-the-loop approval, webhook integrations, external API polling.\n\n\`\`\`typescript\nexport async function humanApproval(\n request: ApprovalRequest,\n options = { mockable: true, timeout: 30000 }\n) {\n if (options.mockable) {\n return { status: \'success\', data: { approved: true } };\n }\n\n const response = await emitEvent(request, options.timeout);\n return { status: \'success\', data: response };\n}\n\`\`\`\n\n## Result Envelopes\n\nAlways return result envelopes — never throw exceptions for expected errors.\n\n\`\`\`typescript\n// AgentResult<TData, TError> — for single-execution agents\ntype AgentResult<TData, TError> =\n | { status: \'success\'; data: TData }\n | { status: \'error\'; error: TError };\n\n// StatefulAgentResult — for conversational agents\ntype StatefulAgentResult<TData, TError, TMetadata> =\n | { status: \'in-progress\'; metadata?: TMetadata }\n | { status: \'success\'; data: TData }\n | { status: \'error\'; error: TError };\n\`\`\`\n\nStandard LLM error literals: \`\'llm-refusal\'\`, \`\'llm-invalid-output\'\`, \`\'llm-timeout\'\`,\n\`\'llm-rate-limit\'\`, \`\'llm-token-limit\'\`, \`\'llm-unavailable\'\`.\n\nAlways check status before accessing data:\n\`\`\`typescript\nconst output = await myAgent.execute(input);\nif (output.result.status === \'success\') {\n console.log(output.result.data);\n} else if (output.result.status === \'error\') {\n console.error(\'Failed:\', output.result.error);\n}\n\`\`\`\n\n## Orchestration Patterns\n\n### Sequential Pipeline\n\n\`\`\`typescript\nconst analysisOutput = await analyzer.execute(input);\nconst processedOutput = await andThen(\n analysisOutput.result,\n async (data) => {\n const out = await processor.execute(data);\n return out.result;\n }\n);\n\`\`\`\n\n### Parallel Execution\n\n\`\`\`typescript\nconst [output1, output2, output3] = await Promise.all([\n agent1.execute(input),\n agent2.execute(input),\n agent3.execute(input),\n]);\n\`\`\`\n\n### Validation Loop (Generate + Validate with Retry)\n\n\`\`\`typescript\nasync function generateValidOutput(input: MyInput, maxAttempts = 5) {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const generatorOutput = await generator.execute(input);\n if (generatorOutput.result.status === \'error\') continue;\n\n const validatorOutput = await validator.execute(generatorOutput.result.data);\n if (validatorOutput.result.status === \'success\' &&\n validatorOutput.result.data.valid) {\n return generatorOutput.result.data;\n }\n }\n throw new Error(\'Max attempts exceeded\');\n}\n\`\`\`\n\n### Human-in-the-Loop\n\n\`\`\`typescript\nconst generatorOutput = await generator.execute(input);\nif (generatorOutput.result.status === \'success\') {\n const approvalOutput = await humanApproval.execute({\n content: generatorOutput.result.data,\n context: input,\n });\n if (approvalOutput.result.data.approved) {\n return generatorOutput.result.data;\n }\n}\n\`\`\`\n\n### Conversational Multi-Turn\n\n\`\`\`typescript\nlet session = { state: { phase: \'gathering\' }, history: [] };\n\nwhile (true) {\n const userMessage = await getUserInput();\n const output = await conversationalAgent.execute({\n message: userMessage,\n sessionState: session.state,\n });\n\n console.log(\'Agent:\', output.reply);\n session = {\n state: output.sessionState,\n history: [...session.history,\n { role: \'user\', content: userMessage },\n { role: \'assistant\', content: output.reply }\n ],\n };\n\n if (output.result.status === \'success\') break;\n if (output.result.status === \'error\') break;\n // status === \'in-progress\': continue\n}\n\`\`\`\n\n## packagingOptions Reference\n\nConfigure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\n\`\`\`\n\n**\`linkFollowDepth\`** — How deep to follow links from SKILL.md:\n\n| Value | Behavior |\n|-------|----------|\n| \`0\` | Skill file only (no links followed) |\n| \`1\` | Direct links only |\n| \`2\` | Direct + one transitive level **(default)** |\n| \`\"full\"\` | Complete transitive closure |\n\n**\`resourceNaming\`** — How bundled files are named:\n\n| Strategy | Example | Use When |\n|----------|---------|----------|\n| \`basename\` | \`overview.md\` | Few files, unique names **(default)** |\n| \`resource-id\` | \`topics-quickstart-overview.md\` | Many files, flat output |\n| \`preserve-path\` | \`topics/quickstart/overview.md\` | Preserve structure |\n\nUse \`stripPrefix\` to remove a common directory prefix (e.g., \`\"knowledge-base\"\`).\n\n**\`excludeReferencesFromBundle\`** — Rules for excluding files and rewriting their links:\n- \`rules[]\` — Ordered glob patterns (first match wins), each with optional Handlebars template\n- \`defaultTemplate\` — Applied to depth-exceeded links not matching any rule\n\n**Template variables:**\n\n| Variable | Description |\n|----------|-------------|\n| \`{{link.text}}\` | Link display text |\n| \`{{link.href}}\` | Original href (without fragment) |\n| \`{{link.fragment}}\` | Fragment including \`#\` prefix, or empty |\n| \`{{link.type}}\` | Link type (\`\"local_file\"\`, etc.) |\n| \`{{link.resource.id}}\` | Target resource ID (if resolved) |\n| \`{{link.resource.fileName}}\` | Target filename (if resolved) |\n| \`{{skill.name}}\` | Skill name from frontmatter |\n\n**\`validation\`** — Unified framework for overriding default severity and accepting specific issue instances:\n\n\`\`\`yaml\n# In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>\nvalidation:\n severity:\n LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links\n LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs\n accept:\n PACKAGED_UNREFERENCED_FILE:\n - paths: [\"templates/runtime.json\"]\n reason: \"consumed programmatically at runtime\"\n expires: \"2026-09-30\"\n\`\`\`\n\nTwo sub-keys, each covering a different override granularity:\n\n- **\`severity\`** — Class-level. Raise any code to \`error\` (blocks build), lower to \`warning\` (emits, non-blocking), or \`ignore\` (fully suppressed). Applies to every instance of that code.\n- **\`accept\`** — Per-instance. Suppress specific \`(code, path)\` matches with a required \`reason\` and optional \`expires\` date. Use for legitimate exceptions that don\'t warrant code-wide silencing.\n\nThings adopters typically adjust:\n\n- Downgrade \`LINK_DROPPED_BY_DEPTH\` to \`ignore\` when intentionally linking out to external docs.\n- Accept specific files under \`PACKAGED_UNREFERENCED_FILE\` when they\'re consumed programmatically by CLI scripts at runtime.\n- Raise \`ACCEPTANCE_EXPIRED\` to \`error\` for zero-tolerance expiry policies.\n\nExpired \`accept\` entries still apply — VAT emits \`ACCEPTANCE_EXPIRED\` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused \`accept\` entries surface as \`ACCEPTANCE_UNUSED\` (analogous to ESLint\'s unused-disable).\n\nFull code reference at \`docs/validation-codes.md\`. \`vat audit\` is advisory: it applies \`severity\` for display grouping only, ignores \`accept\`, and always exits 0. Use \`vat skills validate\` or \`vat skills build\` for gated checks.\n\n## Testing Agents\n\n### Unit Testing Pure Functions\n\n\`\`\`typescript\nimport { describe, expect, it } from \'vitest\';\nimport { resultMatchers } from \'@vibe-agent-toolkit/agent-runtime\';\n\ndescribe(\'myValidator\', () => {\n it(\'should validate correct input\', async () => {\n const output = await myValidator.execute({ text: \'valid\' });\n resultMatchers.expectSuccess(output.result);\n expect(output.result.data.valid).toBe(true);\n });\n});\n\`\`\`\n\n### Integration Testing with Mock LLM\n\n\`\`\`typescript\nimport { createMockContext } from \'@vibe-agent-toolkit/agent-runtime\';\n\nconst mockContext = createMockContext(\n JSON.stringify({ sentiment: \'positive\', confidence: 0.9 })\n);\nconst output = await myAnalyzer.execute({ text: \'Great!\' }, mockContext);\nresultMatchers.expectSuccess(output.result);\n\`\`\`\n\n### Testing Conversational Flows\n\n\`\`\`typescript\n// Turn 1\nconst output1 = await agent.execute({ message: \'Hello\' });\nexpect(output1.reply).toContain(\'name?\');\nresultMatchers.expectInProgress(output1.result);\n\n// Turn 2 — pass session state forward\nconst output2 = await agent.execute({\n message: \'My name is Alice\',\n sessionState: output1.sessionState,\n});\n\`\`\`\n\n## Best Practices\n\n1. **Return result envelopes, never throw** for expected errors\n2. **Define error types as literal unions** (\`\'invalid-format\' | \'timeout\'\`) not \`string\`\n3. **Use Zod schemas** for all input/output validation\n4. **Test all paths** — success, each error type, edge cases\n5. **Use mock mode** for external dependencies to enable offline testing\n6. **Document with JSDoc** — purpose, params, return type, example, \`@throws Never throws\`\n7. **Keep SKILL.md focused** — if it exceeds ~300 lines, split into action skills\n\n## References\n\n- [Skill Quality Checklist](skill-quality-checklist.md) — Pre-publication checklist for all skills (general + CLI-backed)\n- [agent-authoring.md](../../../../docs/agent-authoring.md) — Complete patterns guide\n- [orchestration.md](../../../../docs/orchestration.md) — Multi-agent workflows\n- [Building Effective Agents - Anthropic](https://www.anthropic.com/research/building-effective-agents)\n";
10
+ export const text = "\n# VAT Agent Authoring: SKILL.md, Archetypes & Patterns\n\n## SKILL.md Structure\n\nA SKILL.md file is the definition file for a VAT agent skill. It tells Claude what the skill\ndoes and how to use it. All SKILL.md files must have YAML frontmatter:\n\n\`\`\`markdown\n---\nname: my-skill\ndescription: One sentence: what this skill does and when to use it (max 200 chars)\n---\n\n# My Skill\n\nRest of the skill documentation...\n\`\`\`\n\nRequired frontmatter fields:\n- \`name\` — unique identifier, kebab-case, matches the skill\'s directory name\n- \`description\` — trigger description used for skill routing; be specific about activation conditions\n\nBest practices for \`description\`:\n- Start with \"Use when...\" to make activation conditions explicit\n- Include the key commands or concepts the skill covers\n- Keep under 200 characters\n\n## Agent Archetypes\n\nVAT supports four agent archetypes for different use cases.\n\n### Archetype 1: Pure Function Tool\n\n**When to use:** Stateless validation, transformation, computation — no LLM needed.\n\n**Characteristics:** Deterministic output, fast execution, easy to test.\n\n**Example use cases:** Input validation, data transformation, format conversion, rules-based logic.\n\n\`\`\`typescript\nexport async function validateInput(input: MyInput): Promise<ValidationResult> {\n if (input.text.length < 5) {\n return { status: \'error\', error: \'too-short\' };\n }\n return { status: \'success\', data: { valid: true } };\n}\n\`\`\`\n\n### Archetype 2: One-Shot LLM Analyzer\n\n**When to use:** Single LLM call for analysis, classification, or generation.\n\n**Characteristics:** One LLM call per execution, stateless, handles LLM errors.\n\n**Example use cases:** Sentiment analysis, text classification, entity extraction, creative generation.\n\n\`\`\`typescript\nexport async function analyzeSentiment(text: string, context: AgentContext) {\n const response = await context.callLLM([\n { role: \'user\', content: \`Analyze sentiment: \"${text}\"\` }\n ]);\n\n const parsed = JSON.parse(response);\n return { status: \'success\', data: parsed };\n}\n\`\`\`\n\n### Archetype 3: Conversational Assistant\n\n**When to use:** Multi-turn dialogue, progressive data collection across sessions.\n\n**Characteristics:** Multiple LLM calls, maintains session state, phases (gathering → ready → complete).\n\n**Example use cases:** Customer support chatbots, product advisors, interview agents, multi-step forms.\n\n\`\`\`typescript\nexport async function conversationalAgent(\n message: string,\n sessionState: SessionState\n) {\n if (sessionState.phase === \'gathering\') {\n return {\n reply: \"Can you tell me more about X?\",\n sessionState: { ...sessionState },\n result: { status: \'in-progress\' }\n };\n }\n\n return {\n reply: \"Here\'s your result!\",\n sessionState: { ...sessionState, phase: \'complete\' },\n result: { status: \'success\', data: finalResult }\n };\n}\n\`\`\`\n\n### Archetype 4: External Event Integrator\n\n**When to use:** Waiting for external events (approvals, webhooks, third-party APIs).\n\n**Characteristics:** Emits event, blocks waiting for response, timeout handling, mockable for testing.\n\n**Example use cases:** Human-in-the-loop approval, webhook integrations, external API polling.\n\n\`\`\`typescript\nexport async function humanApproval(\n request: ApprovalRequest,\n options = { mockable: true, timeout: 30000 }\n) {\n if (options.mockable) {\n return { status: \'success\', data: { approved: true } };\n }\n\n const response = await emitEvent(request, options.timeout);\n return { status: \'success\', data: response };\n}\n\`\`\`\n\n## Result Envelopes\n\nAlways return result envelopes — never throw exceptions for expected errors.\n\n\`\`\`typescript\n// AgentResult<TData, TError> — for single-execution agents\ntype AgentResult<TData, TError> =\n | { status: \'success\'; data: TData }\n | { status: \'error\'; error: TError };\n\n// StatefulAgentResult — for conversational agents\ntype StatefulAgentResult<TData, TError, TMetadata> =\n | { status: \'in-progress\'; metadata?: TMetadata }\n | { status: \'success\'; data: TData }\n | { status: \'error\'; error: TError };\n\`\`\`\n\nStandard LLM error literals: \`\'llm-refusal\'\`, \`\'llm-invalid-output\'\`, \`\'llm-timeout\'\`,\n\`\'llm-rate-limit\'\`, \`\'llm-token-limit\'\`, \`\'llm-unavailable\'\`.\n\nAlways check status before accessing data:\n\`\`\`typescript\nconst output = await myAgent.execute(input);\nif (output.result.status === \'success\') {\n console.log(output.result.data);\n} else if (output.result.status === \'error\') {\n console.error(\'Failed:\', output.result.error);\n}\n\`\`\`\n\n## Orchestration Patterns\n\n### Sequential Pipeline\n\n\`\`\`typescript\nconst analysisOutput = await analyzer.execute(input);\nconst processedOutput = await andThen(\n analysisOutput.result,\n async (data) => {\n const out = await processor.execute(data);\n return out.result;\n }\n);\n\`\`\`\n\n### Parallel Execution\n\n\`\`\`typescript\nconst [output1, output2, output3] = await Promise.all([\n agent1.execute(input),\n agent2.execute(input),\n agent3.execute(input),\n]);\n\`\`\`\n\n### Validation Loop (Generate + Validate with Retry)\n\n\`\`\`typescript\nasync function generateValidOutput(input: MyInput, maxAttempts = 5) {\n for (let attempt = 0; attempt < maxAttempts; attempt++) {\n const generatorOutput = await generator.execute(input);\n if (generatorOutput.result.status === \'error\') continue;\n\n const validatorOutput = await validator.execute(generatorOutput.result.data);\n if (validatorOutput.result.status === \'success\' &&\n validatorOutput.result.data.valid) {\n return generatorOutput.result.data;\n }\n }\n throw new Error(\'Max attempts exceeded\');\n}\n\`\`\`\n\n### Human-in-the-Loop\n\n\`\`\`typescript\nconst generatorOutput = await generator.execute(input);\nif (generatorOutput.result.status === \'success\') {\n const approvalOutput = await humanApproval.execute({\n content: generatorOutput.result.data,\n context: input,\n });\n if (approvalOutput.result.data.approved) {\n return generatorOutput.result.data;\n }\n}\n\`\`\`\n\n### Conversational Multi-Turn\n\n\`\`\`typescript\nlet session = { state: { phase: \'gathering\' }, history: [] };\n\nwhile (true) {\n const userMessage = await getUserInput();\n const output = await conversationalAgent.execute({\n message: userMessage,\n sessionState: session.state,\n });\n\n console.log(\'Agent:\', output.reply);\n session = {\n state: output.sessionState,\n history: [...session.history,\n { role: \'user\', content: userMessage },\n { role: \'assistant\', content: output.reply }\n ],\n };\n\n if (output.result.status === \'success\') break;\n if (output.result.status === \'error\') break;\n // status === \'in-progress\': continue\n}\n\`\`\`\n\n## packagingOptions Reference\n\nConfigure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\n\`\`\`\n\n**\`linkFollowDepth\`** — How deep to follow links from SKILL.md:\n\n| Value | Behavior |\n|-------|----------|\n| \`0\` | Skill file only (no links followed) |\n| \`1\` | Direct links only |\n| \`2\` | Direct + one transitive level **(default)** |\n| \`\"full\"\` | Complete transitive closure |\n\n**\`resourceNaming\`** — How bundled files are named:\n\n| Strategy | Example | Use When |\n|----------|---------|----------|\n| \`basename\` | \`overview.md\` | Few files, unique names **(default)** |\n| \`resource-id\` | \`topics-quickstart-overview.md\` | Many files, flat output |\n| \`preserve-path\` | \`topics/quickstart/overview.md\` | Preserve structure |\n\nUse \`stripPrefix\` to remove a common directory prefix (e.g., \`\"knowledge-base\"\`).\n\n**\`excludeReferencesFromBundle\`** — Rules for excluding files and rewriting their links:\n- \`rules[]\` — Ordered glob patterns (first match wins), each with optional Handlebars template\n- \`defaultTemplate\` — Applied to depth-exceeded links not matching any rule\n\n**Template variables:**\n\n| Variable | Description |\n|----------|-------------|\n| \`{{link.text}}\` | Link display text |\n| \`{{link.href}}\` | Original href (without fragment) |\n| \`{{link.fragment}}\` | Fragment including \`#\` prefix, or empty |\n| \`{{link.type}}\` | Link type (\`\"local_file\"\`, etc.) |\n| \`{{link.resource.id}}\` | Target resource ID (if resolved) |\n| \`{{link.resource.fileName}}\` | Target filename (if resolved) |\n| \`{{skill.name}}\` | Skill name from frontmatter |\n\n**\`validation\`** — Unified framework for overriding default severity and allowing specific issue instances:\n\n\`\`\`yaml\n# In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>\nvalidation:\n severity:\n LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links\n LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs\n allow:\n PACKAGED_UNREFERENCED_FILE:\n - paths: [\"templates/runtime.json\"]\n reason: \"consumed programmatically at runtime\"\n expires: \"2026-09-30\"\n SKILL_LENGTH_EXCEEDS_RECOMMENDED:\n - reason: \"whole-skill concern; paths defaults to [\'**/*\']\"\n\`\`\`\n\nTwo sub-keys, each covering a different override granularity:\n\n- **\`severity\`** — Class-level. Raise any code to \`error\` (blocks build), lower to \`warning\` (emits, non-blocking), or \`ignore\` (fully suppressed). Applies to every instance of that code.\n- **\`allow\`** — Per-instance. Suppress specific \`(code, path)\` matches with a required \`reason\` and optional \`expires\` date. \`paths\` is optional (defaults to \`[\"**/*\"]\` — the whole skill). Use for legitimate exceptions that don\'t warrant code-wide silencing.\n\nThings adopters typically adjust:\n\n- Downgrade \`LINK_DROPPED_BY_DEPTH\` to \`ignore\` when intentionally linking out to external docs.\n- Allow specific files under \`PACKAGED_UNREFERENCED_FILE\` when they\'re consumed programmatically by CLI scripts at runtime.\n- Raise \`ALLOW_EXPIRED\` to \`error\` for zero-tolerance expiry policies.\n\nExpired \`allow\` entries still apply — VAT emits \`ALLOW_EXPIRED\` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused \`allow\` entries surface as \`ALLOW_UNUSED\` (analogous to ESLint\'s unused-disable).\n\nFull code reference at \`docs/validation-codes.md\`. \`vat audit\` is advisory: it applies \`severity\` for display grouping only, ignores \`allow\`, and always exits 0. Use \`vat skills validate\` or \`vat skills build\` for gated checks.\n\n## Testing Agents\n\n### Unit Testing Pure Functions\n\n\`\`\`typescript\nimport { describe, expect, it } from \'vitest\';\nimport { resultMatchers } from \'@vibe-agent-toolkit/agent-runtime\';\n\ndescribe(\'myValidator\', () => {\n it(\'should validate correct input\', async () => {\n const output = await myValidator.execute({ text: \'valid\' });\n resultMatchers.expectSuccess(output.result);\n expect(output.result.data.valid).toBe(true);\n });\n});\n\`\`\`\n\n### Integration Testing with Mock LLM\n\n\`\`\`typescript\nimport { createMockContext } from \'@vibe-agent-toolkit/agent-runtime\';\n\nconst mockContext = createMockContext(\n JSON.stringify({ sentiment: \'positive\', confidence: 0.9 })\n);\nconst output = await myAnalyzer.execute({ text: \'Great!\' }, mockContext);\nresultMatchers.expectSuccess(output.result);\n\`\`\`\n\n### Testing Conversational Flows\n\n\`\`\`typescript\n// Turn 1\nconst output1 = await agent.execute({ message: \'Hello\' });\nexpect(output1.reply).toContain(\'name?\');\nresultMatchers.expectInProgress(output1.result);\n\n// Turn 2 — pass session state forward\nconst output2 = await agent.execute({\n message: \'My name is Alice\',\n sessionState: output1.sessionState,\n});\n\`\`\`\n\n## Best Practices\n\n1. **Return result envelopes, never throw** for expected errors\n2. **Define error types as literal unions** (\`\'invalid-format\' | \'timeout\'\`) not \`string\`\n3. **Use Zod schemas** for all input/output validation\n4. **Test all paths** — success, each error type, edge cases\n5. **Use mock mode** for external dependencies to enable offline testing\n6. **Document with JSDoc** — purpose, params, return type, example, \`@throws Never throws\`\n7. **Keep SKILL.md focused** — if it exceeds ~300 lines, split into action skills\n\n## References\n\n- [Skill Quality Checklist](skill-quality-checklist.md) — Pre-publication checklist for all skills (general + CLI-backed)\n- [agent-authoring.md](../../../../docs/agent-authoring.md) — Complete patterns guide\n- [orchestration.md](../../../../docs/orchestration.md) — Multi-agent workflows\n- [Building Effective Agents - Anthropic](https://www.anthropic.com/research/building-effective-agents)\n";
11
11
 
12
12
  export const fragments = {
13
13
  skillmdStructure: {
@@ -32,8 +32,8 @@ export const fragments = {
32
32
  },
33
33
  packagingoptionsReference: {
34
34
  header: "## packagingOptions Reference",
35
- body: "Configure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\n\`\`\`\n\n**\`linkFollowDepth\`** — How deep to follow links from SKILL.md:\n\n| Value | Behavior |\n|-------|----------|\n| \`0\` | Skill file only (no links followed) |\n| \`1\` | Direct links only |\n| \`2\` | Direct + one transitive level **(default)** |\n| \`\"full\"\` | Complete transitive closure |\n\n**\`resourceNaming\`** — How bundled files are named:\n\n| Strategy | Example | Use When |\n|----------|---------|----------|\n| \`basename\` | \`overview.md\` | Few files, unique names **(default)** |\n| \`resource-id\` | \`topics-quickstart-overview.md\` | Many files, flat output |\n| \`preserve-path\` | \`topics/quickstart/overview.md\` | Preserve structure |\n\nUse \`stripPrefix\` to remove a common directory prefix (e.g., \`\"knowledge-base\"\`).\n\n**\`excludeReferencesFromBundle\`** — Rules for excluding files and rewriting their links:\n- \`rules[]\` — Ordered glob patterns (first match wins), each with optional Handlebars template\n- \`defaultTemplate\` — Applied to depth-exceeded links not matching any rule\n\n**Template variables:**\n\n| Variable | Description |\n|----------|-------------|\n| \`{{link.text}}\` | Link display text |\n| \`{{link.href}}\` | Original href (without fragment) |\n| \`{{link.fragment}}\` | Fragment including \`#\` prefix, or empty |\n| \`{{link.type}}\` | Link type (\`\"local_file\"\`, etc.) |\n| \`{{link.resource.id}}\` | Target resource ID (if resolved) |\n| \`{{link.resource.fileName}}\` | Target filename (if resolved) |\n| \`{{skill.name}}\` | Skill name from frontmatter |\n\n**\`validation\`** — Unified framework for overriding default severity and accepting specific issue instances:\n\n\`\`\`yaml\n# In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>\nvalidation:\n severity:\n LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links\n LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs\n accept:\n PACKAGED_UNREFERENCED_FILE:\n - paths: [\"templates/runtime.json\"]\n reason: \"consumed programmatically at runtime\"\n expires: \"2026-09-30\"\n\`\`\`\n\nTwo sub-keys, each covering a different override granularity:\n\n- **\`severity\`** — Class-level. Raise any code to \`error\` (blocks build), lower to \`warning\` (emits, non-blocking), or \`ignore\` (fully suppressed). Applies to every instance of that code.\n- **\`accept\`** — Per-instance. Suppress specific \`(code, path)\` matches with a required \`reason\` and optional \`expires\` date. Use for legitimate exceptions that don\'t warrant code-wide silencing.\n\nThings adopters typically adjust:\n\n- Downgrade \`LINK_DROPPED_BY_DEPTH\` to \`ignore\` when intentionally linking out to external docs.\n- Accept specific files under \`PACKAGED_UNREFERENCED_FILE\` when they\'re consumed programmatically by CLI scripts at runtime.\n- Raise \`ACCEPTANCE_EXPIRED\` to \`error\` for zero-tolerance expiry policies.\n\nExpired \`accept\` entries still apply — VAT emits \`ACCEPTANCE_EXPIRED\` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused \`accept\` entries surface as \`ACCEPTANCE_UNUSED\` (analogous to ESLint\'s unused-disable).\n\nFull code reference at \`docs/validation-codes.md\`. \`vat audit\` is advisory: it applies \`severity\` for display grouping only, ignores \`accept\`, and always exits 0. Use \`vat skills validate\` or \`vat skills build\` for gated checks.",
36
- text: "## packagingOptions Reference\n\nConfigure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\n\`\`\`\n\n**\`linkFollowDepth\`** — How deep to follow links from SKILL.md:\n\n| Value | Behavior |\n|-------|----------|\n| \`0\` | Skill file only (no links followed) |\n| \`1\` | Direct links only |\n| \`2\` | Direct + one transitive level **(default)** |\n| \`\"full\"\` | Complete transitive closure |\n\n**\`resourceNaming\`** — How bundled files are named:\n\n| Strategy | Example | Use When |\n|----------|---------|----------|\n| \`basename\` | \`overview.md\` | Few files, unique names **(default)** |\n| \`resource-id\` | \`topics-quickstart-overview.md\` | Many files, flat output |\n| \`preserve-path\` | \`topics/quickstart/overview.md\` | Preserve structure |\n\nUse \`stripPrefix\` to remove a common directory prefix (e.g., \`\"knowledge-base\"\`).\n\n**\`excludeReferencesFromBundle\`** — Rules for excluding files and rewriting their links:\n- \`rules[]\` — Ordered glob patterns (first match wins), each with optional Handlebars template\n- \`defaultTemplate\` — Applied to depth-exceeded links not matching any rule\n\n**Template variables:**\n\n| Variable | Description |\n|----------|-------------|\n| \`{{link.text}}\` | Link display text |\n| \`{{link.href}}\` | Original href (without fragment) |\n| \`{{link.fragment}}\` | Fragment including \`#\` prefix, or empty |\n| \`{{link.type}}\` | Link type (\`\"local_file\"\`, etc.) |\n| \`{{link.resource.id}}\` | Target resource ID (if resolved) |\n| \`{{link.resource.fileName}}\` | Target filename (if resolved) |\n| \`{{skill.name}}\` | Skill name from frontmatter |\n\n**\`validation\`** — Unified framework for overriding default severity and accepting specific issue instances:\n\n\`\`\`yaml\n# In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>\nvalidation:\n severity:\n LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links\n LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs\n accept:\n PACKAGED_UNREFERENCED_FILE:\n - paths: [\"templates/runtime.json\"]\n reason: \"consumed programmatically at runtime\"\n expires: \"2026-09-30\"\n\`\`\`\n\nTwo sub-keys, each covering a different override granularity:\n\n- **\`severity\`** — Class-level. Raise any code to \`error\` (blocks build), lower to \`warning\` (emits, non-blocking), or \`ignore\` (fully suppressed). Applies to every instance of that code.\n- **\`accept\`** — Per-instance. Suppress specific \`(code, path)\` matches with a required \`reason\` and optional \`expires\` date. Use for legitimate exceptions that don\'t warrant code-wide silencing.\n\nThings adopters typically adjust:\n\n- Downgrade \`LINK_DROPPED_BY_DEPTH\` to \`ignore\` when intentionally linking out to external docs.\n- Accept specific files under \`PACKAGED_UNREFERENCED_FILE\` when they\'re consumed programmatically by CLI scripts at runtime.\n- Raise \`ACCEPTANCE_EXPIRED\` to \`error\` for zero-tolerance expiry policies.\n\nExpired \`accept\` entries still apply — VAT emits \`ACCEPTANCE_EXPIRED\` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused \`accept\` entries surface as \`ACCEPTANCE_UNUSED\` (analogous to ESLint\'s unused-disable).\n\nFull code reference at \`docs/validation-codes.md\`. \`vat audit\` is advisory: it applies \`severity\` for display grouping only, ignores \`accept\`, and always exits 0. Use \`vat skills validate\` or \`vat skills build\` for gated checks."
35
+ body: "Configure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\n\`\`\`\n\n**\`linkFollowDepth\`** — How deep to follow links from SKILL.md:\n\n| Value | Behavior |\n|-------|----------|\n| \`0\` | Skill file only (no links followed) |\n| \`1\` | Direct links only |\n| \`2\` | Direct + one transitive level **(default)** |\n| \`\"full\"\` | Complete transitive closure |\n\n**\`resourceNaming\`** — How bundled files are named:\n\n| Strategy | Example | Use When |\n|----------|---------|----------|\n| \`basename\` | \`overview.md\` | Few files, unique names **(default)** |\n| \`resource-id\` | \`topics-quickstart-overview.md\` | Many files, flat output |\n| \`preserve-path\` | \`topics/quickstart/overview.md\` | Preserve structure |\n\nUse \`stripPrefix\` to remove a common directory prefix (e.g., \`\"knowledge-base\"\`).\n\n**\`excludeReferencesFromBundle\`** — Rules for excluding files and rewriting their links:\n- \`rules[]\` — Ordered glob patterns (first match wins), each with optional Handlebars template\n- \`defaultTemplate\` — Applied to depth-exceeded links not matching any rule\n\n**Template variables:**\n\n| Variable | Description |\n|----------|-------------|\n| \`{{link.text}}\` | Link display text |\n| \`{{link.href}}\` | Original href (without fragment) |\n| \`{{link.fragment}}\` | Fragment including \`#\` prefix, or empty |\n| \`{{link.type}}\` | Link type (\`\"local_file\"\`, etc.) |\n| \`{{link.resource.id}}\` | Target resource ID (if resolved) |\n| \`{{link.resource.fileName}}\` | Target filename (if resolved) |\n| \`{{skill.name}}\` | Skill name from frontmatter |\n\n**\`validation\`** — Unified framework for overriding default severity and allowing specific issue instances:\n\n\`\`\`yaml\n# In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>\nvalidation:\n severity:\n LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links\n LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs\n allow:\n PACKAGED_UNREFERENCED_FILE:\n - paths: [\"templates/runtime.json\"]\n reason: \"consumed programmatically at runtime\"\n expires: \"2026-09-30\"\n SKILL_LENGTH_EXCEEDS_RECOMMENDED:\n - reason: \"whole-skill concern; paths defaults to [\'**/*\']\"\n\`\`\`\n\nTwo sub-keys, each covering a different override granularity:\n\n- **\`severity\`** — Class-level. Raise any code to \`error\` (blocks build), lower to \`warning\` (emits, non-blocking), or \`ignore\` (fully suppressed). Applies to every instance of that code.\n- **\`allow\`** — Per-instance. Suppress specific \`(code, path)\` matches with a required \`reason\` and optional \`expires\` date. \`paths\` is optional (defaults to \`[\"**/*\"]\` — the whole skill). Use for legitimate exceptions that don\'t warrant code-wide silencing.\n\nThings adopters typically adjust:\n\n- Downgrade \`LINK_DROPPED_BY_DEPTH\` to \`ignore\` when intentionally linking out to external docs.\n- Allow specific files under \`PACKAGED_UNREFERENCED_FILE\` when they\'re consumed programmatically by CLI scripts at runtime.\n- Raise \`ALLOW_EXPIRED\` to \`error\` for zero-tolerance expiry policies.\n\nExpired \`allow\` entries still apply — VAT emits \`ALLOW_EXPIRED\` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused \`allow\` entries surface as \`ALLOW_UNUSED\` (analogous to ESLint\'s unused-disable).\n\nFull code reference at \`docs/validation-codes.md\`. \`vat audit\` is advisory: it applies \`severity\` for display grouping only, ignores \`allow\`, and always exits 0. Use \`vat skills validate\` or \`vat skills build\` for gated checks.",
36
+ text: "## packagingOptions Reference\n\nConfigure in your skill\'s \`vat.skills[]\` entry in \`package.json\`:\n\n\`\`\`json\n{\n \"vat\": {\n \"skills\": [{\n \"name\": \"my-skill\",\n \"source\": \"./SKILL.md\",\n \"path\": \"./dist/skills/my-skill\",\n \"packagingOptions\": {\n \"linkFollowDepth\": 1,\n \"resourceNaming\": \"resource-id\",\n \"stripPrefix\": \"knowledge-base\",\n \"excludeReferencesFromBundle\": {\n \"rules\": [\n { \"patterns\": [\"**/concepts/**\"], \"template\": \"Use search to find: {{link.text}}\" }\n ],\n \"defaultTemplate\": \"{{link.text}} (search knowledge base)\"\n }\n }\n }]\n }\n}\n\`\`\`\n\n**\`linkFollowDepth\`** — How deep to follow links from SKILL.md:\n\n| Value | Behavior |\n|-------|----------|\n| \`0\` | Skill file only (no links followed) |\n| \`1\` | Direct links only |\n| \`2\` | Direct + one transitive level **(default)** |\n| \`\"full\"\` | Complete transitive closure |\n\n**\`resourceNaming\`** — How bundled files are named:\n\n| Strategy | Example | Use When |\n|----------|---------|----------|\n| \`basename\` | \`overview.md\` | Few files, unique names **(default)** |\n| \`resource-id\` | \`topics-quickstart-overview.md\` | Many files, flat output |\n| \`preserve-path\` | \`topics/quickstart/overview.md\` | Preserve structure |\n\nUse \`stripPrefix\` to remove a common directory prefix (e.g., \`\"knowledge-base\"\`).\n\n**\`excludeReferencesFromBundle\`** — Rules for excluding files and rewriting their links:\n- \`rules[]\` — Ordered glob patterns (first match wins), each with optional Handlebars template\n- \`defaultTemplate\` — Applied to depth-exceeded links not matching any rule\n\n**Template variables:**\n\n| Variable | Description |\n|----------|-------------|\n| \`{{link.text}}\` | Link display text |\n| \`{{link.href}}\` | Original href (without fragment) |\n| \`{{link.fragment}}\` | Fragment including \`#\` prefix, or empty |\n| \`{{link.type}}\` | Link type (\`\"local_file\"\`, etc.) |\n| \`{{link.resource.id}}\` | Target resource ID (if resolved) |\n| \`{{link.resource.fileName}}\` | Target filename (if resolved) |\n| \`{{skill.name}}\` | Skill name from frontmatter |\n\n**\`validation\`** — Unified framework for overriding default severity and allowing specific issue instances:\n\n\`\`\`yaml\n# In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>\nvalidation:\n severity:\n LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links\n LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs\n allow:\n PACKAGED_UNREFERENCED_FILE:\n - paths: [\"templates/runtime.json\"]\n reason: \"consumed programmatically at runtime\"\n expires: \"2026-09-30\"\n SKILL_LENGTH_EXCEEDS_RECOMMENDED:\n - reason: \"whole-skill concern; paths defaults to [\'**/*\']\"\n\`\`\`\n\nTwo sub-keys, each covering a different override granularity:\n\n- **\`severity\`** — Class-level. Raise any code to \`error\` (blocks build), lower to \`warning\` (emits, non-blocking), or \`ignore\` (fully suppressed). Applies to every instance of that code.\n- **\`allow\`** — Per-instance. Suppress specific \`(code, path)\` matches with a required \`reason\` and optional \`expires\` date. \`paths\` is optional (defaults to \`[\"**/*\"]\` — the whole skill). Use for legitimate exceptions that don\'t warrant code-wide silencing.\n\nThings adopters typically adjust:\n\n- Downgrade \`LINK_DROPPED_BY_DEPTH\` to \`ignore\` when intentionally linking out to external docs.\n- Allow specific files under \`PACKAGED_UNREFERENCED_FILE\` when they\'re consumed programmatically by CLI scripts at runtime.\n- Raise \`ALLOW_EXPIRED\` to \`error\` for zero-tolerance expiry policies.\n\nExpired \`allow\` entries still apply — VAT emits \`ALLOW_EXPIRED\` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused \`allow\` entries surface as \`ALLOW_UNUSED\` (analogous to ESLint\'s unused-disable).\n\nFull code reference at \`docs/validation-codes.md\`. \`vat audit\` is advisory: it applies \`severity\` for display grouping only, ignores \`allow\`, and always exits 0. Use \`vat skills validate\` or \`vat skills build\` for gated checks."
37
37
  },
38
38
  testingAgents: {
39
39
  header: "## Testing Agents",
@@ -7,7 +7,7 @@ export const meta = {
7
7
  description: "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."
8
8
  };
9
9
 
10
- export const text = "\n# VAT Audit: Validating Plugins, Skills & Marketplaces\n\n## Running the Audit\n\n\`\`\`bash\n# Audit current directory (recursive by default)\nvat audit\n\n# Audit a specific directory\nvat audit ./plugins/\n\n# Audit your entire Claude installation\nvat audit --user\n\n# Exclude noisy directories\nvat audit --exclude \"dist/**\" --exclude \"node_modules/**\"\n\n# Verbose: show all resources, not just those with issues\nvat audit --verbose\n\n# Compatibility analysis: which Claude surfaces each plugin supports\nvat audit ./plugins/ --compat\n\`\`\`\n\n## What Gets Detected (Automatic)\n\nRunning \`vat audit <path>\` recursively walks the directory and auto-detects:\n\n| Found | Detected as |\n|---|---|\n| \`.claude-plugin/plugin.json\` in a dir | Claude Plugin |\n| \`.claude-plugin/marketplace.json\` in a dir | Claude Marketplace |\n| \`SKILL.md\` file | Agent Skill |\n| \`agent.yaml\` + \`SKILL.md\` | VAT Agent |\n| \`installed_plugins.json\` | Registry file |\n\nRecursion is the default — you do not need \`--recursive\`.\n\n## Compatibility Analysis (\`--compat\`)\n\n\`\`\`bash\nvat audit ./plugins/ --compat\n\`\`\`\n\nOutput per plugin:\n\`\`\`yaml\nplugin: mission-control\ncompatibility:\n claude-code:\n compatible: true\n evidence: []\n cowork:\n compatible: true\n evidence: []\n claude-desktop:\n compatible: false\n evidence:\n - type: python-script\n file: hooks-handlers/handler.py\n detail: Python execution not available in claude-desktop\n\`\`\`\n\nUse this before a release to determine which surfaces each plugin supports.\n\n## Exit Codes\n\n\`vat audit\` is **advisory** — it reports every issue it detects but never blocks on validation severity:\n\n- \`0\` — always, when the audit completes, regardless of errors or warnings in the report.\n- \`2\` — system error (path not found, permission denied, etc.) — the audit could not run.\n\nFor 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.accept\` from config.\n\n## CI Usage\n\n\`\`\`yaml\n# vibe-validate.config.yaml\nsteps:\n - name: Plugin and skill validation\n command: vat audit plugins/ --exclude \"**/__pycache__/**\"\n\`\`\`\n\n## Interpreting Output\n\n\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nSeverity taxonomy in audit output:\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations\n- **Warnings:** Skill too long, description too short, best practice violations\n\nAudit always exits \`0\` regardless — surface-level severity drives display grouping only.\n\n**Hiding codes from audit output.** Audit ignores \`validation.accept\` 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:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output\n\`\`\`\n\n**Per-instance acceptance.** For per-path suppression with an audit trail, use \`validation.accept\` and run \`vat skills validate\` or \`vat skills build\` — those commands apply \`accept\` and gate the build. See \`docs/validation-codes.md\` for the full code reference and the VAT agent-authoring skill for configuration patterns.\n";
10
+ export const text = "\n# VAT Audit: Validating Plugins, Skills & Marketplaces\n\n## Running the Audit\n\n\`\`\`bash\n# Audit current directory (recursive by default)\nvat audit\n\n# Audit a specific directory\nvat audit ./plugins/\n\n# Audit your entire Claude installation\nvat audit --user\n\n# Exclude noisy directories\nvat audit --exclude \"dist/**\" --exclude \"node_modules/**\"\n\n# Verbose: show all resources, not just those with issues\nvat audit --verbose\n\n# Compatibility analysis: which Claude surfaces each plugin supports\nvat audit ./plugins/ --compat\n\`\`\`\n\n## What Gets Detected (Automatic)\n\nRunning \`vat audit <path>\` recursively walks the directory and auto-detects:\n\n| Found | Detected as |\n|---|---|\n| \`.claude-plugin/plugin.json\` in a dir | Claude Plugin |\n| \`.claude-plugin/marketplace.json\` in a dir | Claude Marketplace |\n| \`SKILL.md\` file | Agent Skill |\n| \`agent.yaml\` + \`SKILL.md\` | VAT Agent |\n| \`installed_plugins.json\` | Registry file |\n\nRecursion is the default — you do not need \`--recursive\`.\n\n## Compatibility Analysis (\`--compat\`)\n\n\`\`\`bash\nvat audit ./plugins/ --compat\n\`\`\`\n\nOutput per plugin:\n\`\`\`yaml\nplugin: mission-control\ncompatibility:\n claude-code:\n compatible: true\n evidence: []\n cowork:\n compatible: true\n evidence: []\n claude-desktop:\n compatible: false\n evidence:\n - type: python-script\n file: hooks-handlers/handler.py\n detail: Python execution not available in claude-desktop\n\`\`\`\n\nUse this before a release to determine which surfaces each plugin supports.\n\n## Exit Codes\n\n\`vat audit\` is **advisory** — it reports every issue it detects but never blocks on validation severity:\n\n- \`0\` — always, when the audit completes, regardless of errors or warnings in the report.\n- \`2\` — system error (path not found, permission denied, etc.) — the audit could not run.\n\nFor 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.\n\n## CI Usage\n\n\`\`\`yaml\n# vibe-validate.config.yaml\nsteps:\n - name: Plugin and skill validation\n command: vat audit plugins/ --exclude \"**/__pycache__/**\"\n\`\`\`\n\n## Interpreting Output\n\n\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nSeverity taxonomy in audit output:\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations\n- **Warnings:** Skill too long, description too short, best practice violations\n\nAudit always exits \`0\` regardless — surface-level severity drives display grouping only.\n\n**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:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output\n\`\`\`\n\n**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.\n";
11
11
 
12
12
  export const fragments = {
13
13
  runningTheAudit: {
@@ -27,8 +27,8 @@ export const fragments = {
27
27
  },
28
28
  exitCodes: {
29
29
  header: "## Exit Codes",
30
- body: "\`vat audit\` is **advisory** — it reports every issue it detects but never blocks on validation severity:\n\n- \`0\` — always, when the audit completes, regardless of errors or warnings in the report.\n- \`2\` — system error (path not found, permission denied, etc.) — the audit could not run.\n\nFor 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.accept\` from config.",
31
- text: "## Exit Codes\n\n\`vat audit\` is **advisory** — it reports every issue it detects but never blocks on validation severity:\n\n- \`0\` — always, when the audit completes, regardless of errors or warnings in the report.\n- \`2\` — system error (path not found, permission denied, etc.) — the audit could not run.\n\nFor 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.accept\` from config."
30
+ body: "\`vat audit\` is **advisory** — it reports every issue it detects but never blocks on validation severity:\n\n- \`0\` — always, when the audit completes, regardless of errors or warnings in the report.\n- \`2\` — system error (path not found, permission denied, etc.) — the audit could not run.\n\nFor 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.",
31
+ text: "## Exit Codes\n\n\`vat audit\` is **advisory** — it reports every issue it detects but never blocks on validation severity:\n\n- \`0\` — always, when the audit completes, regardless of errors or warnings in the report.\n- \`2\` — system error (path not found, permission denied, etc.) — the audit could not run.\n\nFor 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."
32
32
  },
33
33
  ciUsage: {
34
34
  header: "## CI Usage",
@@ -37,7 +37,7 @@ export const fragments = {
37
37
  },
38
38
  interpretingOutput: {
39
39
  header: "## Interpreting Output",
40
- body: "\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nSeverity taxonomy in audit output:\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations\n- **Warnings:** Skill too long, description too short, best practice violations\n\nAudit always exits \`0\` regardless — surface-level severity drives display grouping only.\n\n**Hiding codes from audit output.** Audit ignores \`validation.accept\` 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:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output\n\`\`\`\n\n**Per-instance acceptance.** For per-path suppression with an audit trail, use \`validation.accept\` and run \`vat skills validate\` or \`vat skills build\` — those commands apply \`accept\` and gate the build. See \`docs/validation-codes.md\` for the full code reference and the VAT agent-authoring skill for configuration patterns.",
41
- text: "## Interpreting Output\n\n\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nSeverity taxonomy in audit output:\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations\n- **Warnings:** Skill too long, description too short, best practice violations\n\nAudit always exits \`0\` regardless — surface-level severity drives display grouping only.\n\n**Hiding codes from audit output.** Audit ignores \`validation.accept\` 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:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output\n\`\`\`\n\n**Per-instance acceptance.** For per-path suppression with an audit trail, use \`validation.accept\` and run \`vat skills validate\` or \`vat skills build\` — those commands apply \`accept\` and gate the build. See \`docs/validation-codes.md\` for the full code reference and the VAT agent-authoring skill for configuration patterns."
40
+ body: "\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nSeverity taxonomy in audit output:\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations\n- **Warnings:** Skill too long, description too short, best practice violations\n\nAudit always exits \`0\` regardless — surface-level severity drives display grouping only.\n\n**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:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output\n\`\`\`\n\n**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.",
41
+ text: "## Interpreting Output\n\n\`\`\`yaml\nstatus: warning\nsummary:\n filesScanned: 23\n success: 21\n warnings: 2\n errors: 0\n\`\`\`\n\nSeverity taxonomy in audit output:\n- **Errors:** Missing required frontmatter, broken links, invalid plugin.json schema, link integrity violations\n- **Warnings:** Skill too long, description too short, best practice violations\n\nAudit always exits \`0\` regardless — surface-level severity drives display grouping only.\n\n**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:\n\n\`\`\`yaml\nskills:\n config:\n my-skill:\n validation:\n severity:\n LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output\n\`\`\`\n\n**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."
42
42
  }
43
43
  };
@@ -74,7 +74,7 @@ Use this before a release to determine which surfaces each plugin supports.
74
74
  - `0` — always, when the audit completes, regardless of errors or warnings in the report.
75
75
  - `2` — system error (path not found, permission denied, etc.) — the audit could not run.
76
76
 
77
- 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.accept` from config.
77
+ 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.
78
78
 
79
79
  ## CI Usage
80
80
 
@@ -102,7 +102,7 @@ Severity taxonomy in audit output:
102
102
 
103
103
  Audit always exits `0` regardless — surface-level severity drives display grouping only.
104
104
 
105
- **Hiding codes from audit output.** Audit ignores `validation.accept` 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:
105
+ **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:
106
106
 
107
107
  ```yaml
108
108
  skills:
@@ -113,4 +113,4 @@ skills:
113
113
  LINK_TO_NAVIGATION_FILE: ignore # hidden from audit output
114
114
  ```
115
115
 
116
- **Per-instance acceptance.** For per-path suppression with an audit trail, use `validation.accept` and run `vat skills validate` or `vat skills build` — those commands apply `accept` and gate the build. See `docs/validation-codes.md` for the full code reference and the VAT agent-authoring skill for configuration patterns.
116
+ **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.
@@ -298,7 +298,7 @@ Use `stripPrefix` to remove a common directory prefix (e.g., `"knowledge-base"`)
298
298
  | `{{link.resource.fileName}}` | Target filename (if resolved) |
299
299
  | `{{skill.name}}` | Skill name from frontmatter |
300
300
 
301
- **`validation`** — Unified framework for overriding default severity and accepting specific issue instances:
301
+ **`validation`** — Unified framework for overriding default severity and allowing specific issue instances:
302
302
 
303
303
  ```yaml
304
304
  # In vibe-agent-toolkit.config.yaml under skills.defaults or skills.config.<name>
@@ -306,27 +306,29 @@ validation:
306
306
  severity:
307
307
  LINK_DROPPED_BY_DEPTH: error # upgrade: block on depth-dropped links
308
308
  LINK_TO_NAVIGATION_FILE: ignore # silence: this skill intentionally links to READMEs
309
- accept:
309
+ allow:
310
310
  PACKAGED_UNREFERENCED_FILE:
311
311
  - paths: ["templates/runtime.json"]
312
312
  reason: "consumed programmatically at runtime"
313
313
  expires: "2026-09-30"
314
+ SKILL_LENGTH_EXCEEDS_RECOMMENDED:
315
+ - reason: "whole-skill concern; paths defaults to ['**/*']"
314
316
  ```
315
317
 
316
318
  Two sub-keys, each covering a different override granularity:
317
319
 
318
320
  - **`severity`** — Class-level. Raise any code to `error` (blocks build), lower to `warning` (emits, non-blocking), or `ignore` (fully suppressed). Applies to every instance of that code.
319
- - **`accept`** — Per-instance. Suppress specific `(code, path)` matches with a required `reason` and optional `expires` date. Use for legitimate exceptions that don't warrant code-wide silencing.
321
+ - **`allow`** — Per-instance. Suppress specific `(code, path)` matches with a required `reason` and optional `expires` date. `paths` is optional (defaults to `["**/*"]` — the whole skill). Use for legitimate exceptions that don't warrant code-wide silencing.
320
322
 
321
323
  Things adopters typically adjust:
322
324
 
323
325
  - Downgrade `LINK_DROPPED_BY_DEPTH` to `ignore` when intentionally linking out to external docs.
324
- - Accept specific files under `PACKAGED_UNREFERENCED_FILE` when they're consumed programmatically by CLI scripts at runtime.
325
- - Raise `ACCEPTANCE_EXPIRED` to `error` for zero-tolerance expiry policies.
326
+ - Allow specific files under `PACKAGED_UNREFERENCED_FILE` when they're consumed programmatically by CLI scripts at runtime.
327
+ - Raise `ALLOW_EXPIRED` to `error` for zero-tolerance expiry policies.
326
328
 
327
- Expired `accept` entries still apply — VAT emits `ACCEPTANCE_EXPIRED` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused `accept` entries surface as `ACCEPTANCE_UNUSED` (analogous to ESLint's unused-disable).
329
+ Expired `allow` entries still apply — VAT emits `ALLOW_EXPIRED` as a reminder rather than silently re-surfacing the underlying issue (no surprise build breaks when a date passes). Unused `allow` entries surface as `ALLOW_UNUSED` (analogous to ESLint's unused-disable).
328
330
 
329
- Full code reference at `docs/validation-codes.md`. `vat audit` is advisory: it applies `severity` for display grouping only, ignores `accept`, and always exits 0. Use `vat skills validate` or `vat skills build` for gated checks.
331
+ Full code reference at `docs/validation-codes.md`. `vat audit` is advisory: it applies `severity` for display grouping only, ignores `allow`, and always exits 0. Use `vat skills validate` or `vat skills build` for gated checks.
330
332
 
331
333
  ## Testing Agents
332
334
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vibe-agent-toolkit/vat-development-agents",
3
- "version": "0.1.30-rc.1",
3
+ "version": "0.1.30-rc.2",
4
4
  "description": "VAT development agents - dogfooding the vibe-agent-toolkit",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -65,13 +65,13 @@
65
65
  "postinstall": "vat claude plugin install --npm-postinstall || exit 0"
66
66
  },
67
67
  "dependencies": {
68
- "@vibe-agent-toolkit/agent-schema": "0.1.30-rc.1",
69
- "@vibe-agent-toolkit/cli": "0.1.30-rc.1",
68
+ "@vibe-agent-toolkit/agent-schema": "0.1.30-rc.2",
69
+ "@vibe-agent-toolkit/cli": "0.1.30-rc.2",
70
70
  "yaml": "^2.8.2"
71
71
  },
72
72
  "devDependencies": {
73
73
  "@types/node": "^25.0.3",
74
- "@vibe-agent-toolkit/resource-compiler": "0.1.30-rc.1",
74
+ "@vibe-agent-toolkit/resource-compiler": "0.1.30-rc.2",
75
75
  "ts-patch": "^3.2.1",
76
76
  "typescript": "^5.7.3"
77
77
  },