@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,103 @@
1
+ ---
2
+ # yaml-language-server: $schema=https://skillgraph.dev/schemas/skill.v4.schema.json
3
+ schema_version: 4
4
+ name: link-rot-detection
5
+ description: "Use when authoring or reviewing a periodic-scan job that walks every external link in a markdown content set and flags 404s, redirects to unrelated content, and connection failures. Activate this skill whenever the task says 'check our links' or mentions a link-rot scan, broken-link audit, or link-health report. Do NOT use for live runtime link checking inside the rendered page (use a frontend a11y / UX skill) or for chasing a specific broken-link incident from a user report (use debugging)."
6
+ version: 0.1.0
7
+ type: capability
8
+ category: content
9
+ domain: content/maintenance
10
+ scope: portable
11
+ owner: markdown-static-site-maintainer
12
+ freshness: "2026-05-06"
13
+ drift_check:
14
+ last_verified: "2026-05-06"
15
+ eval_artifacts: none
16
+ eval_state: unverified
17
+ routing_eval: absent
18
+ stability: experimental
19
+ license: MIT
20
+ compatibility:
21
+ runtimes:
22
+ - node
23
+ node: ">=20"
24
+ notes: "Portable across any markdown-content project; no codebase grounding required."
25
+ allowed-tools: Read Grep Bash
26
+ keywords:
27
+ - link rot
28
+ - link-rot detection
29
+ - broken link audit
30
+ - link health
31
+ - dead link scan
32
+ - 404 audit
33
+ - external link check
34
+ - periodic scan
35
+ - markdown link extraction
36
+ - link-rot report
37
+ triggers:
38
+ - link-rot-detection
39
+ examples:
40
+ - "design a periodic link-rot scan that runs nightly and posts a report"
41
+ - "review the link-rot detector — does it handle redirects correctly?"
42
+ - "explain how to test the link-rot scanner against a fixture set without hitting the network"
43
+ - "should the scan retry on transient 5xx, or only flag persistent failures?"
44
+ anti_examples:
45
+ - "validate this internal route in the live app"
46
+ - "the link to example.com just broke for one user"
47
+ - "design the rendering of broken-link badges in the UI"
48
+ relations:
49
+ boundary:
50
+ - skill: documentation
51
+ reason: "documentation writes prose about link-health policy; this skill enforces the detection primitive in code"
52
+ - skill: debugging
53
+ reason: "debugging chases a specific reported broken link; this skill is the periodic audit applied before user reports"
54
+ - skill: refactor
55
+ reason: "refactor changes scanner code shape; this skill enforces the detection contract that any refactor must preserve"
56
+ verify_with:
57
+ - testing-strategy
58
+ portability:
59
+ readiness: scripted
60
+ targets:
61
+ - skill-md
62
+ workspace_tags:
63
+ - content
64
+ - markdown
65
+ lifecycle:
66
+ stale_after_days: 180
67
+ review_cadence: quarterly
68
+ ---
69
+
70
+ # Link-Rot Detection
71
+
72
+ ## Coverage
73
+
74
+ - Markdown link extraction — pulling every `[text](url)` and `[text][ref]` reference link out of every `.md` and `.mdx` file in the content tree
75
+ - External vs internal classification — what counts as external (different host) and what gets skipped (relative path, anchor link, mailto, tel)
76
+ - Status-code interpretation — 200 is healthy, 301/308 is a redirect (record the new URL but don't fail), 302/307 is transient (re-check next run), 404/410 is dead (flag), 5xx is transient (retry with backoff before flagging)
77
+ - Soft-404 detection — pages that return HTTP 200 but render an "unknown page" interstitial (compare body length / content against known soft-404 patterns)
78
+ - Rate-limiting and politeness — concurrent request budget per origin host, honoring `robots.txt` crawl-delay, exponential backoff on 429
79
+ - Reporting shape — the scanner's output is a structured report (JSON + markdown summary), not a live alert; the report is the audit artifact
80
+
81
+ ## Philosophy
82
+
83
+ External links rot. Every site that's older than two years has at least a few. The choice is between knowing about them on a schedule or finding out from a user. A periodic scan with a published report turns link health into a maintenance task instead of an emergency. The discipline is to be conservative — distinguish persistent failures (404 across 3 runs) from transient ones (one 503 on a Tuesday) — and to never let the scanner itself become a denial-of-service vector against the targets it's checking.
84
+
85
+ ## Verification
86
+
87
+ Before merging any change to the link-rot scanner or its config:
88
+
89
+ - [ ] The scanner extracts every link in `[text](url)` and `[text][ref]` form from `.md` and `.mdx` files; reference links resolve their targets before classification
90
+ - [ ] Internal links (relative paths, same-host absolute, anchors, mailto, tel) are explicitly excluded — confirmed by a fixture test with mixed link types
91
+ - [ ] Persistent failures are distinguished from transient ones — a link is only flagged after N consecutive failures across separate runs (default N=3)
92
+ - [ ] The scanner respects per-host concurrency limits and honors `robots.txt` crawl-delay; a single host getting many requests in tight sequence is a bug
93
+ - [ ] Soft-404 detection has a defined pattern set and an explicit "unknown" bucket for cases that don't match any known soft-404
94
+ - [ ] The scanner produces both a JSON report (machine-readable) and a markdown summary (human-readable) with link, status code, last-seen-OK timestamp, and recommendation
95
+
96
+ ## Do NOT Use When
97
+
98
+ | Use instead | When |
99
+ |---|---|
100
+ | (a frontend a11y / UX skill) | The task is rendering a "this link may be broken" badge in the live UI |
101
+ | `debugging` | A specific link broke for a specific user and you need to reproduce |
102
+ | `documentation` | The task is writing the link-health policy doc, not the scanner |
103
+ | `refactor` | The task is restructuring the scanner without changing the detection contract |
@@ -0,0 +1,133 @@
1
+ ---
2
+ # yaml-language-server: $schema=https://skillgraph.dev/schemas/skill.v4.schema.json
3
+ schema_version: 4
4
+ name: markdown-post-frontmatter-validation
5
+ description: "Use when authoring or reviewing the frontmatter of a markdown post — checking required fields (title, date, slug, tags), validating against the content schema in `lib/content/schema.ts`, catching ambiguous date formats or tags not in the controlled vocabulary, and ensuring the slug matches the file path. Activate this skill whenever the task touches files under `content/posts/**/*.md`, the `parsePostFrontmatter()` helper, or any code path that reads YAML frontmatter from a content file. Do NOT use for general YAML schema design (use a generic schema-design skill) or for chasing a specific build-time validation failure (use debugging)."
6
+ version: 0.1.0
7
+ type: capability
8
+ category: content
9
+ domain: content/markdown/frontmatter
10
+ scope: codebase
11
+ owner: markdown-static-site-maintainer
12
+ freshness: "2026-05-06"
13
+ drift_check:
14
+ last_verified: "2026-05-06"
15
+ eval_artifacts: none
16
+ eval_state: unverified
17
+ routing_eval: absent
18
+ stability: experimental
19
+ license: MIT
20
+ compatibility:
21
+ runtimes:
22
+ - node
23
+ node: ">=20"
24
+ notes: "Astro / Next / Eleventy / Hugo all read YAML frontmatter; the validation pattern is portable across them."
25
+ allowed-tools: Read Grep
26
+ keywords:
27
+ - markdown frontmatter
28
+ - post frontmatter
29
+ - frontmatter validation
30
+ - content schema
31
+ - parsePostFrontmatter
32
+ - YAML frontmatter
33
+ - title required
34
+ - tag vocabulary
35
+ - slug mismatch
36
+ - date format
37
+ - controlled vocabulary
38
+ - markdown post metadata
39
+ triggers:
40
+ - markdown-post-frontmatter-validation
41
+ paths:
42
+ - "content/posts/**/*.md"
43
+ - "lib/content/schema.ts"
44
+ - "lib/content/parse-frontmatter.ts"
45
+ - "!**/*.test.md"
46
+ examples:
47
+ - "validate the frontmatter of a new post against our content schema"
48
+ - "why does the build fail when I add a tag like `Politics` (capital P)?"
49
+ - "review this post's frontmatter — is the date format correct?"
50
+ - "explain how the slug is derived from the file path"
51
+ anti_examples:
52
+ - "design a YAML schema for a different domain"
53
+ - "the build is failing — what's the actual error?"
54
+ - "rewrite parsePostFrontmatter for performance"
55
+ relations:
56
+ boundary:
57
+ - skill: documentation
58
+ reason: "documentation writes prose explaining the frontmatter format; this skill enforces the validation contract in code"
59
+ - skill: debugging
60
+ reason: "debugging chases a specific build-time validation failure from logs; this skill is the authoring discipline applied before failure"
61
+ - skill: refactor
62
+ reason: "refactor changes code shape; this skill enforces a specific validation contract that must survive any refactor"
63
+ verify_with:
64
+ - testing-strategy
65
+ grounding:
66
+ domain_object: "Markdown post frontmatter — the YAML block at the top of every content file that drives the site's index, routing, and rendering"
67
+ grounding_mode: repo_specific
68
+ truth_sources:
69
+ - content/posts/_template.md
70
+ - lib/content/schema.ts
71
+ - lib/content/parse-frontmatter.ts
72
+ failure_modes:
73
+ - missing_required_title_field
74
+ - ambiguous_date_format_no_timezone
75
+ - tag_not_in_controlled_vocabulary
76
+ - slug_mismatch_with_file_path
77
+ - frontmatter_block_not_terminated
78
+ evidence_priority: repo_code_first
79
+ portability:
80
+ readiness: scripted
81
+ targets:
82
+ - skill-md
83
+ workspace_tags:
84
+ - content
85
+ - static-site
86
+ - markdown
87
+ lifecycle:
88
+ stale_after_days: 90
89
+ review_cadence: quarterly
90
+ ---
91
+
92
+ # Markdown Post Frontmatter Validation
93
+
94
+ ## Coverage
95
+
96
+ - Required-field enforcement — every post must declare `title`, `date`, `slug`, and `tags`; missing fields fail the build at parse time
97
+ - Date format discipline — ISO 8601 with explicit timezone (`2026-05-06T12:00:00Z`); ambiguous formats like `2026-05-06` or `5/6/26` are rejected
98
+ - Slug-to-path consistency — the `slug` field must match the post's directory name; out-of-sync slugs cause silent route conflicts
99
+ - Controlled-vocabulary tagging — every tag in the post's `tags` array must appear in `lib/content/tag-vocabulary.ts`; lowercase, hyphen-separated, no synonyms
100
+ - Schema evolution — when `lib/content/schema.ts` changes, every post's frontmatter is re-validated; existing posts that violate the new schema are flagged before the next build runs
101
+ - Reserved-field protection — fields like `_id`, `_internal`, or any underscore-prefixed key are reserved for the build pipeline and rejected in author-facing frontmatter
102
+
103
+ ## Philosophy
104
+
105
+ The frontmatter block is the contract every post makes with the site's index, the router, and the renderer. If that contract is loose — if posts can omit fields, use ambiguous dates, or invent ad-hoc tags — the index drifts, routes silently overlap, and the search surface degrades. The cost of catching frontmatter bugs at build time is one re-run; the cost of catching them in production is a broken page or a missing entry in the archive. The rule is: validate at parse time, fail loud, and keep the schema small enough that authors can hold it in their head.
106
+
107
+ ## Key Files
108
+
109
+ | File | Purpose |
110
+ |---|---|
111
+ | `content/posts/_template.md` | The canonical template every new post copies — its frontmatter is the worked example of every required field |
112
+ | `lib/content/schema.ts` | The TypeScript schema (Zod or equivalent) that runtime validation calls |
113
+ | `lib/content/parse-frontmatter.ts` | The thin wrapper that reads the YAML block and runs `schema.parse()` — the failure surface for build-time errors |
114
+
115
+ ## Verification
116
+
117
+ Before merging any change to a post's frontmatter or to the schema:
118
+
119
+ - [ ] Every post has the four required fields: `title`, `date`, `slug`, `tags`
120
+ - [ ] `date` is ISO 8601 with timezone (no naked `YYYY-MM-DD`, no locale-formatted dates)
121
+ - [ ] `slug` matches the post's directory name exactly — not derived from `title` at runtime
122
+ - [ ] Every tag in `tags` is present in `lib/content/tag-vocabulary.ts` (run `npm run check:tags` to confirm)
123
+ - [ ] No underscore-prefixed fields (`_id`, `_internal`, etc.) — those are reserved for the pipeline
124
+ - [ ] Schema changes (`lib/content/schema.ts`) are paired with a `npm run validate:posts` pass against the entire `content/posts/**/*.md` set
125
+
126
+ ## Do NOT Use When
127
+
128
+ | Use instead | When |
129
+ |---|---|
130
+ | (a generic schema-design skill) | The task is designing a new YAML schema for an unrelated domain |
131
+ | `debugging` | A specific build is failing and you need to reproduce the validation error from logs |
132
+ | `documentation` | The task is writing a runbook or contributor doc about the frontmatter format |
133
+ | `refactor` | The task is restructuring `parse-frontmatter.ts` without changing the validation contract |
@@ -0,0 +1,140 @@
1
+ ---
2
+ # yaml-language-server: $schema=https://skillgraph.dev/schemas/skill.v4.schema.json
3
+ schema_version: 4
4
+ name: migrate-posts-to-v2-frontmatter
5
+ description: "Use when migrating every existing post in `content/posts/**/*.md` to the v2 frontmatter schema — adding the new required `summary` field, normalizing `tags` to the controlled vocabulary, converting bare-date `date` strings to ISO 8601 with timezone, and re-validating every post against the v2 schema before the next build runs. Activate this skill whenever the task references migration `0007-frontmatter-v2`, the v2 frontmatter rollout, or asks how to safely change a required-field set across a populated content tree without breaking the build. Do NOT use for unrelated migrations (use a generic content-migration skill or write a fresh one) or for general schema-design questions (use a schema-design skill)."
6
+ version: 0.1.0
7
+ type: workflow
8
+ category: content
9
+ domain: content/migrations
10
+ scope: codebase
11
+ owner: markdown-static-site-maintainer
12
+ freshness: "2026-05-06"
13
+ drift_check:
14
+ last_verified: "2026-05-06"
15
+ eval_artifacts: none
16
+ eval_state: unverified
17
+ routing_eval: absent
18
+ stability: experimental
19
+ license: MIT
20
+ compatibility:
21
+ runtimes:
22
+ - node
23
+ node: ">=20"
24
+ notes: "Markdown content tree under content/posts/; assumes Zod or similar runtime validator."
25
+ allowed-tools: Read Grep Bash
26
+ keywords:
27
+ - migrate posts
28
+ - frontmatter v2 migration
29
+ - 0007 frontmatter v2
30
+ - content schema migration
31
+ - tag vocabulary normalization
32
+ - bare-date conversion
33
+ - safe content migration
34
+ - post backfill
35
+ - frontmatter migration
36
+ triggers:
37
+ - migrate-posts-to-v2-frontmatter
38
+ paths:
39
+ - "scripts/migrate-frontmatter-v2.ts"
40
+ - "lib/content/schema.ts"
41
+ - "lib/content/tag-vocabulary.ts"
42
+ examples:
43
+ - "run the v2 frontmatter migration on every post in `content/posts/`"
44
+ - "the v2 migration's tag-normalization step is rejecting some valid tags — what's safe to do?"
45
+ - "verify that every post passes the v2 schema before flipping the validator"
46
+ - "design migration 0008 to drop the legacy `excerpt` field now that `summary` is canonical"
47
+ anti_examples:
48
+ - "design a new frontmatter schema for a different domain"
49
+ - "the migration is failing in CI — what's wrong?"
50
+ - "write the v2 frontmatter doc for new contributors"
51
+ relations:
52
+ boundary:
53
+ - skill: documentation
54
+ reason: "documentation writes prose explaining the schema migration; this workflow is the procedural enforcement"
55
+ - skill: debugging
56
+ reason: "debugging chases a specific migration failure from logs; this workflow is the pre-failure procedure"
57
+ - skill: refactor
58
+ reason: "refactor changes code shape with no behavior change; a content-schema migration changes the validation contract — different problem, different gates"
59
+ verify_with:
60
+ - testing-strategy
61
+ depends_on:
62
+ - skill: testing-strategy
63
+ min_version: "^1.0.0"
64
+ grounding:
65
+ domain_object: "The 0007 frontmatter-v2 migration — a multi-step procedure that adds a required field, normalizes the tag vocabulary, converts bare-date strings to ISO 8601, and re-validates every post against the v2 schema before the validator is flipped"
66
+ grounding_mode: repo_specific
67
+ truth_sources:
68
+ - scripts/migrate-frontmatter-v2.ts
69
+ - lib/content/schema.ts
70
+ - lib/content/tag-vocabulary.ts
71
+ failure_modes:
72
+ - validator_flipped_before_backfill_complete
73
+ - tag_normalization_drops_a_valid_tag_silently
74
+ - bare_date_conversion_picks_wrong_timezone
75
+ - migration_runs_outside_dry_run_gate_first
76
+ - rollback_step_overwrites_authored_summary_field
77
+ evidence_priority: repo_code_first
78
+ portability:
79
+ readiness: scripted
80
+ targets:
81
+ - skill-md
82
+ workspace_tags:
83
+ - content
84
+ - static-site
85
+ - migrations
86
+ lifecycle:
87
+ stale_after_days: 30
88
+ review_cadence: quarterly
89
+ ---
90
+
91
+ # Migrate Posts to v2 Frontmatter
92
+
93
+ ## Coverage
94
+
95
+ - The four-phase pattern for adding a required field to a populated content tree — *add as nullable → backfill from existing data → verify → flip the validator to require it* — and why collapsing any two phases into one is unsafe
96
+ - The backfill query — generating a `summary` from each post's first paragraph, with a per-post manual-override fallback for cases where the auto-summary is wrong
97
+ - The verification gate between backfill and validator-flip — running `validate-posts.ts` against the entire `content/posts/**/*.md` tree must return zero errors before the schema is updated
98
+ - The tag-normalization step — mapping every tag to its canonical form in `tag-vocabulary.ts`, with a deny-list for tags that should be removed entirely (e.g., legacy synonyms now folded into a canonical tag)
99
+ - The dry-run gate — the migration script always runs in dry-run by default, printing the diff per post; the `--apply` flag is opt-in and never the CI default
100
+ - The rollback path — what `ROLLBACK.md` for this migration looks like and why "regenerate every summary" is wrong (overwrites authored summaries); the correct rollback restores the per-post `.bak` file the migration writes alongside each edit
101
+
102
+ ## Philosophy
103
+
104
+ A content-schema migration is a rare migration where being careful is cheaper than being clever. The temptation to combine the four phases into one "atomic" pass fails because the backfill produces some surprising auto-summaries, the human reviewer needs time to override them, and flipping the validator before the human pass is done means every build between then and the override fails. The four-phase pattern is verbose but unambiguous: each phase has a clear success criterion, each phase is re-runnable, and the rollback at any phase is well-defined. Pay the verbosity cost; the alternative is a build outage on a non-emergency migration.
105
+
106
+ ## Workflow
107
+
108
+ Each step has a clear precondition and a clear success criterion. Do not skip steps; the steps exist because skipping them is how content migrations corrupt authored data.
109
+
110
+ | Step | Precondition | Action | Success criterion |
111
+ |---|---|---|---|
112
+ | 1. Add nullable `summary` | The schema has no `summary` field | `lib/content/schema.ts`: add `summary: z.string().optional()` (no `required`). Deploy. | The schema accepts posts both with and without `summary`; the build does not fail on existing posts. |
113
+ | 2. Backfill | Step 1 deployed | Run `scripts/migrate-frontmatter-v2.ts --apply --field summary` which generates a draft summary per post from the first paragraph and writes a `.bak` for each modified file. | Verification query reports 0 posts where `summary` is null or empty. |
114
+ | 3. Human review of auto-summaries | Step 2 success | Each post author reviews their auto-summary. Override by editing the post's frontmatter manually; the migration script will not re-run on a post whose `summary` was edited after step 2's `.bak` was written. | Author sign-off recorded in `audits/0007-frontmatter-v2/sign-off.md`. |
115
+ | 4. Flip the validator | Step 3 sign-off committed | `lib/content/schema.ts`: change `summary: z.string().optional()` to `summary: z.string().min(40)` (required, with a minimum length). Deploy. | Builds fail on any post that doesn't pass the v2 schema; the failure surface is the build log, not user-facing pages. |
116
+
117
+ ### When to back out
118
+
119
+ - Step 2 backfill produces too many surprising auto-summaries → reduce the auto-summary rule (e.g., first-sentence-only); the migration is still safe to resume from the same `.bak` set.
120
+ - Step 3 reveals that some posts genuinely have no extractable summary → those posts need authored summaries before step 4; do NOT flip the validator with placeholder summaries in place.
121
+ - Step 4 is flipped and the build fails on a post whose summary was edited but didn't trip the `min(40)` floor → revert step 4 (`.optional()` again), have the author rewrite the summary, re-flip.
122
+
123
+ ## Verification
124
+
125
+ - [ ] Step 1 added the field as `.optional()`, not as required
126
+ - [ ] Step 2 was run with `--apply` only after a `--dry-run` was reviewed (the dry-run output is committed under `audits/0007-frontmatter-v2/dry-run.md`)
127
+ - [ ] Step 2's `.bak` files exist for every modified post and are committed (so rollback is a one-command restore)
128
+ - [ ] Step 3 sign-off is recorded for every post in `content/posts/**/*.md` — no post moved past step 3 without explicit author confirmation
129
+ - [ ] Step 4 was applied AFTER step 3 sign-off — never before, even if the author backlog is taking longer than expected
130
+ - [ ] The rollback path in `ROLLBACK.md` does NOT include "regenerate every summary" — that overwrites authored content. Rollback is `mv <post>.md.bak <post>.md` per file, with the `.bak`s already committed.
131
+ - [ ] An end-to-end CI test runs the migration in dry-run mode against the live `content/posts/` set and reports the diff in the PR description before any human merges step 4
132
+
133
+ ## Do NOT Use When
134
+
135
+ | Use instead | When |
136
+ |---|---|
137
+ | `markdown-post-frontmatter-validation` | The task is reviewing or authoring a single post's frontmatter, not the migration that adds a new required field |
138
+ | `debugging` | A specific migration step is failing in CI and you need to reproduce |
139
+ | `documentation` | The task is writing a runbook or contributor doc about the migration |
140
+ | (a generic migration skill) | The task is a different content migration with no relation to the v2 frontmatter rollout |
@@ -0,0 +1,208 @@
1
+ # saas-stripe-postgres — Skill Graph Example Project
2
+
3
+ This directory is an OSS specimen demonstrating Skill Graph on a realistic SaaS stack: Next.js App Router + Stripe webhooks + Postgres with row-level security. It is a documentation artifact, not a maintained starter kit.
4
+
5
+ **Purpose:** Show developers how to author, relate, and route skills for a payment-integrated, multi-tenant SaaS — so they can build their own skill library using the same patterns.
6
+
7
+ ---
8
+
9
+ ## Skill Graph Structure
10
+
11
+ Five specimen skills, each representing a distinct layer of the stack:
12
+
13
+ ```
14
+ stripe-webhook-signature-verification
15
+ │ depends_on ──────────────────────────────────────┐
16
+ │ boundary with nextjs-server-action-validation │
17
+ │ verify_with nextjs-server-action-validation │
18
+ ▼ ▼
19
+ payment-provider-router postgres-rls-pattern
20
+ │ depends_on │ verify_with
21
+ │ stripe-webhook-signature-verification│ migrate-orders-to-canonical-schema
22
+ ▼ ▼
23
+ nextjs-server-action-validation migrate-orders-to-canonical-schema
24
+ │ depends_on postgres-rls-pattern │ depends_on postgres-rls-pattern
25
+ │ boundary stripe-webhook-... │ boundary payment-provider-router
26
+ ```
27
+
28
+ | Skill | Type | Scope | Domain |
29
+ |---|---|---|---|
30
+ | `stripe-webhook-signature-verification` | capability | portable | engineering/payments |
31
+ | `postgres-rls-pattern` | capability | portable | engineering/database |
32
+ | `nextjs-server-action-validation` | capability | portable | engineering/web |
33
+ | `payment-provider-router` | router | portable | engineering/payments |
34
+ | `migrate-orders-to-canonical-schema` | workflow | codebase | engineering/database |
35
+
36
+ ---
37
+
38
+ ## Routing Trace
39
+
40
+ **Query:** "How do I safely handle a Stripe webhook in a Next.js API route?"
41
+
42
+ This is the kind of question that activates multiple skills in sequence. Here is the routing trace showing which skills fire and why:
43
+
44
+ ```
45
+ Input: "How do I safely handle a Stripe webhook in a Next.js API route?"
46
+
47
+ Step 1 — Router resolves candidates:
48
+ MATCH stripe-webhook-signature-verification
49
+ trigger: "stripe-webhook-signature-verification"
50
+ keywords: ["stripe webhook signature verification",
51
+ "webhook hmac verification",
52
+ "stripe constructEvent"]
53
+ score: HIGH
54
+
55
+ MATCH payment-provider-router
56
+ keywords: ["payment event routing", "stripe event type dispatch"]
57
+ score: MEDIUM
58
+
59
+ NO MATCH nextjs-server-action-validation
60
+ anti_examples: ["validate the stripe-signature header in a
61
+ webhook route handler"]
62
+ → excluded by anti_example match
63
+
64
+ NO MATCH postgres-rls-pattern
65
+ → no keyword/trigger overlap with webhook routing
66
+
67
+ Step 2 — Relation graph consulted:
68
+ stripe-webhook-signature-verification.depends_on → postgres-rls-pattern
69
+ (idempotency key INSERT runs inside orgQuery)
70
+ → postgres-rls-pattern co-activated at lower priority
71
+
72
+ stripe-webhook-signature-verification.boundary → payment-provider-router
73
+ (verification is a precondition for routing)
74
+ → payment-provider-router activated as step 2
75
+
76
+ Step 3 — Activation order:
77
+ 1. stripe-webhook-signature-verification ← verify authenticity
78
+ 2. payment-provider-router ← route to handler
79
+ 3. postgres-rls-pattern ← query layer (co-activated)
80
+
81
+ Output: Three skills activated in dependency order.
82
+ ```
83
+
84
+ **Paste-able verification** (run from `examples/projects/saas-stripe-postgres/`):
85
+
86
+ ```bash
87
+ # Verify the 5 skills pass schema validation (run from skill-graph repo root)
88
+ cd ~/Development/skill-graph
89
+ node scripts/skill-lint.js \
90
+ examples/projects/saas-stripe-postgres/skills/stripe-webhook-signature-verification/SKILL.md \
91
+ examples/projects/saas-stripe-postgres/skills/postgres-rls-pattern/SKILL.md \
92
+ examples/projects/saas-stripe-postgres/skills/nextjs-server-action-validation/SKILL.md \
93
+ examples/projects/saas-stripe-postgres/skills/payment-provider-router/SKILL.md \
94
+ examples/projects/saas-stripe-postgres/skills/migrate-orders-to-canonical-schema/SKILL.md
95
+ ```
96
+
97
+ Expected output (all 5 pass T5):
98
+ ```
99
+ OK [T5] stripe-webhook-signature-verification/SKILL.md
100
+ OK [T5] postgres-rls-pattern/SKILL.md
101
+ OK [T5] nextjs-server-action-validation/SKILL.md
102
+ OK [T5] payment-provider-router/SKILL.md
103
+ OK [T5] migrate-orders-to-canonical-schema/SKILL.md
104
+ 5 file(s) checked, 0 error(s)
105
+ ```
106
+
107
+ ---
108
+
109
+ ## What Each Skill Demonstrates
110
+
111
+ ### `stripe-webhook-signature-verification` — Skill Graph Contract: Pushy Description + Negative Boundary
112
+
113
+ The description reads as a command: "Use when validating incoming Stripe webhook requests... Do NOT use for general HTTP signature validation (use a generic crypto-signature skill)."
114
+
115
+ This is the Skill Graph pattern for descriptions: pushy trigger phrase + explicit negative boundary. Claude tends to under-trigger skills with polite descriptions ("This skill provides..."). Command-form descriptions force the router to match.
116
+
117
+ ### `postgres-rls-pattern` — Skill Graph Contract: Portability
118
+
119
+ `scope: portable` + `portability.readiness: portable` declares this skill is codebase-agnostic. The orgQuery wrapper pattern works on any Postgres + Node.js project without modification.
120
+
121
+ ### `nextjs-server-action-validation` — Skill Graph Contract: Anti-Examples
122
+
123
+ The `anti_examples` field prevents false positives:
124
+ ```yaml
125
+ anti_examples:
126
+ - "validate the stripe-signature header in a webhook route handler"
127
+ ```
128
+ Without this, the router might activate this skill for a webhook validation query — both are about "validation". The anti_example explicitly signals: if the user is asking about `stripe-signature`, route to `stripe-webhook-signature-verification` instead.
129
+
130
+ ### `payment-provider-router` — Skill Graph Contract: Router Archetype + Depends-On
131
+
132
+ `type: router` activates the router archetype section map: `## Coverage`, `## Routing Rules`, `## Do NOT Use When` (no Philosophy section). The `depends_on` relation declares that `stripe-webhook-signature-verification` must run before this router sees the event.
133
+
134
+ ### `migrate-orders-to-canonical-schema` — Skill Graph Contract: Grounding
135
+
136
+ `scope: codebase` + `grounding.truth_sources` anchors this skill to actual files in the example project (`db/migrations/0004_canonicalize_orders.sql`, `db/schema.sql`). When those files change, the drift sentinel flags the skill as potentially stale. This is how Skill Graph prevents skills from becoming documentation that drifts from the code.
137
+
138
+ ---
139
+
140
+ ## Drift-Check Baseline
141
+
142
+ The drift sentinel records a content hash for `truth_sources` files. When either file changes, the skill's `drift_check.last_verified` becomes stale.
143
+
144
+ To record the current baseline (run from skill-graph repo root):
145
+
146
+ ```bash
147
+ node scripts/skill-graph-drift.js \
148
+ --record \
149
+ --apply \
150
+ examples/projects/saas-stripe-postgres/skills/migrate-orders-to-canonical-schema
151
+ ```
152
+
153
+ The command reads the `truth_sources` paths from the skill frontmatter, hashes the file contents, and writes the hashes to `drift_check.truth_source_hashes`. Future runs of `npm run drift` compare the live hashes against the recorded baseline and report STALE when they diverge.
154
+
155
+ After recording, the skill frontmatter gains a `truth_source_hashes` block:
156
+
157
+ ```yaml
158
+ drift_check:
159
+ last_verified: "2026-05-18"
160
+ truth_source_hashes:
161
+ examples/projects/saas-stripe-postgres/db/migrations/0004_canonicalize_orders.sql: "sha256:<hash>"
162
+ examples/projects/saas-stripe-postgres/db/schema.sql: "sha256:<hash>"
163
+ ```
164
+
165
+ ---
166
+
167
+ ## Skills Referenced vs. Skills in This Project
168
+
169
+ The 5 skills cross-reference each other via `relations`. They also reference skills from the main Skill Graph library (e.g., `documentation`, `refactor`) via the `boundary` predicate — those skills must exist in the configured skill root (`../skills/skills/`) for the lint check to pass.
170
+
171
+ **Skills referenced from the library root** (must exist in `../skills/skills/`):
172
+
173
+ | Referenced by | Skill referenced | Via predicate |
174
+ |---|---|---|
175
+ | (all skills) | Standard library skills | (none in this example — intra-project only) |
176
+
177
+ These 5 specimens only cross-reference each other. They are self-contained within the example project.
178
+
179
+ ---
180
+
181
+ ## File Structure
182
+
183
+ ```
184
+ examples/projects/saas-stripe-postgres/
185
+ ├── README.md ← this file
186
+ ├── db/
187
+ │ ├── schema.sql ← canonical table + RLS policy definitions
188
+ │ └── migrations/
189
+ │ └── 0004_canonicalize_orders.sql ← Phase 1+2 of orders canonicalization
190
+ └── skills/
191
+ ├── stripe-webhook-signature-verification/SKILL.md
192
+ ├── postgres-rls-pattern/SKILL.md
193
+ ├── nextjs-server-action-validation/SKILL.md
194
+ ├── payment-provider-router/SKILL.md
195
+ └── migrate-orders-to-canonical-schema/SKILL.md
196
+ ```
197
+
198
+ ---
199
+
200
+ ## Why These 5 Skills?
201
+
202
+ These specimens were chosen by the IMPROVEMENT_PLAN 2026-05-06 board meeting (U19 edit) to demonstrate Skill Graph's contract on a realistic stack:
203
+
204
+ - **Stripe webhook + RLS + Server Action** covers the three most common "how do I do this securely?" questions in a SaaS codebase
205
+ - **Payment router** demonstrates the `type: router` archetype, distinct from `capability` and `workflow`
206
+ - **Migration** demonstrates `scope: codebase` grounding and the four-phase procedure pattern — the hardest migration category to get right
207
+
208
+ Each skill is a specimen for learning, not a production recommendation. The patterns are generic; adopt them and adapt them to your own codebase.
@@ -0,0 +1,37 @@
1
+ -- Migration 0004: Canonicalize orders table
2
+ -- Changes: Stripe-specific column names → provider-agnostic names
3
+ -- stripe_session_id → provider_order_id
4
+ -- stripe_customer_id → provider_customer_id
5
+ -- (new) provider column set to 'stripe' for all existing rows
6
+ --
7
+ -- SAFE MIGRATION — four-phase procedure:
8
+ -- Phase 1: Add nullable columns (this file, deploy first)
9
+ -- Phase 2: Backfill data (this file, run after Phase 1 deploys)
10
+ -- Phase 3: Update application code to read new columns (manual, 24h observation)
11
+ -- Phase 4: Drop legacy columns (separate migration file 0004b)
12
+ --
13
+ -- Do NOT run Phase 4 (0004b) until 0 reads of stripe_session_id appear in logs
14
+ -- for at least 24 hours after Phase 3 application deployment.
15
+
16
+ -- ─── Phase 1: Add nullable canonical columns ─────────────────────────────────
17
+ ALTER TABLE orders
18
+ ADD COLUMN IF NOT EXISTS provider TEXT,
19
+ ADD COLUMN IF NOT EXISTS provider_order_id TEXT,
20
+ ADD COLUMN IF NOT EXISTS provider_customer_id TEXT;
21
+
22
+ -- ─── Phase 2: Backfill from Stripe-specific columns ──────────────────────────
23
+ -- Run: psql $DATABASE_URL -f 0004_canonicalize_orders.sql
24
+ -- Or: node scripts/migrate-orders.ts --apply (dry-run by default)
25
+
26
+ UPDATE orders
27
+ SET
28
+ provider = 'stripe',
29
+ provider_order_id = stripe_session_id,
30
+ provider_customer_id = stripe_customer_id
31
+ WHERE provider IS NULL;
32
+
33
+ -- Verify: SELECT COUNT(*) FROM orders WHERE provider IS NULL;
34
+ -- Expected: 0 rows
35
+
36
+ -- ─── Phase 4 is in 0004b_drop_legacy_columns.sql ────────────────────────────
37
+ -- Only run 0004b after Phase 3 observation period (24h, zero old-column reads).