@skill-graph/cli 0.5.6

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.
Files changed (330) hide show
  1. package/CHANGELOG.md +247 -0
  2. package/LICENSE +200 -0
  3. package/NOTICE +62 -0
  4. package/README.md +398 -0
  5. package/SKILL_GRAPH.md +443 -0
  6. package/bin/skill-graph.js +374 -0
  7. package/docs/ADOPTION.md +117 -0
  8. package/docs/CONFORMANCE.md +66 -0
  9. package/docs/PRIMER.md +384 -0
  10. package/docs/QUICKSTART-30MIN.md +333 -0
  11. package/docs/ROUTING-METRICS.md +120 -0
  12. package/docs/SKILL-MD-FORMAT-COMPATIBILITY.md +127 -0
  13. package/docs/SKILL_AUDIT_CHECKLIST.md +199 -0
  14. package/docs/SKILL_AUDIT_LOOP.md +195 -0
  15. package/docs/SKILL_METADATA_PROTOCOL.md +609 -0
  16. package/docs/_archived/marketplace-publication-priority-2026-05-18.md +239 -0
  17. package/docs/adr/0001-predicate-set.md +69 -0
  18. package/docs/adr/0002-json-ld-context.md +82 -0
  19. package/docs/adr/0003-ontoclean-rigidity-tags.md +65 -0
  20. package/docs/adr/0004-persistent-identifiers.md +74 -0
  21. package/docs/adr/0005-freshness-consolidation.md +70 -0
  22. package/docs/adr/0006-revise-predicate-rename.md +105 -0
  23. package/docs/adr/0007-audit-loop-cadence.md +99 -0
  24. package/docs/adr/0008-skill-surface-split-and-curation-policy.md +93 -0
  25. package/docs/category-consumers.md +168 -0
  26. package/docs/concept-map.md +194 -0
  27. package/docs/diagrams/drift-states.mmd +21 -0
  28. package/docs/diagrams/manifest-pipeline.mmd +25 -0
  29. package/docs/diagrams/routing-harness.mmd +41 -0
  30. package/docs/diagrams/starter-graph.mmd +53 -0
  31. package/docs/field-decision-guide.md +315 -0
  32. package/docs/field-rationale.md +211 -0
  33. package/docs/field-reference.generated.md +624 -0
  34. package/docs/field-reference.md +1426 -0
  35. package/docs/glossary.md +190 -0
  36. package/docs/head-noun-glossary.md +63 -0
  37. package/docs/images/audit-phases.png +0 -0
  38. package/docs/images/drift-states.png +0 -0
  39. package/docs/images/graded-mode.png +0 -0
  40. package/docs/images/manifest-pipeline.png +0 -0
  41. package/docs/images/routing-harness.png +0 -0
  42. package/docs/images/skill-anatomy.png +0 -0
  43. package/docs/images/starter-graph.png +0 -0
  44. package/docs/images/system-model.png +0 -0
  45. package/docs/integrations/github-actions.md +155 -0
  46. package/docs/manifest-field-mapping.md +443 -0
  47. package/docs/marketplace-publication-queue.generated.md +240 -0
  48. package/docs/marketplace-release-agent-prompt.md +82 -0
  49. package/docs/marketplace-skill-candidate-list.md +272 -0
  50. package/docs/marketplace-syndication.md +222 -0
  51. package/docs/migration-sample-review.md +155 -0
  52. package/docs/migrations/v4-to-v5.md +168 -0
  53. package/docs/migrations/v5-to-v6.md +221 -0
  54. package/docs/name-exceptions.yaml +37 -0
  55. package/docs/plans/marketplace-p1-public-migration-plan.md +41 -0
  56. package/docs/plans/multi-root-workspace.md +148 -0
  57. package/docs/plans/scripts-roadmap.md +107 -0
  58. package/docs/plans/v4-schema-bump.md +160 -0
  59. package/docs/plans/wave-2-extraction.md +122 -0
  60. package/docs/positioning-vs-marketplaces.md +175 -0
  61. package/docs/proposals/skill-audit-loop-positioning.md +160 -0
  62. package/docs/quality-doctrine.md +138 -0
  63. package/docs/recommended-skills.md +150 -0
  64. package/docs/research/skill-comprehension-eval-research.md +1830 -0
  65. package/docs/research/skill-retrieval-evidence.md +66 -0
  66. package/docs/skill-metadata-protocol.md +471 -0
  67. package/docs/skills-sh-maintainer-cleanup-request.md +80 -0
  68. package/examples/audits/a11y/findings.md +52 -0
  69. package/examples/audits/a11y/scorecard.md +21 -0
  70. package/examples/audits/a11y/verdict.md +44 -0
  71. package/examples/audits/debugging/findings.md +59 -0
  72. package/examples/audits/debugging/scorecard.md +22 -0
  73. package/examples/audits/debugging/verdict.md +33 -0
  74. package/examples/audits/documentation/findings.md +59 -0
  75. package/examples/audits/documentation/scorecard.md +22 -0
  76. package/examples/audits/documentation/verdict.md +33 -0
  77. package/examples/evals/a11y.json +140 -0
  78. package/examples/evals/api-design.json +52 -0
  79. package/examples/evals/code-review.json +52 -0
  80. package/examples/evals/data-modeling.json +52 -0
  81. package/examples/evals/database-migration.json +52 -0
  82. package/examples/evals/debugging.json +118 -0
  83. package/examples/evals/dependency-architecture.json +52 -0
  84. package/examples/evals/design-system-architecture.json +52 -0
  85. package/examples/evals/error-tracking.json +52 -0
  86. package/examples/evals/event-contract-design.json +52 -0
  87. package/examples/evals/form-ux-architecture.json +52 -0
  88. package/examples/evals/framework-fit-analysis.json +52 -0
  89. package/examples/evals/graph-audit.json +139 -0
  90. package/examples/evals/information-architecture.json +52 -0
  91. package/examples/evals/interaction-feedback.json +52 -0
  92. package/examples/evals/interaction-patterns.json +52 -0
  93. package/examples/evals/layout-composition.json +52 -0
  94. package/examples/evals/lint-overlay.json +117 -0
  95. package/examples/evals/microcopy.json +52 -0
  96. package/examples/evals/observability-modeling.json +52 -0
  97. package/examples/evals/pattern-recognition.json +96 -0
  98. package/examples/evals/performance-engineering.json +52 -0
  99. package/examples/evals/refactor.json +128 -0
  100. package/examples/evals/semiotics.json +52 -0
  101. package/examples/evals/skill-infrastructure.json +96 -0
  102. package/examples/evals/skill-router.json +140 -0
  103. package/examples/evals/skill-router.routing.json +113 -0
  104. package/examples/evals/system-interface-contracts.json +52 -0
  105. package/examples/evals/task-analysis.json +52 -0
  106. package/examples/evals/testing-strategy.json +118 -0
  107. package/examples/evals/type-safety.json +249 -0
  108. package/examples/evals/visual-design-foundations.json +52 -0
  109. package/examples/evals/webhook-integration.json +52 -0
  110. package/examples/exports/a11y.skill-md.md +80 -0
  111. package/examples/exports/debugging.skill-md.md +80 -0
  112. package/examples/exports/refactor.skill-md.md +78 -0
  113. package/examples/exports/testing-strategy.skill-md.md +81 -0
  114. package/examples/projects/markdown-static-site/README.md +115 -0
  115. package/examples/projects/markdown-static-site/skills/content-source-router/SKILL.md +131 -0
  116. package/examples/projects/markdown-static-site/skills/image-optimization-pipeline-config/SKILL.md +132 -0
  117. package/examples/projects/markdown-static-site/skills/link-rot-detection/SKILL.md +103 -0
  118. package/examples/projects/markdown-static-site/skills/markdown-post-frontmatter-validation/SKILL.md +133 -0
  119. package/examples/projects/markdown-static-site/skills/migrate-posts-to-v2-frontmatter/SKILL.md +140 -0
  120. package/examples/projects/saas-stripe-postgres/README.md +208 -0
  121. package/examples/projects/saas-stripe-postgres/db/migrations/0004_canonicalize_orders.sql +37 -0
  122. package/examples/projects/saas-stripe-postgres/db/schema.sql +112 -0
  123. package/examples/projects/saas-stripe-postgres/skills/migrate-orders-to-canonical-schema/SKILL.md +149 -0
  124. package/examples/projects/saas-stripe-postgres/skills/nextjs-server-action-validation/SKILL.md +154 -0
  125. package/examples/projects/saas-stripe-postgres/skills/payment-provider-router/SKILL.md +153 -0
  126. package/examples/projects/saas-stripe-postgres/skills/postgres-rls-pattern/SKILL.md +163 -0
  127. package/examples/projects/saas-stripe-postgres/skills/stripe-webhook-signature-verification/SKILL.md +137 -0
  128. package/examples/protocol/skill-metadata-template.md +301 -0
  129. package/examples/protocol/skills.manifest.sample.json +13245 -0
  130. package/examples/skill-metadata-template.md +317 -0
  131. package/examples/skills.manifest.sample.json +13519 -0
  132. package/examples/tests/v3-1-skos-fixture/SKILL.md +93 -0
  133. package/marketplace/README.md +17 -0
  134. package/marketplace/skills/a11y/SKILL.md +66 -0
  135. package/marketplace/skills/acid-fundamentals/SKILL.md +106 -0
  136. package/marketplace/skills/agent-engineering/SKILL.md +386 -0
  137. package/marketplace/skills/agent-eval-design/SKILL.md +55 -0
  138. package/marketplace/skills/ai-native-development/SKILL.md +294 -0
  139. package/marketplace/skills/api-design/SKILL.md +60 -0
  140. package/marketplace/skills/architecture-decision-records/SKILL.md +55 -0
  141. package/marketplace/skills/background-jobs/SKILL.md +265 -0
  142. package/marketplace/skills/bounded-context-mapping/SKILL.md +55 -0
  143. package/marketplace/skills/cap-theorem-tradeoffs/SKILL.md +127 -0
  144. package/marketplace/skills/client-server-boundary/SKILL.md +187 -0
  145. package/marketplace/skills/code-review/SKILL.md +120 -0
  146. package/marketplace/skills/color-system-design/SKILL.md +43 -0
  147. package/marketplace/skills/component-architecture/SKILL.md +126 -0
  148. package/marketplace/skills/compression/SKILL.md +112 -0
  149. package/marketplace/skills/conceptual-modeling/SKILL.md +181 -0
  150. package/marketplace/skills/connection-pooling/SKILL.md +105 -0
  151. package/marketplace/skills/constraint-awareness/SKILL.md +287 -0
  152. package/marketplace/skills/content-monitor/SKILL.md +209 -0
  153. package/marketplace/skills/context-engineering/SKILL.md +320 -0
  154. package/marketplace/skills/context-graph/SKILL.md +174 -0
  155. package/marketplace/skills/context-management/SKILL.md +174 -0
  156. package/marketplace/skills/context-window/SKILL.md +239 -0
  157. package/marketplace/skills/contract-testing/SKILL.md +120 -0
  158. package/marketplace/skills/cron-scheduling/SKILL.md +223 -0
  159. package/marketplace/skills/dark-mode-implementation/SKILL.md +47 -0
  160. package/marketplace/skills/data-modeling/SKILL.md +59 -0
  161. package/marketplace/skills/data-modeling-fundamentals/SKILL.md +117 -0
  162. package/marketplace/skills/database-migration/SKILL.md +429 -0
  163. package/marketplace/skills/debugging/SKILL.md +67 -0
  164. package/marketplace/skills/dependency-architecture/SKILL.md +58 -0
  165. package/marketplace/skills/design-module-composition/SKILL.md +43 -0
  166. package/marketplace/skills/design-system-architecture/SKILL.md +61 -0
  167. package/marketplace/skills/design-thinking/SKILL.md +44 -0
  168. package/marketplace/skills/diagnosis/SKILL.md +296 -0
  169. package/marketplace/skills/diff-analysis/SKILL.md +188 -0
  170. package/marketplace/skills/e2e-test-design/SKILL.md +113 -0
  171. package/marketplace/skills/entity-relationship-modeling/SKILL.md +218 -0
  172. package/marketplace/skills/epistemic-grounding/SKILL.md +112 -0
  173. package/marketplace/skills/error-boundary/SKILL.md +235 -0
  174. package/marketplace/skills/error-tracking/SKILL.md +261 -0
  175. package/marketplace/skills/eval-driven-development/SKILL.md +147 -0
  176. package/marketplace/skills/evaluation/SKILL.md +113 -0
  177. package/marketplace/skills/event-contract-design/SKILL.md +60 -0
  178. package/marketplace/skills/event-storming/SKILL.md +56 -0
  179. package/marketplace/skills/form-ux-architecture/SKILL.md +60 -0
  180. package/marketplace/skills/framework-fit-analysis/SKILL.md +59 -0
  181. package/marketplace/skills/frontend-architecture/SKILL.md +43 -0
  182. package/marketplace/skills/generative-ui/SKILL.md +118 -0
  183. package/marketplace/skills/graph-audit/SKILL.md +81 -0
  184. package/marketplace/skills/guardrails/SKILL.md +118 -0
  185. package/marketplace/skills/hooks-patterns/SKILL.md +185 -0
  186. package/marketplace/skills/http-semantics/SKILL.md +136 -0
  187. package/marketplace/skills/ideation/SKILL.md +41 -0
  188. package/marketplace/skills/indexing-strategy/SKILL.md +108 -0
  189. package/marketplace/skills/information-architecture/SKILL.md +59 -0
  190. package/marketplace/skills/integration-test-design/SKILL.md +111 -0
  191. package/marketplace/skills/intent-recognition/SKILL.md +136 -0
  192. package/marketplace/skills/interaction-feedback/SKILL.md +59 -0
  193. package/marketplace/skills/interaction-patterns/SKILL.md +59 -0
  194. package/marketplace/skills/journey-mapping/SKILL.md +41 -0
  195. package/marketplace/skills/keywords/SKILL.md +213 -0
  196. package/marketplace/skills/knowledge-modeling/SKILL.md +232 -0
  197. package/marketplace/skills/layout-composition/SKILL.md +59 -0
  198. package/marketplace/skills/linguistics/SKILL.md +429 -0
  199. package/marketplace/skills/lint-overlay/SKILL.md +76 -0
  200. package/marketplace/skills/mental-models/SKILL.md +126 -0
  201. package/marketplace/skills/merge-queue/SKILL.md +94 -0
  202. package/marketplace/skills/methodology/SKILL.md +317 -0
  203. package/marketplace/skills/microcopy/SKILL.md +232 -0
  204. package/marketplace/skills/middleware-patterns/SKILL.md +363 -0
  205. package/marketplace/skills/mobile-responsive-ux/SKILL.md +287 -0
  206. package/marketplace/skills/mutation-testing/SKILL.md +112 -0
  207. package/marketplace/skills/naming-conventions/SKILL.md +112 -0
  208. package/marketplace/skills/observability-modeling/SKILL.md +59 -0
  209. package/marketplace/skills/ontology-modeling/SKILL.md +67 -0
  210. package/marketplace/skills/owasp-security/SKILL.md +153 -0
  211. package/marketplace/skills/pattern-recognition/SKILL.md +472 -0
  212. package/marketplace/skills/performance-budgets/SKILL.md +185 -0
  213. package/marketplace/skills/performance-engineering/SKILL.md +58 -0
  214. package/marketplace/skills/performance-testing/SKILL.md +125 -0
  215. package/marketplace/skills/printify/SKILL.md +42 -0
  216. package/marketplace/skills/prioritization/SKILL.md +118 -0
  217. package/marketplace/skills/problem-framing/SKILL.md +41 -0
  218. package/marketplace/skills/problem-locating-solving/SKILL.md +203 -0
  219. package/marketplace/skills/project-knowledge-extraction/SKILL.md +54 -0
  220. package/marketplace/skills/prompt-craft/SKILL.md +134 -0
  221. package/marketplace/skills/prompt-injection-defense/SKILL.md +132 -0
  222. package/marketplace/skills/property-based-testing/SKILL.md +100 -0
  223. package/marketplace/skills/prototyping/SKILL.md +43 -0
  224. package/marketplace/skills/query-optimization/SKILL.md +144 -0
  225. package/marketplace/skills/real-time-updates/SKILL.md +324 -0
  226. package/marketplace/skills/ref-patterns/SKILL.md +284 -0
  227. package/marketplace/skills/refactor/SKILL.md +65 -0
  228. package/marketplace/skills/rendering-models/SKILL.md +142 -0
  229. package/marketplace/skills/replication-patterns/SKILL.md +110 -0
  230. package/marketplace/skills/research-synthesis/SKILL.md +41 -0
  231. package/marketplace/skills/route-handler-design/SKILL.md +347 -0
  232. package/marketplace/skills/schema-evolution/SKILL.md +140 -0
  233. package/marketplace/skills/security-fundamentals/SKILL.md +139 -0
  234. package/marketplace/skills/semantic-center/SKILL.md +194 -0
  235. package/marketplace/skills/semantic-relations/SKILL.md +250 -0
  236. package/marketplace/skills/semantics/SKILL.md +366 -0
  237. package/marketplace/skills/semiotics/SKILL.md +230 -0
  238. package/marketplace/skills/seo-strategy/SKILL.md +260 -0
  239. package/marketplace/skills/server-actions-design/SKILL.md +243 -0
  240. package/marketplace/skills/server-components-design/SKILL.md +190 -0
  241. package/marketplace/skills/sharding-strategy/SKILL.md +123 -0
  242. package/marketplace/skills/shopify/SKILL.md +42 -0
  243. package/marketplace/skills/skill-infrastructure/SKILL.md +320 -0
  244. package/marketplace/skills/skill-router/SKILL.md +71 -0
  245. package/marketplace/skills/skill-scaffold/SKILL.md +105 -0
  246. package/marketplace/skills/snapshot-testing/SKILL.md +120 -0
  247. package/marketplace/skills/spec-driven-development/SKILL.md +148 -0
  248. package/marketplace/skills/state-machine-modeling/SKILL.md +56 -0
  249. package/marketplace/skills/state-management/SKILL.md +134 -0
  250. package/marketplace/skills/streaming-architecture/SKILL.md +194 -0
  251. package/marketplace/skills/summarization/SKILL.md +156 -0
  252. package/marketplace/skills/suspense-patterns/SKILL.md +265 -0
  253. package/marketplace/skills/system-interface-contracts/SKILL.md +59 -0
  254. package/marketplace/skills/task-analysis/SKILL.md +201 -0
  255. package/marketplace/skills/taxonomy-design/SKILL.md +66 -0
  256. package/marketplace/skills/test-coverage-strategy/SKILL.md +108 -0
  257. package/marketplace/skills/test-doubles-design/SKILL.md +98 -0
  258. package/marketplace/skills/test-driven-development/SKILL.md +96 -0
  259. package/marketplace/skills/testing-strategy/SKILL.md +67 -0
  260. package/marketplace/skills/theme-system-design/SKILL.md +43 -0
  261. package/marketplace/skills/tool-call-flow/SKILL.md +229 -0
  262. package/marketplace/skills/tool-call-strategy/SKILL.md +292 -0
  263. package/marketplace/skills/transaction-isolation/SKILL.md +98 -0
  264. package/marketplace/skills/type-safety/SKILL.md +177 -0
  265. package/marketplace/skills/typography-system/SKILL.md +43 -0
  266. package/marketplace/skills/usability-testing/SKILL.md +43 -0
  267. package/marketplace/skills/user-research/SKILL.md +43 -0
  268. package/marketplace/skills/vercel-composition-patterns/SKILL.md +157 -0
  269. package/marketplace/skills/version-control/SKILL.md +233 -0
  270. package/marketplace/skills/visual-design-foundations/SKILL.md +59 -0
  271. package/marketplace/skills/visual-hierarchy/SKILL.md +43 -0
  272. package/marketplace/skills/webhook-integration/SKILL.md +331 -0
  273. package/marketplace/skills/writing-humanizer/SKILL.md +380 -0
  274. package/package.json +67 -0
  275. package/schemas/manifest.schema.json +811 -0
  276. package/schemas/manifest.v2.schema.json +164 -0
  277. package/schemas/manifest.v3.schema.json +758 -0
  278. package/schemas/manifest.v4.schema.json +755 -0
  279. package/schemas/manifest.v5.schema.json +755 -0
  280. package/schemas/manifest.v6.schema.json +811 -0
  281. package/schemas/skill.context.jsonld +279 -0
  282. package/schemas/skill.schema.json +919 -0
  283. package/schemas/skill.v2.schema.json +201 -0
  284. package/schemas/skill.v3.schema.json +827 -0
  285. package/schemas/skill.v4.schema.json +822 -0
  286. package/schemas/skill.v5.schema.json +830 -0
  287. package/schemas/skill.v6.schema.json +946 -0
  288. package/schemas/vocabulary/keywords.json +180 -0
  289. package/schemas/vocabulary/workspace_tags.json +23 -0
  290. package/scripts/__tests__/migrate-skill-v2-to-v3.test.js +161 -0
  291. package/scripts/__tests__/migrate-skill-v3-to-v4.test.js +158 -0
  292. package/scripts/__tests__/test-export-parser-drift.js +149 -0
  293. package/scripts/__tests__/test-marketplace-export.js +114 -0
  294. package/scripts/__tests__/test-router-paths.js +82 -0
  295. package/scripts/__tests__/test-stability-promotion.js +244 -0
  296. package/scripts/__tests__/test-v3-1-alias-contract.js +109 -0
  297. package/scripts/__tests__/test-v3-1-skos-runtime.js +116 -0
  298. package/scripts/backfill-schema-version.js +198 -0
  299. package/scripts/build-field-reference.js +160 -0
  300. package/scripts/build-retrieval-baseline.js +511 -0
  301. package/scripts/check-markdown-links.js +211 -0
  302. package/scripts/check-protocol-consistency.js +979 -0
  303. package/scripts/export-marketplace-skills.js +610 -0
  304. package/scripts/export-skill.js +374 -0
  305. package/scripts/generate-manifest.js +787 -0
  306. package/scripts/lib/alias-contract.js +83 -0
  307. package/scripts/lib/audit-prompt-builder.js +771 -0
  308. package/scripts/lib/mock-grader.js +134 -0
  309. package/scripts/lib/parse-frontmatter.js +429 -0
  310. package/scripts/lib/roots.js +119 -0
  311. package/scripts/lint/check-archetype-sections.js +185 -0
  312. package/scripts/lint/check-category-enum.js +83 -0
  313. package/scripts/lint/check-routing-eval.js +146 -0
  314. package/scripts/lint/check-routing-quality.js +211 -0
  315. package/scripts/lint/check-stability-promotion.js +220 -0
  316. package/scripts/lint/format-code-frame.js +206 -0
  317. package/scripts/marketplace-install.js +125 -0
  318. package/scripts/migrate-category-to-enum.js +169 -0
  319. package/scripts/migrate-skill-v2-to-v3.js +424 -0
  320. package/scripts/migrate-skill-v3-to-v4.js +200 -0
  321. package/scripts/migrate-skill-v5-to-v6.js +304 -0
  322. package/scripts/restructure-by-category.js +85 -0
  323. package/scripts/seed-publication-classification.js +282 -0
  324. package/scripts/skill-audit.js +893 -0
  325. package/scripts/skill-graph-drift.js +483 -0
  326. package/scripts/skill-graph-route.js +766 -0
  327. package/scripts/skill-graph-routing-eval.js +393 -0
  328. package/scripts/skill-lint.js +1317 -0
  329. package/scripts/skill-overlap.js +213 -0
  330. package/scripts/verify-skill-md-export.js +201 -0
@@ -0,0 +1,1426 @@
1
+ # Skill Graph Field Reference
2
+
3
+ > One section per authored field. Use this when writing or reviewing a `SKILL.md` file.
4
+ > For the "which value do I pick?" decisions, see [`docs/field-decision-guide.md`](field-decision-guide.md).
5
+ > For field groups, conditional requiredness, and schema strictness rules, see [`docs/skill-metadata-protocol.md`](skill-metadata-protocol.md).
6
+
7
+ Fields are listed in authored order — the same order they appear in [`examples/skill-metadata-template.md`](../examples/skill-metadata-template.md).
8
+
9
+ ## Three docs, three genres
10
+
11
+ The field reference is split across three coordinated documents. Use whichever fits your task:
12
+
13
+ | Doc | Genre | When to read |
14
+ |---|---|---|
15
+ | [`field-reference.md`](field-reference.md) (this doc) | **Hand-curated prose reference.** Field-by-field, with worked examples, lint notes, and cross-cutting guidance. | When authoring or reviewing a SKILL.md and you want examples and "when to use" rules alongside the schema-canonical definition. |
16
+ | [`field-reference.generated.md`](field-reference.generated.md) | **Auto-generated index.** Built from `schemas/skill.v4.schema.json` description strings by `scripts/build-field-reference.js`. Drift-free against the schema. | When you want the machine-guaranteed list of every field, every type, every pattern, every enum value. The fastest way to verify what the schema actually accepts today. |
17
+ | [`field-rationale.md`](field-rationale.md) | **Hand-authored "why this field" rationale.** Covers the ~10 fields whose meaning is non-obvious from the schema description (`scope`, `eval_artifacts`, `eval_state`, `routing_eval`, `relations.depends_on`, `relations.verify_with`, `relations.broader`, `grounding.evidence_priority`, `lifecycle.review_cadence`, `portability.readiness`). | When you understand *what* a field stores but want to know *why the field exists at all* and *what the common confusion looks like*. |
18
+
19
+ The schema is the single source of truth for shape; this doc is the source of truth for prose; `field-rationale.md` is the source of truth for design intent. Lint check C7 (in `scripts/check-protocol-consistency.js`) verifies the generated index stays in sync with the schema description strings — running `node scripts/build-field-reference.js --check` against the live schema must succeed before commit.
20
+
21
+ ---
22
+
23
+ ## `schema_version`
24
+
25
+ **Purpose.** Versions the contract so migration tooling can handle future schema changes deterministically.
26
+
27
+ **Rules.**
28
+ - Must be the integer `4` or the string `"4"` for all v4 skills.
29
+ - Start every new skill at the current schema version. Do not downgrade.
30
+ - The v3 -> v4 bump renamed `browse_category` -> `category`, `category` / `category_path` -> `domain`, `project_tags` -> `workspace_tags`, and `routing_groups` -> `routing_bundles`. Run `node scripts/migrate-skill-v3-to-v4.js` for a one-shot migration.
31
+ - The v1 → v2 bump (SH-5784) changed the `scope` enum (`generic`→`portable`, `operational`→`codebase`), split `eval_status` into three orthogonal fields, renamed `portability.level`→`readiness` and `portability.exports`→`targets`, and renamed `route_bundles`→`routing_bundles`. See `docs/manifest-field-mapping.md § Migration Note — v1 → v2` for the historical map.
32
+
33
+ **Versioning semantics (policy).** The integer signals *breaking vs non-breaking* evolution. A minor/patch axis is intentionally not surfaced on this field; additive schema changes do not require consumers to migrate, so no version bump is emitted.
34
+
35
+ **Example.**
36
+ ```yaml
37
+ schema_version: 4
38
+ ```
39
+
40
+ **When to use.** Always — this is a required field.
41
+
42
+ **When NOT to use.** N/A — required.
43
+
44
+ ---
45
+
46
+ ## `urn`
47
+
48
+ **Purpose.** Globally-unique persistent identifier for the skill. Unlocks FAIR Findability (Wilkinson et al. 2016) across repos and federated registries. `name` is the display-layer handle; `urn` is the stable identity consumers should cite. See ADR 0004 for the full rationale.
49
+
50
+ **Rules.**
51
+ - Optional in v4.
52
+ - Format: `urn:skill:<repo-slug>:<skill-name>`.
53
+ - `<repo-slug>` is the publishing repo's canonical short handle — lowercase, hyphen-separated, `[a-z0-9-]+` (e.g. `skill-graph`, or your own repo's short name).
54
+ - `<skill-name>` MUST equal the `name` field exactly.
55
+ - Must be globally unique across all federated repos — the URN is the primary key a registry uses to resolve skills.
56
+ - Pattern: `^urn:skill:[a-z0-9][a-z0-9-]*:[a-z0-9][a-z0-9-/:]*$`.
57
+
58
+ **Example.**
59
+ ```yaml
60
+ name: knowledge-graph
61
+ urn: urn:skill:skill-graph:knowledge-graph
62
+ ```
63
+
64
+ **When to use.** Populate on every new skill and on every skill edited after 2026-04-20. Required when the skill is published to a federated registry. Recommended universally because it is cheap to add and free to have.
65
+
66
+ **When NOT to use.** Skills that are strictly internal and will never leave the authoring repo MAY omit the field in v3. They cannot omit it in v4.
67
+
68
+ **JSON-LD mapping.** `urn` maps to `@id` in `schemas/skill.context.jsonld`. When the skill is projected to RDF, the URN becomes the subject of every triple derived from the skill's frontmatter.
69
+
70
+ **References.** RFC 8141 (URN Syntax), ADR 0004.
71
+
72
+ ---
73
+
74
+ ## `name`
75
+
76
+ **Purpose.** Stable skill identifier used for routing, `relations.*` targets, and filesystem layout. This is the handle other skills point at in their `relations` blocks.
77
+
78
+ **Rules.**
79
+ - Must match `^[a-z0-9][a-z0-9-/:]*$` — lowercase alphanumerics, hyphens, forward slashes, and colons only.
80
+ - Must start with a letter or digit.
81
+ - Should match the parent directory name so Agent-Skills export can use the directory as the canonical identifier.
82
+ - Forward slashes (`/`) and colons (`:`) are allowed in Skill Graph names but are normalized to hyphens during Agent-Skills export.
83
+
84
+ **Example.**
85
+ ```yaml
86
+ name: shopify
87
+ ```
88
+
89
+ **When to use.** Always — required.
90
+
91
+ **When NOT to use.** N/A — required.
92
+
93
+ ---
94
+
95
+ ## `description`
96
+
97
+ **Purpose.** The routing contract. Tells a router whether this skill should activate for a given query or label. It is pushy, specific, and boundary-aware.
98
+
99
+ **Rules.**
100
+ - Lead with trigger phrases ("Use when…", "Activates for…") rather than generic summaries.
101
+ - Include an explicit negative boundary ("Do NOT use for…") so the router doesn't over-activate.
102
+ - Do not repeat the `## Coverage` section body here — that belongs inside the skill body, not in the routing contract.
103
+
104
+ **Example.**
105
+ ```yaml
106
+ description: >
107
+ Shopify integration skill for API, webhook, and sync work. Use when the
108
+ task involves Shopify orders, products, webhooks, or the Shopify Admin API.
109
+ Do NOT use for general e-commerce patterns not tied to Shopify.
110
+ ```
111
+
112
+ **When to use.** Always — required.
113
+
114
+ **When NOT to use.** Do not expand beyond 3 sentences or copy-paste the `## Coverage` scope list here. The description and `## Coverage` are sibling layers of progressive disclosure, not duplicates.
115
+
116
+ **Lint check.** `scripts/skill-lint.js` warns when the description text appears verbatim inside the `## Coverage` section body — a signal that the two layers have collapsed. See `scripts/lint/check-routing-quality.js` (check R2).
117
+
118
+ ---
119
+
120
+ ## `version`
121
+
122
+ **Purpose.** Tracks the semantic version of the skill content itself, independent of the schema version. Enables change tracking, relation resolution, and diff-based audit.
123
+
124
+ **Rules.**
125
+ - Must be a semver string matching `^[0-9]+\.[0-9]+\.[0-9]+$`.
126
+ - Start new skills at `1.0.0`.
127
+ - Increment the patch version for small corrections (examples, wording, typos).
128
+ - Increment the minor version when new sections or fields are added without breaking the existing shape.
129
+ - Increment the major version when content is reorganized or an archetype changes.
130
+
131
+ **Example.**
132
+ ```yaml
133
+ version: 1.0.0
134
+ ```
135
+
136
+ **When to use.** Always — required.
137
+
138
+ **When NOT to use.** N/A — required.
139
+
140
+ ---
141
+
142
+ ## `type`
143
+
144
+ **Purpose.** Defines the behavioral archetype. The archetype determines which body H2 sections are required, how the skill is loaded by a router, and which schema conditionals apply.
145
+
146
+ **Allowed values.**
147
+
148
+ | Value | Meaning |
149
+ |---|---|
150
+ | `capability` | A standalone functional skill — what the agent can do. Required sections: `## Coverage`, `## Philosophy`, `## Verification`, `## Do NOT Use When`. |
151
+ | `workflow` | A step-by-step procedural skill. Adds `## Workflow` to the required sections. |
152
+ | `router` | A skill that dispatches to other skills. Uses `## Routing Rules` instead of `## Workflow`. |
153
+ | `overlay` | A skill that extends another skill. Requires `extends` and uses `## Overlay Rules` and `## Extends`. |
154
+
155
+ **Rules.**
156
+ - Keep `type` restricted to these four values.
157
+ - Use `category` (flat bucket) or `category` (hierarchical path) for browse taxonomy, not `type`.
158
+ - `overlay` type always requires the `extends` field.
159
+
160
+ **Example.**
161
+ ```yaml
162
+ type: capability
163
+ ```
164
+
165
+ **When to use.** Always — required.
166
+
167
+ **When NOT to use.** Do not invent new type values. If none of the four archetypes fit, use `capability` as the closest and note the variation in the `## Coverage` section.
168
+
169
+ **Lint check.** `scripts/skill-lint.js` enforces the archetype section map: missing required H2 sections produce an error; H2 sections present but containing fewer than 50 non-whitespace characters produce a warning. See `scripts/lint/check-archetype-sections.js`.
170
+
171
+ ---
172
+
173
+ ## `archetype`
174
+
175
+ **Purpose.** v3.1 preferred alias for `type`. Identical enum and semantics; the rename resolves sign-drift between the schema (`type`) and the doc body / ADR 0003 (which already say "archetype" everywhere) and removes a generic-name anti-pattern.
176
+
177
+ **Allowed values.** Identical to `type`: `capability`, `workflow`, `router`, `overlay`.
178
+
179
+ **Rules.**
180
+ - When both `type` and `archetype` are present, they must match. The lint will warn on mismatch.
181
+ - v3.x skills can set either form; v4 makes `archetype` canonical and removes `type`.
182
+
183
+ **Example.**
184
+ ```yaml
185
+ archetype: capability
186
+ ```
187
+
188
+ **When to use.** Prefer `archetype` for new skills authored against the v3.1 contract. Existing skills do not need to migrate during v3.x.
189
+
190
+ **Lint check.** Mismatch warning when both are set (planned). v4 will hard-error on `type`.
191
+
192
+ ---
193
+
194
+ ## `category`
195
+
196
+ **Purpose.** Flat human browse bucket for discovery and grouping. Does not imply runtime behavior or evaluation logic. Renamed from v3 `browse_category` in v4 so the public browse axis has the obvious name.
197
+
198
+ **Rules.**
199
+ - Required.
200
+ - Open-ended string; no enum is enforced.
201
+ - Use stable, human-readable buckets.
202
+ - Avoid one-off synonyms for the same idea (for example, pick `engineering` and stick to it; do not use `dev` in one skill and `engineering` in another).
203
+ - For hierarchical taxonomy (`ecommerce/integrations/shopify`), use the optional `domain` field. `category` is flat on purpose.
204
+
205
+ **Recommended values.**
206
+
207
+ | Value | Use for |
208
+ |---|---|
209
+ | `knowledge` | Domain expertise, reference skills |
210
+ | `engineering` | Code, architecture, infrastructure |
211
+ | `frontend` | UI, CSS, component patterns |
212
+ | `quality` | Testing, auditing, review |
213
+ | `integrations` | External APIs, webhooks, data sync |
214
+ | `security` | Security review and risk controls |
215
+ | `design` | UX, research, visual, and product design |
216
+
217
+ **Example.**
218
+ ```yaml
219
+ category: integrations
220
+ ```
221
+
222
+ **When to use.** Always. Even if the bucket is unusual, populate it so the skill appears in browse indexes.
223
+
224
+ **When NOT to use.** Do not use `category` for behavioral control; that is `type`'s job. Do not use it for activation-bundle membership; that is `routing_bundles`. Do not use it for hierarchical placement; that is `domain`.
225
+
226
+ **Migration from v3.** The field name changed from `browse_category` to `category` in v4 (values unchanged). Run `node scripts/migrate-skill-v3-to-v4.js` for the automatic rename.
227
+
228
+ ---
229
+
230
+ ## `domain`
231
+
232
+ **Purpose.** Hierarchical domain path as slash-delimited segments. Complements `category`: flat bucket and tree path answer different questions. A UI or docs site uses `domain` to render a folder tree; a filter UI uses `category` for quick grouping.
233
+
234
+ **Rules.**
235
+ - Optional.
236
+ - Lowercase alphanumeric segments separated by `/` (for example, `ecommerce/integrations/shopify`).
237
+ - Must match pattern `^[a-z0-9][a-z0-9-]*(/[a-z0-9][a-z0-9-]*)*$`.
238
+ - Do not use absolute paths, leading `/`, trailing `/`, `.`, or `..`.
239
+ - One skill, one path. Use `workspace_tags` or `routing_bundles` for secondary flat grouping.
240
+
241
+ **Example.**
242
+ ```yaml
243
+ domain: ecommerce/integrations/shopify
244
+ ```
245
+
246
+ **When to use.** When the skill library is large enough that a tree structure helps readers find related skills. A library with fewer than 20 skills rarely benefits.
247
+
248
+ **When NOT to use.** Small skill libraries where `category` alone is sufficient. Skills where categorization is genuinely ambiguous should use `workspace_tags` or `routing_bundles` to attach flat semantic tags instead.
249
+
250
+ ---
251
+
252
+ ## `scope`
253
+
254
+ **Purpose.** Indicates locality and usage mode. Tells the router and auditor whether the skill is fully portable, a documentation reference, or grounded in a specific codebase.
255
+
256
+ **Allowed values.**
257
+
258
+ | Value | Meaning | Requires `grounding`? |
259
+ |---|---|---|
260
+ | `portable` | Fully portable, no repo-specific claims | No |
261
+ | `reference` | Documentation-style skill grounded in protocol documents | No |
262
+ | `codebase` | Grounded in a specific codebase or deployment | **Yes** (schema-enforced) |
263
+
264
+ **Rules.**
265
+ - `scope: codebase` triggers a schema `allOf` rule that requires the `grounding` block. Lint fails without it.
266
+ - Do not use `overlay` as a scope value — use `type: overlay` and `extends` instead.
267
+ - Choose `portable` for starter skills and broadly reusable skills.
268
+ - The v1 names `generic` and `operational` were renamed in schema_version 2: `generic` → `portable` (the intent is "works anywhere"), and `operational` → `codebase` (the intent is "grounded in *this* codebase"). The v1 names are hard errors under the v2 schema.
269
+
270
+ **Example.**
271
+ ```yaml
272
+ scope: codebase
273
+ ```
274
+
275
+ **When to use.** Always — required.
276
+
277
+ **When NOT to use.** Do not use `codebase` for skills that make no concrete repo claims — use `portable` instead.
278
+
279
+ ---
280
+
281
+ ## `owner`
282
+
283
+ **Purpose.** Records who is responsible for keeping the skill current. Enables audit tooling to surface orphaned or unmaintained skills.
284
+
285
+ **Rules.**
286
+ - Free-form string — no enum is enforced.
287
+ - Use a stable identifier: a GitHub handle, a team name, or `maintainer` for shared ownership.
288
+ - For open-source skills with no single owner, use `community`.
289
+
290
+ **Example.**
291
+ ```yaml
292
+ owner: maintainer
293
+ ```
294
+
295
+ **When to use.** Always — required.
296
+
297
+ **When NOT to use.** Do not omit or use a placeholder like `TBD`. An unknown owner is still a real state — record the team that accepted the skill.
298
+
299
+ ---
300
+
301
+ ## `freshness`
302
+
303
+ **Purpose.** Records when the skill content was last meaningfully reviewed or updated. Drives staleness detection in audit tooling.
304
+
305
+ **Rules.**
306
+ - ISO 8601 date string (`YYYY-MM-DD`).
307
+ - Update this field whenever the skill body or frontmatter is substantively revised.
308
+ - Cosmetic edits (typos, formatting) do not require a `freshness` bump.
309
+ - A `freshness` date more than 90 days old is a signal for re-review.
310
+
311
+ **Example.**
312
+ ```yaml
313
+ freshness: "2026-04-15"
314
+ ```
315
+
316
+ **When to use.** Always — required.
317
+
318
+ **When NOT to use.** N/A — required. If you are unsure of the last review date, set it to the current date as an explicit "reviewed now" assertion.
319
+
320
+ ---
321
+
322
+ ## `reviewed_at`
323
+
324
+ **Purpose.** v3.1 preferred alias for `freshness`. Identical semantics; the rename uses the project's own `_at` date-field convention (per the `linguistics` skill) and removes the metaphorical phrasing ("freshness" is a property of food).
325
+
326
+ **Rules.**
327
+ - ISO 8601 date string (`YYYY-MM-DD`).
328
+ - When both `freshness` and `reviewed_at` are present, they must match.
329
+ - v3.x skills can set either; v4 makes `reviewed_at` canonical and removes `freshness`. ADR 0005 proposes a further consolidation with `drift_check.last_verified` in v4.
330
+
331
+ **Example.**
332
+ ```yaml
333
+ reviewed_at: "2026-05-12"
334
+ ```
335
+
336
+ ---
337
+
338
+ ## `drift_check`
339
+
340
+ **Purpose.** Records when the skill was last verified against its truth sources (code, docs, external specs) AND stores content hashes of those truth sources at the time of verification. The stored hashes turn `drift_check` from a self-asserted date into evidence the drift sentinel can verify. Distinct from `freshness` — a skill can be editorially fresh but technically drifted.
341
+
342
+ **Shape change in v3.** The v2 field was a date string. The v3 field is an object with a required `last_verified` date and an optional `truth_source_hashes` map. The v2 scalar form is rejected as a type error under v3; run `node scripts/migrate-skill-v2-to-v3.js` for an automatic upgrade.
343
+
344
+ **Rules.**
345
+ - Object with one required sub-field and one optional sub-field.
346
+ - `last_verified`: ISO 8601 date string (`YYYY-MM-DD`).
347
+ - `truth_source_hashes`: optional map of normalized truth-source key -> SHA-256 hex digest.
348
+ - Keys must match the normalized form produced from `grounding.truth_sources`: `path` for whole-file sources, `path#Lstart-Lend` for line ranges, and `path#anchor` for anchor-only sources. The drift sentinel (`scripts/skill-graph-drift.js`) reports DRIFT when any live hash differs from the recorded hash, BROKEN when a local truth source is missing, STALE when the lifecycle window is exceeded, NO_BASELINE when `truth_source_hashes` is absent but local truth sources are declared, and EXTERNAL_UNHASHED when a URL truth source is valid but not fetched by the zero-dependency sentinel.
349
+ - For `scope: portable` skills with no external truth sources, `drift_check.last_verified` equals `freshness` and `truth_source_hashes` is omitted.
350
+ - Record hashes with `node scripts/skill-graph-drift.js --record --apply <skill-path>`; preview without `--apply`.
351
+ - A `drift_check.last_verified` date significantly older than `freshness` is a warning sign that editorial updates have outpaced verification.
352
+
353
+ **Sub-fields.**
354
+
355
+ | Sub-field | Type | Meaning |
356
+ |---|---|---|
357
+ | `last_verified` | string (date) | ISO date of the most recent verification against truth sources |
358
+ | `truth_source_hashes` | object (string -> string) | Map of normalized truth-source key -> SHA-256 hex digest at the time of verification |
359
+
360
+ **Example.**
361
+ ```yaml
362
+ drift_check:
363
+ last_verified: "2026-04-17"
364
+ truth_source_hashes:
365
+ "src/integrations/shopify/client.ts": "c2a4b1e0...64-char-hex..."
366
+ "src/integrations/shopify/webhooks.ts#L40-L96": "7f81a3d2...64-char-hex..."
367
+ ```
368
+
369
+ **When to use.** Always — required.
370
+
371
+ **When NOT to use.** Do not fabricate hashes. If you cannot compute them with the drift tool, omit `truth_source_hashes` and accept a NO_BASELINE state until you can run the tool. URL truth sources are valid grounding references, but the built-in drift sentinel reports them as EXTERNAL_UNHASHED unless a separate fetch-and-hash workflow records evidence.
372
+
373
+ **Migration from v2.** v2 used a single date string: `drift_check: "2026-04-15"`. v3 requires an object: `drift_check:\n last_verified: "2026-04-15"`. The codemod handles this transformation automatically.
374
+
375
+ ---
376
+
377
+ ## `last_audited`
378
+
379
+ **Purpose.** ISO date of the most recent audit run that produced a recorded verdict for this skill. Part of the v6 Health Block — a flat set of top-level fields that surface audit state without requiring readers to parse nested audit artifact files.
380
+
381
+ **Rules.**
382
+ - Optional. ISO 8601 date string (`YYYY-MM-DD`).
383
+ - Set by the audit loop when it writes its verdict. Do not hand-author; let the audit tool write it.
384
+ - If absent, the skill has no recorded audit history.
385
+
386
+ **Example.**
387
+ ```yaml
388
+ last_audited: "2026-05-16"
389
+ ```
390
+
391
+ **When to use.** Set by `skill-audit.js` or the audit-loop pipeline. Authors do not need to set this manually.
392
+
393
+ **When NOT to use.** Do not fabricate or manually back-date. An absent field is more accurate than a guessed date.
394
+
395
+ ---
396
+
397
+ ## `last_changed`
398
+
399
+ **Purpose.** ISO date of the last meaningful content change to the SKILL.md. Distinct from `freshness` (editorial review date) and `last_audited` (audit run date). Part of the v6 Health Block.
400
+
401
+ **Rules.**
402
+ - Optional. ISO 8601 date string (`YYYY-MM-DD`).
403
+ - Updated when the skill body or frontmatter receives a substantive edit.
404
+ - Used by the drift sentinel to determine whether a post-audit change has invalidated the recorded `audit_verdict`.
405
+
406
+ **Example.**
407
+ ```yaml
408
+ last_changed: "2026-05-14"
409
+ ```
410
+
411
+ ---
412
+
413
+ ## `audit_verdict`
414
+
415
+ **Purpose.** The overall verdict from the most recent completed audit run. Part of the v6 Health Block.
416
+
417
+ **Allowed values.**
418
+
419
+ | Value | Meaning |
420
+ |---|---|
421
+ | `PASS` | All audit dimensions passed |
422
+ | `PASS_WITH_FIXES` | Passed after in-session corrections |
423
+ | `PARTIAL` | Some dimensions passed; others were deferred |
424
+ | `FAIL` | One or more audit dimensions failed |
425
+ | `UNKNOWN` | No audit has been run or the verdict is unavailable |
426
+
427
+ **Rules.**
428
+ - Optional. Defaults to `UNKNOWN` when absent.
429
+ - Written by the audit loop; do not hand-author.
430
+ - Paired with `last_audited` — if `last_audited` is set, `audit_verdict` should be set too.
431
+
432
+ **Example.**
433
+ ```yaml
434
+ audit_verdict: PASS
435
+ ```
436
+
437
+ ---
438
+
439
+ ## `eval_score`
440
+
441
+ **Purpose.** Numeric score from the most recent eval run, on the 0.0–5.0 scale used by `scripts/skill-audit.js`. Part of the v6 Health Block.
442
+
443
+ **Rules.**
444
+ - Optional. Float, range 0.0–5.0.
445
+ - Written by the graded audit; do not hand-author.
446
+ - Corresponds to the weighted average of dimension scores in the audit scorecard.
447
+
448
+ **Example.**
449
+ ```yaml
450
+ eval_score: 4.2
451
+ ```
452
+
453
+ ---
454
+
455
+ ## `eval_failed_ids`
456
+
457
+ **Purpose.** List of eval case IDs that failed in the most recent eval run. Part of the v6 Health Block. Enables fast lookup of which specific cases a skill is failing without opening the full scorecard.
458
+
459
+ **Rules.**
460
+ - Optional. Array of strings (eval case ID strings, matching `id` fields in the eval JSON).
461
+ - Empty array means all cases passed; absent means no eval has been run.
462
+ - Written by the graded audit; do not hand-author.
463
+
464
+ **Example.**
465
+ ```yaml
466
+ eval_failed_ids: ["case-03", "case-07"]
467
+ ```
468
+
469
+ ---
470
+
471
+ ## `lint_verdict`
472
+
473
+ **Purpose.** The verdict from the most recent lint run against this skill. Part of the v6 Health Block.
474
+
475
+ **Allowed values.**
476
+
477
+ | Value | Meaning |
478
+ |---|---|
479
+ | `PASS` | All lint checks passed |
480
+ | `FAIL` | One or more lint checks failed |
481
+ | `UNKNOWN` | No lint has been run or result is unavailable |
482
+
483
+ **Rules.**
484
+ - Optional. Defaults to `UNKNOWN` when absent.
485
+ - Written by `scripts/skill-lint.js` or the audit loop's Phase 1.
486
+
487
+ **Example.**
488
+ ```yaml
489
+ lint_verdict: PASS
490
+ ```
491
+
492
+ ---
493
+
494
+ ## `drift_status`
495
+
496
+ **Purpose.** The result of the most recent drift check for this skill. Part of the v6 Health Block.
497
+
498
+ **Allowed values.**
499
+
500
+ | Value | Meaning |
501
+ |---|---|
502
+ | `OK` | All truth source hashes match |
503
+ | `DRIFT` | At least one local truth source hash differs from the recorded baseline |
504
+ | `BROKEN` | At least one local truth source file is missing |
505
+ | `STALE` | The `last_verified` date exceeds the lifecycle window |
506
+ | `NO_BASELINE` | Local truth sources declared but no hashes recorded |
507
+ | `EXTERNAL_UNHASHED` | URL truth source present but not fetched and hashed |
508
+ | `UNKNOWN` | No drift check has been run |
509
+
510
+ **Rules.**
511
+ - Optional. Written by `scripts/skill-graph-drift.js`.
512
+ - Do not hand-author; let the drift tool write it.
513
+
514
+ **Example.**
515
+ ```yaml
516
+ drift_status: OK
517
+ ```
518
+
519
+ ---
520
+
521
+ ## `eval_artifacts`
522
+
523
+ **Purpose.** Declares the presence of eval artifact files for this skill. This is the "does an eval file exist on disk?" axis — independent of whether the eval has ever been run or is routed anywhere.
524
+
525
+ **Allowed values.**
526
+
527
+ | Value | Meaning | Artifact expectation |
528
+ |---|---|---|
529
+ | `none` | No eval work started or planned | No eval artifact expected |
530
+ | `planned` | Eval work intended but not yet authored | No eval artifact yet — temporary state |
531
+ | `present` | One or more eval files exist on disk | `scripts/skill-lint.js` verifies a file under `examples/evals/` carries the skill's `skill_name` |
532
+
533
+ **Rules.**
534
+ - `present` requires a real eval artifact. The lint script rejects a mismatch.
535
+ - `planned` is a temporary state — move to `present` once artifacts ship.
536
+ - `none` is reserved for skills where evals are genuinely not part of the plan (rare).
537
+
538
+ **Example.**
539
+ ```yaml
540
+ eval_artifacts: present
541
+ ```
542
+
543
+ **When to use.** Always — required.
544
+
545
+ **When NOT to use.** N/A — required. Do not inflate (`present` without a real file).
546
+
547
+ **Migration from v1.** The v1 `eval_status` enum mixed three orthogonal concerns; this field is the "artifact state" axis. See `docs/manifest-field-mapping.md § Migration Note — v1 → v2` for the full mapping (e.g. `eval_status: evals` → `eval_artifacts: present, eval_state: passing, routing_eval: absent`).
548
+
549
+ ---
550
+
551
+ ## `eval_state`
552
+
553
+ **Purpose.** Declares the current runtime verification state of the skill's evals. This is the "have the evals been run and passed recently?" axis — independent of whether the artifact file exists.
554
+
555
+ **Allowed values.**
556
+
557
+ | Value | Meaning |
558
+ |---|---|
559
+ | `unverified` | No passing run has been recorded for these evals |
560
+ | `passing` | A recent run exists and was green |
561
+ | `monitored` | Actively run in a live toolchain, continuously verified |
562
+
563
+ **Rules.**
564
+ - `passing` requires a concrete verification receipt (test output, CI run, or similar evidence).
565
+ - `monitored` requires a live toolchain that re-runs the evals on some cadence.
566
+ - Do not use `passing` without a recorded run — use `unverified` when the artifacts exist but have not been exercised.
567
+
568
+ **Example.**
569
+ ```yaml
570
+ eval_state: passing
571
+ ```
572
+
573
+ **When to use.** Always — required.
574
+
575
+ **When NOT to use.** N/A — required.
576
+
577
+ ---
578
+
579
+ ## `routing_eval`
580
+
581
+ **Purpose.** Declares whether routing / trigger coverage is explicitly evaluated for this skill. This is the "are we checking that the skill activates on the right prompts?" axis — independent of the content-level eval state captured by `eval_state`.
582
+
583
+ **Allowed values.**
584
+
585
+ | Value | Meaning |
586
+ |---|---|
587
+ | `absent` | Routing / trigger coverage is not evaluated for this skill |
588
+ | `present` | Routing / trigger coverage is part of the eval set |
589
+
590
+ **Rules.**
591
+ - `present` implies the eval artifacts include routing or trigger assertions, not just content quality.
592
+ - Most starter skills default to `absent` — routing coverage is a deeper authoring step.
593
+
594
+ **Enforcement.** As of [Unreleased], `routing_eval: present` is a verifiable claim. The harness at `scripts/skill-graph-routing-eval.js` runs every `examples[]` entry through `skill-graph-route.js` and asserts the skill wins; runs every `anti_examples[]` entry and asserts the winner is NOT this skill AND (if non-null) is named in `relations.boundary[]`. A skill that declares `present` must satisfy two lint gates (check 12 in `scripts/skill-lint.js`):
595
+
596
+ 1. Both `examples` and `anti_examples` are populated — the harness needs prompts to evaluate.
597
+ 2. Running `node scripts/skill-graph-routing-eval.js --skill <name>` returns verdict `PASS` for the skill.
598
+
599
+ A skill whose harness run contains any `FAIL` case cannot ship `present`; lint surfaces each failing prompt with the router's actual decision. A `COVERAGE_GAP` verdict (the anti-example correctly avoids this skill but no other skill absorbs it) is informational and does not block `present` — the anti-example did its job; the coverage-gap signal is for the next authoring iteration. Prefer `absent` until the harness agrees — honesty over green checkmarks.
600
+
601
+ **Current status of the starter library.** As of the `[Unreleased]` entry, all eight starters declare `routing_eval: present` and pass the harness 8-of-8 (verified by `node scripts/skill-graph-routing-eval.js --only-asserted`). Each starter's `examples[]` activate the skill correctly and each `anti_examples[]` route to the appropriate boundary owner. The route flips `present` were earned by tightening keywords, splitting `examples` from `anti_examples`, and populating `relations.boundary[]` with explicit handoff targets. New skills should default to `absent` until the harness agrees — honesty over green checkmarks remains the rule.
602
+
603
+ **Example (preferred — production starters).**
604
+ ```yaml
605
+ routing_eval: present
606
+ ```
607
+
608
+ **Example (acceptable for new authoring — flip to `present` once the harness passes).**
609
+ ```yaml
610
+ routing_eval: absent
611
+ ```
612
+
613
+ **When to use.** Always — required.
614
+
615
+ **When NOT to use.** N/A — required. Do not inflate (`present` without a routing harness that returns verdict PASS for the skill).
616
+
617
+ ---
618
+
619
+ ## `comprehension_state`
620
+
621
+ **Purpose.** Declares whether the skill carries a concept-comprehension grading surface in addition to routing and content evals.
622
+
623
+ **Allowed values.**
624
+
625
+ | Value | Meaning |
626
+ |---|---|
627
+ | `absent` | No comprehension grading is declared |
628
+ | `present` | A comprehension eval exists and the `concept` block is required |
629
+
630
+ **Rules.**
631
+ - Optional in v3. Omitted means `absent`.
632
+ - Independent of `routing_eval` and `eval_state`.
633
+ - `present` requires the top-level `concept` block by schema rule.
634
+
635
+ **Example.**
636
+ ```yaml
637
+ comprehension_state: present
638
+ ```
639
+
640
+ **When to use.** Use `present` only when the skill has a real comprehension eval and a filled concept teaching block.
641
+
642
+ **When NOT to use.** Do not set `present` for skills that only have routing examples or general eval artifacts.
643
+
644
+ ---
645
+
646
+ ## `concept`
647
+
648
+ **Purpose.** Seven-field teaching block for the skill's subject. It gives graders and agents a direct concept model: what the subject is, how to think about it, why it exists, what it is not, where it sits near other concepts, a useful analogy, and the common misconception to avoid.
649
+
650
+ **Rules.**
651
+ - Required when `comprehension_state: present`.
652
+ - Object with required `definition`, `mental_model`, `purpose`, `boundary`, `taxonomy`, `analogy`, and `misconception`.
653
+ - Keep this about the universal subject. The body `## Philosophy` explains why this skill exists in this repo.
654
+
655
+ **Example.**
656
+ ```yaml
657
+ concept:
658
+ definition: "Relational mapping is the practice of translating domain relationships into durable data structures."
659
+ mental_model: "Start from entities, cardinality, optionality, ownership, and lifecycle."
660
+ purpose: "It prevents persistence shape from smuggling in a false domain model."
661
+ boundary: "It is not database tuning, UI information architecture, or API envelope design."
662
+ taxonomy: "Prerequisite to data-modeling; adjacent to bounded-context-mapping."
663
+ analogy: "Like drawing load-bearing walls before choosing interior paint."
664
+ misconception: "A table diagram is not a domain model unless the relationships have domain meaning."
665
+ ```
666
+
667
+ **When to use.** Skills whose subject needs concept transfer, not just procedural steps.
668
+
669
+ **When NOT to use.** Pure execution wrappers where the body already contains all needed operational instruction and no concept grader exists.
670
+
671
+ ---
672
+
673
+ ## `mental_model`
674
+
675
+ **Purpose.** v6 flat form of `concept.mental_model`. The primitives, metaphors, or operative principles an agent needs to reason about this subject. Describes *how* to think about the subject — the reasoning substrate, not a procedure.
676
+
677
+ **Rules.**
678
+ - Optional. String.
679
+ - Required when `comprehension_state: present` and using the v6 flat form (instead of nested `concept` block).
680
+ - Must be distinct from `purpose` (which covers *why* the concept exists) and `boundary` (which covers *what it is not*).
681
+
682
+ **Example.**
683
+ ```yaml
684
+ mental_model: "Start from entities, cardinality, optionality, ownership, and lifecycle."
685
+ ```
686
+
687
+ **See also.** `concept` (v5 nested block), `purpose`, `boundary`.
688
+
689
+ ---
690
+
691
+ ## `purpose`
692
+
693
+ **Purpose.** v6 flat form of `concept.purpose`. The problem this concept solves and what it replaced or improved upon. Answers "why does this concept exist?"
694
+
695
+ **Rules.**
696
+ - Optional. String.
697
+ - Required when `comprehension_state: present` and using the v6 flat form.
698
+
699
+ **Example.**
700
+ ```yaml
701
+ purpose: "It prevents persistence shape from smuggling in a false domain model."
702
+ ```
703
+
704
+ ---
705
+
706
+ ## `boundary`
707
+
708
+ **Purpose.** v6 flat form of `concept.boundary`. An explicit statement of what the concept is **not** — adjacent concepts the agent might confuse it with.
709
+
710
+ **Rules.**
711
+ - Optional. String.
712
+ - Required when `comprehension_state: present` and using the v6 flat form.
713
+ - This field is the primary grader input for the C4 rubric dimension (adjacent-concept discrimination). Weight 1.5 in the schema — second highest.
714
+
715
+ **Example.**
716
+ ```yaml
717
+ boundary: "It is not database tuning, UI information architecture, or API envelope design."
718
+ ```
719
+
720
+ ---
721
+
722
+ ## `analogy`
723
+
724
+ **Purpose.** v6 flat form of `concept.analogy`. A single structural analogy that helps an agent grasp the concept's shape. Graded on both correct application AND correct identification of the analogy's limits (C6 rubric).
725
+
726
+ **Rules.**
727
+ - Optional. String.
728
+ - Required when `comprehension_state: present` and using the v6 flat form.
729
+ - Weight 0.5 in the schema — the lowest of the concept-block fields. Analogy is a teaching aid, not a load-bearing primitive.
730
+
731
+ **Example.**
732
+ ```yaml
733
+ analogy: "Like drawing load-bearing walls before choosing interior paint."
734
+ ```
735
+
736
+ ---
737
+
738
+ ## `misconception`
739
+
740
+ **Purpose.** v6 flat form of `concept.misconception`. The single most common wrong belief about the concept that agents and practitioners hold. Graded on whether the agent corrects it unprompted when the misconception is embedded in a probe (C7 rubric).
741
+
742
+ **Rules.**
743
+ - Optional. String.
744
+ - Required when `comprehension_state: present` and using the v6 flat form.
745
+ - Complements `boundary`: `boundary` describes adjacent concepts; `misconception` describes wrong beliefs *about this concept itself*.
746
+ - Not directly weighted in the schema; complements `boundary` (weight 1.5).
747
+
748
+ **Example.**
749
+ ```yaml
750
+ misconception: "A table diagram is not a domain model unless the relationships have domain meaning."
751
+ ```
752
+
753
+ ---
754
+
755
+ ## `eval_last_run`
756
+
757
+ **Purpose.** Optional receipt for the most recent eval run. It turns `eval_state: passing` or `eval_state: monitored` from a self-attested label into a pointer to evidence.
758
+
759
+ **Rules.**
760
+ - Optional in v3.1.
761
+ - Object with required `at` and `status`.
762
+ - `at` is an ISO date-time for the run that supports the current eval claim.
763
+ - `status` is one of `pass`, `fail`, or `mixed`.
764
+ - `runner`, `model`, `receipt`, and `receipt_hash` are optional evidence details.
765
+ - Do not set `eval_state: passing` solely because this object exists; the run still needs to satisfy the skill's eval contract.
766
+
767
+ **Example.**
768
+ ```yaml
769
+ eval_last_run:
770
+ at: "2026-05-12T09:30:00Z"
771
+ status: pass
772
+ runner: "node scripts/skill-audit.js --graded"
773
+ receipt: "examples/audits/documentation/scorecard.md"
774
+ ```
775
+
776
+ **When to use.** When a skill's eval has actually run and there is a scorecard, grader history, CI run, or other receipt worth preserving.
777
+
778
+ **When NOT to use.** Brand-new skills with `eval_state: unverified`, or skills whose last run cannot be traced to an artifact.
779
+
780
+ ---
781
+
782
+ ## `eval`
783
+
784
+ **Purpose.** v3.1 preferred nested form for the eval-health triple (`eval_artifacts` + `eval_state` + `routing_eval`). Aligns with the sibling-object pattern of `drift_check`, `grounding`, `lifecycle`, `portability`. Also resolves the head-first compound ambiguity of `routing_eval` (renamed to `routing_coverage`) and disambiguates `eval_state` from `routing_coverage` (renamed to `content_state`).
785
+
786
+ **Shape.**
787
+ ```yaml
788
+ eval:
789
+ artifacts: present # mirrors eval_artifacts — none | planned | present
790
+ content_state: passing # mirrors eval_state — unverified | passing | monitored
791
+ routing_coverage: present # mirrors routing_eval — absent | present
792
+ ```
793
+
794
+ **Rules.**
795
+ - Optional in v3.1 (the top-level triple is still the source of truth during v3.x).
796
+ - When both the nested `eval.*` fields and the top-level fields are present, they must match.
797
+ - v4 makes `eval` canonical and removes the top-level triple.
798
+
799
+ **When to use.** Prefer for new skills authored against v3.1. Setting both shapes is allowed but redundant.
800
+
801
+ ---
802
+
803
+ ## `stability`
804
+
805
+ **Purpose.** Communicates how mature and reliable the skill is. Helps consumers decide whether to depend on the skill in production workflows.
806
+
807
+ **Allowed values.**
808
+
809
+ | Value | Meaning |
810
+ |---|---|
811
+ | `experimental` | Under active development; API or content may change without notice |
812
+ | `stable` | Content is settled and expected to change only via versioned updates |
813
+ | `frozen` | No further changes planned; archived as-is |
814
+ | `deprecated` | Superseded by another skill; consumers should migrate |
815
+
816
+ **Rules.**
817
+ - Strongly recommended even though not schema-required.
818
+ - Omit only for skills where stability is genuinely unknown at authoring time (migrate to a real value quickly).
819
+ - A deprecated skill should add a note in `## Coverage` pointing to the replacement.
820
+
821
+ **Example.**
822
+ ```yaml
823
+ stability: stable
824
+ ```
825
+
826
+ **When to use.** For any skill intended to be used by others. Omit only if the skill is a draft that will be revised immediately.
827
+
828
+ **When NOT to use.** Do not use `frozen` for skills that might still need maintenance — `stable` is the correct choice for mature, actively-owned skills.
829
+
830
+ ---
831
+
832
+ ## `superseded_by`
833
+
834
+ **Purpose.** Names the skill that replaces this one when `stability: deprecated`. Consumers and routers use this to follow a deprecation chain automatically instead of reading the body prose.
835
+
836
+ **Rules.**
837
+ - Optional for non-deprecated skills.
838
+ - **Required when `stability: deprecated`** — enforced by the `allOf` rule in `skill.schema.json`. A deprecated skill without `superseded_by` fails schema validation.
839
+ - The value must be the `name` of an existing skill in the library. (Target-existence check follows the `relations.*` enforcement pattern and is expected to land in a future lint iteration.)
840
+ - Write a brief pointer in `## Coverage` as well so human readers see the migration path without re-parsing frontmatter.
841
+
842
+ **Example.**
843
+ ```yaml
844
+ stability: deprecated
845
+ superseded_by: new-skill-name
846
+ ```
847
+
848
+ **When to use.** On every skill entering the `deprecated` state, in the same commit that sets `stability: deprecated`.
849
+
850
+ **When NOT to use.** Non-deprecated skills. Do not declare a speculative replacement ahead of the deprecation event — it misleads routers.
851
+
852
+ **Migration from v2.** Added in v0.5.0 (additive — not a schema bump). Prior deprecated skills must retroactively populate `superseded_by` when they next get edited.
853
+
854
+ ---
855
+
856
+ ## `examples`
857
+
858
+ **Purpose.** Positive-class activation examples — a short list of realistic user prompts the skill SHOULD activate for. Complements `keywords` (semantic tokens) and `triggers` (exact labels) by giving routers full-prompt, few-shot retrieval targets.
859
+
860
+ **Rules.**
861
+ - Optional array of strings.
862
+ - 2–5 entries is the sweet spot. Fewer than 2 gives the router no discrimination signal; more than 5 dilutes the vector-search centroid.
863
+ - Write the examples in the user's voice — the prompt they would actually type — not in imperative abstract form.
864
+ - Each example should be a self-contained prompt, not a fragment (router embeddings cover the full string).
865
+ - Groups under `activation.examples` in the manifest projection.
866
+
867
+ **Example.**
868
+ ```yaml
869
+ examples:
870
+ - "how do I validate a webhook signature from Shopify?"
871
+ - "the HMAC check is failing for a real payload — what's wrong?"
872
+ - "add Stripe webhook signature verification to this route"
873
+ ```
874
+
875
+ **When to use.** Any skill that relies on natural-language routing at query time — the router cannot see the skill body, only the metadata. Routable skills without `examples` under-trigger at library scale (see SkillRouter paper, `.artifacts/audit-brief.md` for references).
876
+
877
+ **When NOT to use.** Internal helper skills activated only by label or path. Overlay skills that inherit their parent's activation.
878
+
879
+ **Migration from v2.** Added in v0.5.0 (additive — not a schema bump).
880
+
881
+ ---
882
+
883
+ ## `anti_examples`
884
+
885
+ **Purpose.** Negative-class activation examples — user prompts that look topically related to this skill but should activate a DIFFERENT skill instead. Used as hard-negative training signal by embedding routers to sharpen boundary discrimination.
886
+
887
+ **Rules.**
888
+ - Optional array of strings.
889
+ - Pair with `relations.boundary` — every `anti_examples` entry should correspond to a concrete other skill the router should route to. Name that skill in `relations.boundary` with an object-form `{skill, reason}` explaining why it owns that territory.
890
+ - Do not dump generic off-topic prompts here — this is not a blocklist. Use it only for near-misses the router keeps getting wrong.
891
+ - Groups under `activation.anti_examples` in the manifest projection.
892
+
893
+ **Example.**
894
+ ```yaml
895
+ anti_examples:
896
+ - "refactor this function to be more testable" # → refactor skill, not this one
897
+ - "why is my test failing after the refactor?" # → debugging skill
898
+ relations:
899
+ boundary:
900
+ - skill: refactor
901
+ reason: "refactor covers behavior-preserving code modification; this skill is test-strategy planning"
902
+ - skill: debugging
903
+ reason: "chasing a failure is debugging; planning is strategy"
904
+ ```
905
+
906
+ **When to use.** When the skill has documented confusables (near-miss activations) that the routing layer has gotten wrong. Write the anti-example list after you have seen the router misfire, not before — authoring anti-examples without real router data is speculative.
907
+
908
+ **When NOT to use.** Skills with no close-neighbor confusables. Skills that are activated only by exact label or path (routing is deterministic, not embedding-based).
909
+
910
+ **Migration from v2.** Added in v0.5.0 (additive — not a schema bump).
911
+
912
+ ---
913
+
914
+ ## `license`
915
+
916
+ **Purpose.** Declares the distribution license for the skill content. Required for any skill intended for public or cross-team sharing.
917
+
918
+ **Rules.**
919
+ - Free-form string — use a standard SPDX identifier where possible (`MIT`, `Apache-2.0`, `CC-BY-4.0`).
920
+ - Strongly recommended for all skills, even if the repo already has a top-level LICENSE file.
921
+ - Omit only for internal skills that are explicitly not intended for redistribution.
922
+
923
+ **Example.**
924
+ ```yaml
925
+ license: MIT
926
+ ```
927
+
928
+ **When to use.** Whenever a skill might be shared outside the immediate team or repo.
929
+
930
+ **When NOT to use.** Internal-only skills where no redistribution is expected — but prefer to include it even then, for clarity.
931
+
932
+ ---
933
+
934
+ ## `compatibility`
935
+
936
+ **Purpose.** Declares environment requirements for skills that have specific runtime needs — target agent runtimes, Node.js version, and free-text notes for anything else.
937
+
938
+ **Shape change in v3.** The v2 field was a free-text string up to 500 characters. The v3 field is a structured object so consumers can parse `runtimes` and `node` without heuristics. The scalar form is rejected as a type error under v3; run `node scripts/migrate-skill-v2-to-v3.js` to upgrade (the codemod moves the old string verbatim into `compatibility.notes`).
939
+
940
+ **Rules.**
941
+ - Object with up to three optional sub-fields.
942
+ - Omit the field entirely when the skill is fully generic with no environment requirements.
943
+ - `runtimes`: array of strings naming target agent runtimes with optional version constraints (e.g., `claude-code>=2.0`, `cursor>=0.40`). Use short stable identifiers.
944
+ - `node`: Node.js version constraint as a string (e.g., `>=18`).
945
+ - `notes`: free-text supplement, capped at 500 characters.
946
+
947
+ **Sub-fields.**
948
+
949
+ | Sub-field | Type | Meaning |
950
+ |---|---|---|
951
+ | `runtimes` | string[] | Target agent runtimes with optional version constraints |
952
+ | `node` | string | Node.js version constraint |
953
+ | `notes` | string (≤500 chars) | Free-text supplement |
954
+
955
+ **Example.**
956
+ ```yaml
957
+ compatibility:
958
+ runtimes:
959
+ - claude-code>=2.0
960
+ - cursor>=0.40
961
+ node: ">=18"
962
+ notes: Requires PostgreSQL 15+ when using the `neon` adapter.
963
+ ```
964
+
965
+ **When to use.** When the skill's instructions require a specific runtime, CLI tool, or package version that is not universally available.
966
+
967
+ **When NOT to use.** Generic skills with no runtime dependencies — omit the field rather than setting it to an empty object.
968
+
969
+ **Migration from v2.** The codemod (`scripts/migrate-skill-v2-to-v3.js`) transforms `compatibility: "<text>"` to `compatibility:\n notes: "<text>"`. Authors move the string into `runtimes` / `node` manually when the structured form is more accurate.
970
+
971
+ ---
972
+
973
+ ## `allowed-tools`
974
+
975
+ **Purpose.** Names the pre-approved tools a skill is permitted to invoke when loaded into an agent runtime that honors the declaration.
976
+
977
+ **Rules.**
978
+ - Space-separated string — not an array. The string form is required for Agent-Skills-compatible export.
979
+ - Use the tool names as defined by the target agent runtime (e.g., `Read`, `Grep`, `Bash` for Claude Code).
980
+ - This is experimental per the SKILL.md spec — support varies across agent implementations.
981
+ - Skill Graph validates the shape but does not enforce the allowlist at runtime.
982
+
983
+ **Example.**
984
+ ```yaml
985
+ allowed-tools: Read Grep Bash
986
+ ```
987
+
988
+ **When to use.** When deploying to a runtime that enforces tool allowlists and you want to declare the minimum required set.
989
+
990
+ **When NOT to use.** Skills where all tools are permitted (omit the field) or where the deployment runtime does not read this field.
991
+
992
+ ---
993
+
994
+ ## `allowed_tools`
995
+
996
+ **Purpose.** v3.1 preferred snake_case alias for `allowed-tools`. The kebab-case form is the only field in a snake_case schema; the alias removes that inconsistency on the authoring side. The export transform still writes the kebab-case form for SKILL.md consumers.
997
+
998
+ **Rules.**
999
+ - Space-separated string (same as `allowed-tools`).
1000
+ - When both forms are present, they must match.
1001
+ - v3.x skills can set either; v4 makes `allowed_tools` canonical for authoring. The export transform continues to write `allowed-tools` (kebab) for SKILL.md compatibility.
1002
+
1003
+ **Example.**
1004
+ ```yaml
1005
+ allowed_tools: Read Grep Bash
1006
+ ```
1007
+
1008
+ ---
1009
+
1010
+ ## `extends`
1011
+
1012
+ **Purpose.** Explicitly states which base skill an overlay extends. Required for all `type: overlay` skills.
1013
+
1014
+ **Rules.**
1015
+ - Must be the `name` value of an existing skill in the library.
1016
+ - `scripts/skill-lint.js` verifies the target exists.
1017
+ - Only valid when `type: overlay`. Setting `extends` on a non-overlay skill is an error.
1018
+
1019
+ **Example.**
1020
+ ```yaml
1021
+ type: overlay
1022
+ extends: shopify
1023
+ ```
1024
+
1025
+ **When to use.** When and only when `type: overlay`. The overlay inherits and specializes the base skill's content.
1026
+
1027
+ **When NOT to use.** Non-overlay skills. Do not use `extends` to express a dependency — use `relations.depends_on` for that.
1028
+
1029
+ ---
1030
+
1031
+ ## `triggers`
1032
+
1033
+ **Purpose.** Explicit phrase or label triggers that activate this skill. Complements `keywords` for skills that respond to exact phrases rather than semantic matching.
1034
+
1035
+ **Rules.**
1036
+ - Array of strings.
1037
+ - Use for exact activation phrases that the routing layer should match literally (e.g., skill IDs, CLI flags, label strings).
1038
+ - Prefer `keywords` for semantic matching; use `triggers` for exact-match activation.
1039
+
1040
+ **Example.**
1041
+ ```yaml
1042
+ triggers:
1043
+ - shopify-skill
1044
+ - use-shopify
1045
+ ```
1046
+
1047
+ **When to use.** When the skill has known exact trigger phrases (CLI commands, label names, template strings) that should reliably activate it.
1048
+
1049
+ **When NOT to use.** Generic concepts best expressed as `keywords`. If the phrase is conceptual rather than exact, put it in `keywords`.
1050
+
1051
+ ---
1052
+
1053
+ ## `keywords`
1054
+
1055
+ **Purpose.** Semantic keywords for discovery, search indexing, and activation routing. The primary signal for routers that use vector search or fuzzy matching.
1056
+
1057
+ **Rules.**
1058
+ - Array of strings.
1059
+ - Include topic synonyms, related concepts, and the primary use-case phrases a user would naturally type.
1060
+ - Do not duplicate `name` in keywords unless it is also a common search phrase.
1061
+ - Ordered from most specific to most general.
1062
+
1063
+ **Example.**
1064
+ ```yaml
1065
+ keywords:
1066
+ - shopify
1067
+ - shopify api
1068
+ - shopify webhook
1069
+ - e-commerce integration
1070
+ ```
1071
+
1072
+ **When to use.** Required for all routable skills. Omit only for internal helper skills that are never activated by user language.
1073
+
1074
+ **When NOT to use.** Keywords are not tags for browse taxonomy — that is `category` / `category`'s job. Do not add every possible synonym; keep to the 3–8 most likely search terms.
1075
+
1076
+ **Lint check.** `scripts/skill-lint.js` errors when `keywords` is absent or empty for a skill with `scope: codebase` or a non-empty `routing_bundles` field. Those skills are designed to be discovered by keyword routers and cannot be omitted. See `scripts/lint/check-routing-quality.js` (check R1).
1077
+
1078
+ ---
1079
+
1080
+ ## `paths`
1081
+
1082
+ **Purpose.** Filesystem glob patterns that identify the code surfaces this skill governs. Enables file-surface activation and diff-aware routing.
1083
+
1084
+ **Rules.**
1085
+ - Array of glob strings.
1086
+ - Use `**` for recursive matching within a directory.
1087
+ - Paths are relative to the repo root where the skill is deployed.
1088
+ - A skill activated by file path will load automatically when an agent edits a matching file.
1089
+
1090
+ **Example.**
1091
+ ```yaml
1092
+ paths:
1093
+ - src/integrations/shopify/**
1094
+ - src/webhooks/shopify.ts
1095
+ ```
1096
+
1097
+ **When to use.** For `scope: codebase` skills that govern specific files or directories. Omit for portable or reference skills.
1098
+
1099
+ **When NOT to use.** Generic skills with no specific file surfaces. Do not add paths as aspirational documentation — only add paths the skill actively covers.
1100
+
1101
+ ---
1102
+
1103
+ ## `workspace_tags`
1104
+
1105
+ **Purpose.** Declares which projects a skill is relevant to in a multi-project workspace. A skill without `workspace_tags` is ambient — it applies to every project. A skill with tags is filtered in or out by the router based on the active project.
1106
+
1107
+ **Taxonomy note.** `workspace_tags` answers "which of my projects is this skill relevant to?" `category` answers "where does this belong in a browse tree?" `routing_bundles` answers "which batch-activation group is this in?" Three fields, three different jobs, no overlap.
1108
+
1109
+ **Rules.**
1110
+ - Optional array of lowercase kebab-case tokens.
1111
+ - Each tag is either a literal project handle (whatever kebab-case name you give a project in your workspace config) or a semantic tag that multiple projects share (e.g., `ecommerce`, `saas`, `b2b`).
1112
+ - The workspace config at `.skill-graph/config.json` maps literal project handles to `semantic_tags`. A skill tagged with a semantic tag matches every project whose config expands to include that tag.
1113
+ - Absent `workspace_tags` means the skill is ambient — applies to every project. This is the default; use it for cross-cutting skills like GDPR, a11y, or test-driven-development.
1114
+
1115
+ **Example.**
1116
+ ```yaml
1117
+ # One specific project only — literal targeting
1118
+ workspace_tags: [<project-a>]
1119
+
1120
+ # Cross-ecommerce — every project whose workspace config maps to `ecommerce`
1121
+ workspace_tags: [ecommerce]
1122
+
1123
+ # Literal + semantic — precise match on <project-a>, semantic match on any ecommerce project
1124
+ workspace_tags: [<project-a>, ecommerce]
1125
+ ```
1126
+
1127
+ **Workspace config resolution.**
1128
+
1129
+ ```json
1130
+ // .skill-graph/config.json
1131
+ {
1132
+ "workspace": {
1133
+ "projects": {
1134
+ "<project-a>": { "semantic_tags": ["ecommerce", "saas"] },
1135
+ "<project-b>": { "semantic_tags": ["ecommerce", "b2c"] }
1136
+ }
1137
+ }
1138
+ }
1139
+ ```
1140
+
1141
+ A skill tagged `[ecommerce]` matches both projects. A skill tagged `[<project-a>]` only matches the first. A skill tagged `[saas]` only matches whichever projects' configs map to that semantic tag (the first, in this example).
1142
+
1143
+ **When to use.** When the workspace has more than one project and a skill's scope is clearly bound to a subset. Tag with semantic tags whenever possible — literal project handles couple the skill to a project name that may change.
1144
+
1145
+ **When NOT to use.** Single-project workspaces — omit the field. Cross-cutting skills that apply everywhere — omit the field. Do not use it as a substitute for `category` or `routing_bundles`; they answer different questions.
1146
+
1147
+ ---
1148
+
1149
+ ## `routing_bundles`
1150
+
1151
+ **Purpose.** Named routing group membership for batch activation and browse classification. Allows a router to load all skills in a group with a single label.
1152
+
1153
+ **Taxonomy note.** A routing group is a *classification tag* a router can consult to select a family of skills (e.g., `quality`, `security`, `integrations`). It is not a URL route, not an execution graph, and not a permission scope. The field was renamed from `route_bundles` in schema_version 2 (SH-5784) because the old name invited confusion with URL routing; the semantics did not change.
1154
+
1155
+ **Rules.**
1156
+ - Array of strings.
1157
+ - Group names are library-defined — establish a consistent vocabulary and document it in the library's README.
1158
+ - A skill can belong to multiple routing groups.
1159
+ - Use established groups before inventing new ones. Today's canonical group in this repo is `quality` (used by `testing-strategy`). Propose new groups in a PR before adopting them.
1160
+
1161
+ **Example.**
1162
+ ```yaml
1163
+ routing_bundles:
1164
+ - integrations
1165
+ - quality
1166
+ ```
1167
+
1168
+ **When to use.** When the skill belongs to a logical activation group (e.g., all `integrations` skills load together during an integration task, all `quality` skills load together during an audit).
1169
+
1170
+ **When NOT to use.** Skills that should only activate individually. Do not add routing groups speculatively — add them when a real routing pattern requires them.
1171
+
1172
+ **Migration from v1.** The v1 field name `route_bundles` is a hard error under the v2 schema. Rename the field to `routing_bundles`; values are unchanged.
1173
+
1174
+ **Lint check.** `scripts/skill-lint.js` errors when a skill has a non-empty `routing_bundles` field but an absent or empty `keywords` field. A skill designed for group-based batch activation must also be discoverable by keyword-based routers. See `scripts/lint/check-routing-quality.js` (check R1).
1175
+
1176
+ ---
1177
+
1178
+ ## `relations`
1179
+
1180
+ **Purpose.** Graph semantics between skills. Each key in the `relations` object describes a different type of relationship. Together they form the edges of the skill graph.
1181
+
1182
+ **Rules.**
1183
+ - Object with up to seven optional keys: `related` (preferred) / `adjacent` (deprecated alias), `broader`, `narrower`, `boundary`, `disjoint_with`, `verify_with`, `depends_on`.
1184
+ - Every target must be the `name` of an existing skill. `scripts/skill-lint.js` rejects dangling targets across all seven keys.
1185
+ - Relations are directional from the skill that declares them (A `depends_on` B means A depends on B, not the reverse). `related` is symmetric by SKOS convention; `boundary` is asymmetric (A `boundary: B` does not imply B `boundary: A`).
1186
+
1187
+ **Allowed keys.**
1188
+
1189
+ | Key | Meaning | Item shape | W3C mapping |
1190
+ |---|---|---|---|
1191
+ | `related` *(v3.1 preferred)* | Related skills for discoverability and recommended co-reading. Symmetric; no dependency implied. | string | `skos:related` |
1192
+ | `adjacent` *(deprecated alias of `related`)* | v3.0 name; still valid in v3.x. Lint warns. Removed in v4. | string | `skos:related` |
1193
+ | `broader` *(v3.1)* | Cross-skill generalisation — target is more general than this skill. Triggers Stage 4b parent recall in `scripts/skill-graph-route.js`. | string | `skos:broader` |
1194
+ | `narrower` *(v3.1)* | Cross-skill specialisation — target is more specific than this skill. Inverse of `broader`; not used to drive co-load (a parent match should not pull in arbitrary children). | string | `skos:narrower` |
1195
+ | `boundary` *(canonical, ADR 0006)* | Routing-layer asymmetric handoff — skills this skill explicitly does NOT own; the router uses this to redirect wrong-skill queries to the correct owner. | string OR `{skill, reason}` | `sg:disjointOwnership` |
1196
+ | `disjoint_with` *(v3.1, separate orthogonal relation per ADR 0006)* | Optional formal OWL class-disjointness assertion. Use only when authors genuinely want to claim that no entity can simultaneously be an instance of both classes. Rare; most authors only need `boundary`. | string OR `{skill, reason}` | `owl:disjointWith` |
1197
+ | `verify_with` | Skills that should be co-loaded for verification or that provide cross-checks | string | `prov:wasInformedBy` |
1198
+ | `depends_on` | Explicit dependency — this skill requires the target conceptually or operationally | string OR `{skill, min_version}` | `dcterms:requires` |
1199
+
1200
+ **Boundary vs disjoint_with — the ADR 0006 split.** ADR 0001 originally proposed renaming `boundary` to `disjoint_with` and treating them as aliases. ADR 0006 reverses that: the two predicates operate at different semantic layers and the schema keeps them distinct.
1201
+
1202
+ - `boundary` is a **routing-layer** claim. Skill A says "I am not the right answer for queries also matching B; route those to B." The router uses this for wrong-skill exclusion. Asymmetric; `reason` is strongly recommended; the canonical name for the everyday use case.
1203
+ - `disjoint_with` is a **formal class-theory** claim. A and B name disjoint conceptual classes; no entity can simultaneously be an instance of both. Maps to OWL `owl:disjointWith` for RDF consumers that reason about class membership. Rare in practice — most skill libraries never need this.
1204
+
1205
+ If you are unsure which to use, you want `boundary`. Use `disjoint_with` only when you have an explicit reason to make a formal ontological claim that survives the JSON-LD projection into OWL.
1206
+
1207
+ **Glossary.** See `docs/glossary.md § Relation predicates` for the formal definitions of each predicate, including the OntoClean rigidity tags for `extends` (which lives outside `relations` but participates in the same semantic space). The JSON-LD `@context` at `schemas/skill.context.jsonld` projects these predicates to their W3C equivalents for RDF consumers.
1208
+
1209
+ **Item shapes in v3.** `boundary`, `disjoint_with`, and `depends_on` accept both the bare-string form (v2-compatible) and the enriched object form (v3 addition). The bare form remains valid — upgrade item-by-item when a reason or version constraint is real.
1210
+
1211
+ - `boundary` and `disjoint_with` objects carry a `reason` string. The reason is what makes the relation self-documenting: `"fulfillment owns order state transitions; this skill only reads them"` beats `"fulfillment"` alone.
1212
+ - `depends_on` objects carry a `min_version` semver constraint. Useful when a skill depends on a specific version of another skill's contract.
1213
+ - `related`, `broader`, `narrower`, `verify_with` are bare-string only — they carry no additional metadata.
1214
+
1215
+ **When to use `broader` vs `extends`.** `extends` is overlay-only (`type: overlay`) and forms a single-parent existential-dependency chain (child ceases to have meaning without parent; ADR 0003). `broader` is cross-skill generalisation that does NOT imply existential dependency or overlay semantics — use it when the target is a more general concept but this skill has its own standalone identity. Example: `react-best-practices` has `broader: [frontend]` because it specialises frontend knowledge, but React-best-practices remains a coherent skill even if the `frontend` skill were deleted.
1216
+
1217
+ **Example (v3.1, SKOS-aligned preferred names + ADR 0006 boundary canonical).**
1218
+ ```yaml
1219
+ relations:
1220
+ related:
1221
+ - webhook-integration
1222
+ broader:
1223
+ - integration
1224
+ boundary:
1225
+ - skill: fulfillment
1226
+ reason: "fulfillment owns order state transitions; this skill only reads them"
1227
+ - skill: shipping
1228
+ reason: "shipping is covered by the shipping-integration skill"
1229
+ verify_with:
1230
+ - test-coverage
1231
+ depends_on:
1232
+ - skill: api-key-management
1233
+ min_version: "1.2.0"
1234
+ - testing-strategy
1235
+ ```
1236
+
1237
+ **Example (back-compat — `adjacent` still validates with a deprecation warning).**
1238
+ ```yaml
1239
+ relations:
1240
+ adjacent: # warns: rename to `related`
1241
+ - webhook-integration
1242
+ boundary: # canonical (no warning per ADR 0006)
1243
+ - skill: fulfillment
1244
+ reason: "fulfillment owns order state transitions; this skill only reads them"
1245
+ verify_with:
1246
+ - test-coverage
1247
+ depends_on:
1248
+ - api-key-management
1249
+ ```
1250
+
1251
+ **Example (rare — formal OWL class-disjointness assertion).**
1252
+ ```yaml
1253
+ relations:
1254
+ boundary: # routing-layer (everyday)
1255
+ - skill: error-tracking
1256
+ reason: "error-tracking owns observability surface; this skill is for prevention"
1257
+ disjoint_with: # formal class-theory (rare)
1258
+ - skill: physical-security
1259
+ reason: "Physical-security and information-security are disjoint conceptual classes by design"
1260
+ ```
1261
+
1262
+ **When to use.** Populate `related` and `boundary` for any skill that has clearly related or clearly excluded neighbours. Populate `broader` when the target is a more general standalone skill (router uses this for parent recall). Populate `depends_on` when the skill cannot function without another skill's concepts. Populate `verify_with` when a co-loaded skill improves verification quality. Populate `disjoint_with` only for explicit OWL-class-disjointness needs.
1263
+
1264
+ **When to use object form.** Use `{skill, reason}` whenever a `boundary` or `disjoint_with` entry's rationale isn't obvious from the skill name alone. Use `{skill, min_version}` when a dependency's contract has versioned — without the constraint, a future update to the target skill can silently break this skill's claims.
1265
+
1266
+ **When NOT to use.** Do not use `related` as a dumping ground for loosely related skills — keep it to the 2–4 most meaningful connections. Do not declare the same target under both `adjacent` and `related` (lint warns). Do not fabricate `min_version` values — if you don't know the constraint, omit it. Do not use `disjoint_with` as a more emphatic `boundary`; the OWL semantics are real and reaching for them changes how RDF consumers reason about your skill graph.
1267
+
1268
+ ---
1269
+
1270
+ ## `grounding`
1271
+
1272
+ **Purpose.** Declares what the skill governs in the real world or codebase, and provides evidence anchors for repo-grounded verification. Required for `scope: codebase` skills.
1273
+
1274
+ **Rules.**
1275
+ - Object with five required sub-fields: `domain_object`, `grounding_mode`, `truth_sources`, `failure_modes`, `evidence_priority`.
1276
+ - Omit entirely for `scope: portable` and `scope: reference` skills.
1277
+ - `grounding_mode` must be one of `repo_specific`, `universal`, or `hybrid`.
1278
+ - `evidence_priority` must be one of `repo_code_first`, `general_knowledge_first`, or `equal`.
1279
+
1280
+ **Sub-fields.**
1281
+
1282
+ | Sub-field | Type | Meaning |
1283
+ |---|---|---|
1284
+ | `domain_object` | string | The real-world or codebase entity this skill governs (e.g., "Shopify integration behavior") |
1285
+ | `grounding_mode` | enum | How the skill is grounded: `repo_specific` (one codebase), `universal` (language/framework), `hybrid` (both) |
1286
+ | `truth_sources` | string[] or object[] | Files, docs, URLs, or anchored source slices that are the ground truth for the skill's claims |
1287
+ | `failure_modes` | string[] | Known ways the skill can produce incorrect guidance if applied incorrectly |
1288
+ | `evidence_priority` | enum | Whether to trust repo code or general knowledge first when they conflict |
1289
+
1290
+ **Example.**
1291
+ ```yaml
1292
+ grounding:
1293
+ domain_object: Shopify integration behavior
1294
+ grounding_mode: repo_specific
1295
+ truth_sources:
1296
+ - path: src/integrations/shopify/client.ts
1297
+ line_range: { start: 42, end: 118 }
1298
+ note: "Admin API client behavior"
1299
+ - path: src/integrations/shopify/webhooks.ts
1300
+ anchor: webhook-signature-verification
1301
+ failure_modes:
1302
+ - webhook_signature_bypass
1303
+ - stale_cursor_pagination
1304
+ evidence_priority: repo_code_first
1305
+ ```
1306
+
1307
+ **Truth source forms.**
1308
+ - String entries remain valid for v3 compatibility and mean "hash/review the whole resource."
1309
+ - Object entries are preferred for repo-backed skills: `path` is required; `line_range`, `anchor`, and `note` are optional.
1310
+ - `line_range` hashes only the inclusive source slice after normalizing line endings to LF.
1311
+ - `anchor` is checked by lint as either a Markdown heading slug or literal text in the file.
1312
+ - `drift_check.truth_source_hashes` uses the normalized key: `path` for whole-file sources, `path#Lstart-Lend` for line ranges, and `path#anchor` for anchor-only sources.
1313
+
1314
+ **When to use.** Required for `scope: codebase`. Strongly recommended for any skill that makes concrete implementation claims, even if `scope` is `portable`.
1315
+
1316
+ **When NOT to use.** Portable skills with no specific codebase claims. Omit the entire block rather than populating it with placeholder values.
1317
+
1318
+ ---
1319
+
1320
+ ## `portability`
1321
+
1322
+ **Purpose.** Declares which agent runtimes the skill can be exported to, and an operational rating of how ready the skill is for export.
1323
+
1324
+ **Rules.**
1325
+ - Object with two required sub-fields: `readiness` and `targets`.
1326
+ - `readiness` must be `declared`, `scripted`, or `verified`. This is an operational axis, not an ordinal rating — each value says something concrete about what is true of the skill today.
1327
+ - `targets` is an array constrained to `["skill-md"]`.
1328
+ - `skill-md` in `targets` means the skill can be transformed to a valid SKILL.md file via `scripts/export-skill.js`.
1329
+ - Other runtimes — `cursor`, `windsurf`, `copilot`, `agents-md` — were removed from the enum in 0.3.0. They previously described compatibility goals, but without a working transform they violated the `additionalProperties: false` strictness rule. Re-add via a new RFC and the same PR that ships the transform.
1330
+
1331
+ **Sub-fields.**
1332
+
1333
+ | Sub-field | Type | Meaning |
1334
+ |---|---|---|
1335
+ | `readiness` | `declared` \| `scripted` \| `verified` | Operational export readiness — see values table below |
1336
+ | `targets` | string[] | Destination runtimes the skill is declared portable to |
1337
+
1338
+ **`readiness` values.**
1339
+
1340
+ | Value | Meaning | What must be true |
1341
+ |---|---|---|
1342
+ | `declared` | Portability is asserted in metadata only | The author claims the skill is portable to the listed targets; no export tooling has been run |
1343
+ | `scripted` | Export tooling exists for at least one target | A script (e.g., `scripts/export-skill.js`) can transform this skill to a listed target |
1344
+ | `verified` | Export tooling exists AND the exported output has been verified | A receipt artifact (test run, import check) proves the exported skill works in the target runtime |
1345
+
1346
+ **Example.**
1347
+ ```yaml
1348
+ portability:
1349
+ readiness: scripted
1350
+ targets:
1351
+ - skill-md
1352
+ ```
1353
+
1354
+ **When to use.** When the skill is intended for distribution via the SKILL.md transform, and you want to declare its portability explicitly.
1355
+
1356
+ **When NOT to use.** Internal-only skills that will never be exported. Omit the field rather than setting `readiness: declared` with an empty `targets` array.
1357
+
1358
+ **Migration from v1.** The v1 sub-fields `portability.level` (values `high`/`medium`/`low`) and `portability.exports` were renamed in schema_version 2 (SH-5784). Map `high` → `scripted` when an export script exists for a listed target, else `declared`. Map `medium` → `scripted` similarly. Map `low` → `declared`. Rename `portability.exports` → `portability.targets`; values are unchanged.
1359
+
1360
+ ---
1361
+
1362
+ ## `lifecycle`
1363
+
1364
+ **Purpose.** Per-skill maintenance policy consumed by the drift sentinel (`scripts/skill-graph-drift.js`). Declares how often the skill should be re-verified and after how many days it is considered stale. New in v3.
1365
+
1366
+ **Why it exists.** Integration skills rot faster than pure concept skills. A Shopify API skill might need quarterly review; a testing-strategy skill might be stable for years. A single global staleness threshold misrepresents both. `lifecycle.stale_after_days` lets each skill declare its own decay rate.
1367
+
1368
+ **Rules.**
1369
+ - Optional object with two optional sub-fields.
1370
+ - `stale_after_days`: positive integer. The drift sentinel flags the skill as STALE when `today - drift_check.last_verified > stale_after_days`.
1371
+ - `review_cadence`: enum hint for scheduled drift checks. The value does not affect schema validation; it signals to tooling when the skill wants to be re-verified.
1372
+
1373
+ **Sub-fields.**
1374
+
1375
+ | Sub-field | Type | Meaning |
1376
+ |---|---|---|
1377
+ | `stale_after_days` | integer (≥1) | Days after `drift_check.last_verified` at which the skill is flagged stale |
1378
+ | `review_cadence` | enum | `per-commit` \| `weekly` \| `quarterly` \| `on-truth-source-change` |
1379
+
1380
+ **Example.**
1381
+ ```yaml
1382
+ lifecycle:
1383
+ stale_after_days: 90
1384
+ review_cadence: quarterly
1385
+ ```
1386
+
1387
+ **When to use.** Any skill that makes concrete claims about external systems, APIs, or code that changes independently of the skill content.
1388
+
1389
+ **When NOT to use.** Purely conceptual skills where staleness is not a meaningful concept. In that case, omit the whole block rather than setting `stale_after_days` to an absurdly high value.
1390
+
1391
+ ---
1392
+
1393
+ ## `runtime_telemetry`
1394
+
1395
+ **Purpose.** Pointer to a real-world success/failure feed for this skill. Consumers may use telemetry to corroborate or override the authored `eval_state`. New in v3.
1396
+
1397
+ **Why it exists.** `eval_state` is self-reported — an author claims a skill's evals are passing. `runtime_telemetry` is external-reported — a feedback pipeline records actual success/failure rates from agents that ran the skill. Together they close the loop from "did the author claim this works?" to "does this actually work in the field?"
1398
+
1399
+ **Rules.**
1400
+ - Optional object.
1401
+ - `feedback_source` is required when the block is present. It is a path or URL to a JSONL of run receipts. Each receipt is expected to carry at minimum `{ timestamp, skill, outcome }`.
1402
+ - `last_updated` records when the block's `metrics` were last refreshed.
1403
+ - `metrics` is optional summary statistics derived from the feedback source. Consumers may read this pre-computed summary instead of re-parsing the JSONL.
1404
+
1405
+ **Sub-fields.**
1406
+
1407
+ | Sub-field | Type | Meaning |
1408
+ |---|---|---|
1409
+ | `feedback_source` | string | Path or URL to a JSONL of run receipts (required) |
1410
+ | `last_updated` | string (date) | ISO date of the most recent metrics refresh |
1411
+ | `metrics.sample_size` | integer (≥0) | Number of recorded runs used for the summary |
1412
+ | `metrics.success_rate` | number (0–1) | Fraction of runs with a positive outcome |
1413
+
1414
+ **Example.**
1415
+ ```yaml
1416
+ runtime_telemetry:
1417
+ feedback_source: "telemetry/skills/shopify.jsonl"
1418
+ last_updated: "2026-04-15"
1419
+ metrics:
1420
+ sample_size: 142
1421
+ success_rate: 0.87
1422
+ ```
1423
+
1424
+ **When to use.** When a telemetry pipeline actually exists for this skill and produces receipts the router or auditor can consume.
1425
+
1426
+ **When NOT to use.** Speculative feedback-source paths that do not yet exist. An empty `feedback_source` is worse than an absent block — it promises data that isn't there.