@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,187 @@
1
+ ---
2
+ name: client-server-boundary
3
+ description: "Use when reasoning about the line at which execution context changes between a server runtime and a client runtime: what values can cross via serialization, what cannot, the directives that mark transitions (`'use client'`, `'use server'`), the difference between server-rendered HTML and a serialized component tree, the trust model that treats client input as adversarial, and the consequences of leaking server-only modules into client bundles. Do NOT use for when and where the UI is produced (use rendering-models), the HTTP wire protocol itself (use http-semantics), how to organize the frontend codebase (use frontend-architecture), or how to design the JSON shape of an API endpoint (use api-design)."
4
+ license: MIT
5
+ allowed-tools: Read Grep
6
+ metadata:
7
+ metadata: "{\"schema_version\":6,\"version\":\"1.0.0\",\"type\":\"capability\",\"category\":\"engineering\",\"domain\":\"engineering/frontend\",\"scope\":\"reference\",\"owner\":\"skill-graph-maintainer\",\"freshness\":\"2026-05-15\",\"drift_check\":\"{\\\\\\\"last_verified\\\\\\\":\\\\\\\"2026-05-15\\\\\\\"}\",\"eval_artifacts\":\"planned\",\"eval_state\":\"unverified\",\"routing_eval\":\"absent\",\"comprehension_state\":\"present\",\"stability\":\"experimental\",\"keywords\":\"[\\\\\\\"client server boundary\\\\\\\",\\\\\\\"serialization boundary\\\\\\\",\\\\\\\"use client directive\\\\\\\",\\\\\\\"use server directive\\\\\\\",\\\\\\\"React Server Components\\\\\\\",\\\\\\\"server actions\\\\\\\",\\\\\\\"RPC\\\\\\\",\\\\\\\"serializable types\\\\\\\",\\\\\\\"structured clone\\\\\\\",\\\\\\\"secret leakage\\\\\\\",\\\\\\\"client bundle\\\\\\\",\\\\\\\"hydration boundary\\\\\\\"]\",\"triggers\":\"[\\\\\\\"can I pass this function as a prop\\\\\\\",\\\\\\\"why is my server-only module in the client bundle\\\\\\\",\\\\\\\"what does 'use client' actually do\\\\\\\",\\\\\\\"is it safe to put this secret in a server component\\\\\\\",\\\\\\\"why won't this Date / Map / class serialize\\\\\\\"]\",\"examples\":\"[\\\\\\\"decide whether a piece of data must cross the network or can stay server-only\\\\\\\",\\\\\\\"diagnose why a component marked as a server component is being shipped to the client\\\\\\\",\\\\\\\"review whether secrets in server code can leak through serialized props\\\\\\\",\\\\\\\"design which functions are exposed as server actions and which stay internal\\\\\\\"]\",\"anti_examples\":\"[\\\\\\\"decide whether a route should be SSG or SSR (use rendering-models)\\\\\\\",\\\\\\\"design HTTP authentication headers (use http-semantics)\\\\\\\",\\\\\\\"design the JSON shape of an API response body (use api-design)\\\\\\\"]\",\"relations\":\"{\\\\\\\"related\\\\\\\":[\\\\\\\"rendering-models\\\\\\\",\\\\\\\"http-semantics\\\\\\\",\\\\\\\"frontend-architecture\\\\\\\",\\\\\\\"type-safety\\\\\\\",\\\\\\\"api-design\\\\\\\"],\\\\\\\"boundary\\\\\\\":[{\\\\\\\"skill\\\\\\\":\\\\\\\"rendering-models\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"rendering-models owns the staging of work across build/request/stream/interaction. client-server-boundary owns the serialization frontier — what can cross between server code and client code. The two compose: any rendering model that emits a server-produced artifact for client consumption faces a boundary.\\\\\\\"},{\\\\\\\"skill\\\\\\\":\\\\\\\"http-semantics\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"http-semantics owns the wire protocol (verbs, status codes, headers, caching). client-server-boundary is upstream — it decides what data exists at the boundary and how it is encoded into request and response bodies.\\\\\\\"},{\\\\\\\"skill\\\\\\\":\\\\\\\"api-design\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"api-design owns the external API surface (versioning, REST/GraphQL choice, endpoint shape). client-server-boundary owns the in-program boundary between a unified frontend codebase's server and client halves — a tighter, framework-mediated boundary than a public API.\\\\\\\"},{\\\\\\\"skill\\\\\\\":\\\\\\\"type-safety\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"type-safety owns the discipline of compile-time type checking. client-server-boundary is one of the places where the type system stops — values crossing the boundary lose their type until parsed.\\\\\\\"}],\\\\\\\"verify_with\\\\\\\":[\\\\\\\"type-safety\\\\\\\",\\\\\\\"api-design\\\\\\\"]}\",\"mental_model\":\"|\",\"purpose\":\"|\",\"boundary\":\"|\",\"analogy\":\"The client-server boundary is to a unified codebase what an embassy boundary is to a city — both spaces exist in the same physical address, but inside the embassy the law of one country applies (server: full filesystem, secret access, database), outside the law of another applies (client: browser sandbox, no secrets), and everyone crossing must pass through documented customs (serialization) with their bags inspected (validation) and stamped (authentication).\",\"misconception\":\"|\",\"concept\":\"{\\\\\\\"definition\\\\\\\":\\\\\\\"The client-server boundary is the line in a unified codebase at which execution context changes — between a server runtime (full filesystem, secret access, database connections) and a client runtime (browser, no filesystem, no server secrets, untrusted by the server). Anything that crosses the boundary must be serialized: encoded as bytes on one side, decoded into a value on the other. The boundary is marked by directives, enforced by the framework, and made invisible to the developer who treats it correctly.\\\\\\\",\\\\\\\"mental_model\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"purpose\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"boundary\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"taxonomy\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"analogy\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"misconception\\\\\\\":\\\\\\\"|\\\\\\\"}\",\"skill_graph_source_repo\":\"https://github.com/jacob-balslev/skill-graph\",\"skill_graph_protocol\":\"Skill Metadata Protocol v5\",\"skill_graph_project\":\"Skill Graph\",\"skill_graph_canonical_skill\":\"skills/client-server-boundary/SKILL.md\"}"
8
+ skill_graph_source_repo: "https://github.com/jacob-balslev/skill-graph"
9
+ skill_graph_protocol: Skill Metadata Protocol v4
10
+ skill_graph_project: Skill Graph
11
+ skill_graph_canonical_skill: skills/client-server-boundary/SKILL.md
12
+ ---
13
+
14
+ # Client-Server Boundary
15
+
16
+ ## Coverage
17
+
18
+ The line in a unified codebase at which execution context changes between server and client. Covers the three governing properties (serialization, direction, trust), the wire formats currently in use (JSON, structured clone, RSC payload, FormData), the directives that mark the boundary (`'use client'`, `'use server'`, framework-specific equivalents), the trust asymmetry that makes client→server crossings categorically different from server→client, the leakage modes (server-only modules, secrets, hidden imports) that an unmarked boundary creates, and the misconceptions that arise from treating the boundary as either invisible or as a TypeScript-checked contract.
19
+
20
+ ## Philosophy
21
+
22
+ The boundary always exists. Even an old PHP application with a templated HTML response has a server runtime and a client runtime separated by a wire protocol; the boundary is the network. What modern frameworks add is not the boundary itself, but the markers that make it visible — directives that say "this code is for over there" and serializers that say "these bytes will arrive on the other side as this shape."
23
+
24
+ The discipline of the boundary is to take seriously the asymmetry between sides:
25
+
26
+ - Server code can read secrets; client code cannot.
27
+ - Server code receives requests; client code makes them.
28
+ - Server code trusts itself; client code is trusted by the server only after validation.
29
+ - Server code can import any module; client code can import only what the bundler shipped.
30
+
31
+ A program that treats the two sides as interchangeable will leak secrets, ship broken code, and trust adversaries. A program that marks the boundary explicitly will pay a small upfront cost in ceremony and gain a large benefit in legibility and refactor safety.
32
+
33
+ The goal of this skill is to make the boundary an object of explicit thought — not a thing to work around, but a thing to design with.
34
+
35
+ ## Directives — The Boundary Made Syntactic
36
+
37
+ | Directive | Where it goes | What it means |
38
+ |---|---|---|
39
+ | `'use client'` | Top of a `.tsx` or `.ts` file | This file is the first client module in its import graph. Everything it imports becomes part of the client bundle. The framework will server-render it for first paint, then ship it to the client. |
40
+ | `'use server'` | Top of a `.ts` file or first line of a function body | The functions in this file (or this specific function) become server actions — RPC handlers callable from the client. The function body executes on the server; the client invokes it via a network call. |
41
+ | `import 'server-only'` | A line at the top of a server-intended module | A static import that causes the bundler to error if this module ends up in the client bundle. A guardrail, not a directive. |
42
+ | `import 'client-only'` | A line at the top of a client-intended module | Symmetric: errors if the module ends up in the server bundle. Useful for code that touches `window`, `document`, or other browser-only globals. |
43
+
44
+ The directives are not the boundary; they are the marks that make the boundary visible. A file without `'use client'` in an App Router project is implicitly a server component — the absence is meaningful.
45
+
46
+ ## Serialization — What Can Cross
47
+
48
+ | Wire format | Allowed types | Disallowed types |
49
+ |---|---|---|
50
+ | Plain JSON | string, number, boolean, null, plain objects, arrays | undefined, functions, Dates (become strings), Maps, Sets, Symbols, BigInts, class instances, circular references |
51
+ | Structured clone (postMessage, IndexedDB) | All JSON + Date, RegExp, Blob, File, FileList, ImageData, Map, Set, ArrayBuffer, typed arrays | Functions, DOM nodes, Error objects (partial), class instances with non-cloneable internals |
52
+ | RSC payload (React Server Components) | All structured-clone + Promises, JSX trees, server-action function references (as opaque tokens) | Arbitrary closures, classes with private fields, host-environment-bound objects |
53
+ | FormData (multipart/form-data) | string key/value, File/Blob | Nested structure (must encode as JSON inside a string field), non-string non-file values |
54
+
55
+ The practical rule: **if you cannot describe the value in terms of bytes, it cannot cross.** A `Map<string, User>` can cross structured-clone but not JSON; serialize to an array of `[key, value]` pairs for JSON.
56
+
57
+ ## Trust — The Asymmetric Boundary
58
+
59
+ The two directions across the boundary have categorically different trust profiles.
60
+
61
+ **Server → client.** The server emits a payload. The payload is trusted by its producer (the server) and consumed as data by the client. The client cannot tamper with the payload in transit (TLS), but can read everything inside it and use the contents however the client code chooses.
62
+
63
+ Implications:
64
+ - Do not put server secrets in the payload. The client will see them.
65
+ - Do not assume the client will *not* call a function in the payload. If the payload says "this user is an admin," the client UI may render an admin panel; if a security check depends on it, that check must be repeated on the server.
66
+ - The payload is a window into the server's state model. Keep it minimal.
67
+
68
+ **Client → server.** The client emits a request. The request crosses the trust boundary; every byte is adversarial. The server must:
69
+
70
+ - Parse the request structurally (the bytes may not be the expected shape).
71
+ - Validate the contents semantically (the values may not be in the expected range).
72
+ - Authenticate the requester (cookies, tokens — themselves potentially forged).
73
+ - Authorize the action (the authenticated requester may not have permission for this operation).
74
+ - Rate-limit (the client may be a script).
75
+
76
+ Server actions look like local function calls when invoked from a client component. They are not. They are RPC handlers with a network in front of them and a hostile caller on the other side of the network.
77
+
78
+ ## Common Leakage Modes
79
+
80
+ | Leakage mode | What goes wrong | How to prevent |
81
+ |---|---|---|
82
+ | Secret in a shared module | `process.env.SECRET` is referenced in a module imported by both server and client; the secret name (and possibly value) ends up in the client bundle | Import the secret only in modules guarded by `import 'server-only'`; or read it inside a server action / route handler where the import graph cannot leak |
83
+ | Server-only API in a client bundle | `fs.readFileSync` or `pg.Client` is imported into a `'use client'` component; build fails or runtime crashes | Mark client components with `'use client'`; mark server-only utilities with `import 'server-only'`; the bundler's static analysis catches the leak |
84
+ | Untyped client→server validation gap | A server action accepts an argument typed as `{ userId: string }`; the client constructs a payload with `{ userId: 123 }`; the server crashes or, worse, queries with `123` and accidentally exposes another user's data | Validate every server-action argument with a runtime schema (Zod, valibot); never trust the TypeScript types of an RPC handler |
85
+ | Trusted-by-default client claim | A server action checks `if (req.userRole === 'admin') ...` where `req.userRole` came from the client (via cookie, header, or body) | Re-derive trust from the server's authoritative source (the session record, the database, the IdP) — never from the client's self-report |
86
+ | Non-serializable value in props | A `'use client'` component receives a server-built `Map<string, User>` as a prop; the RSC serializer can encode it, but a misconfigured project on plain JSON cannot — silent data loss or runtime crash | Test the serialization shape in code review; convert to plain objects at the boundary; or upgrade to a wire format that supports the type |
87
+ | Closure leakage attempt | A server component constructs `() => doSomething()` and tries to pass it to a client component as a prop | Use a `'use server'` function (which serializes as an RPC reference) or pass the data the function uses and reconstruct the behavior on the client |
88
+
89
+ ## RSC Server Actions — A Worked Example
90
+
91
+ ```typescript
92
+ // app/actions.ts
93
+ 'use server';
94
+
95
+ import { z } from 'zod';
96
+ import { requireSession } from '@/lib/auth';
97
+ import { db } from '@/lib/db';
98
+
99
+ const UpdateNameInput = z.object({
100
+ userId: z.string().uuid(),
101
+ name: z.string().min(1).max(100),
102
+ });
103
+
104
+ export async function updateUserName(rawInput: unknown) {
105
+ // 1. Authenticate the caller (server-only source of truth)
106
+ const session = await requireSession();
107
+
108
+ // 2. Validate the input (the bytes from the client may be anything)
109
+ const input = UpdateNameInput.parse(rawInput);
110
+
111
+ // 3. Authorize the action (the authenticated user may not be allowed to do this)
112
+ if (session.userId !== input.userId && !session.isAdmin) {
113
+ throw new Error('not allowed');
114
+ }
115
+
116
+ // 4. Perform the action
117
+ await db.user.update({
118
+ where: { id: input.userId },
119
+ data: { name: input.name },
120
+ });
121
+ }
122
+ ```
123
+
124
+ ```typescript
125
+ // app/profile/edit.tsx
126
+ 'use client';
127
+
128
+ import { updateUserName } from '@/app/actions';
129
+
130
+ export function EditProfile({ userId }: { userId: string }) {
131
+ return (
132
+ <form action={async (formData) => {
133
+ await updateUserName({
134
+ userId,
135
+ name: formData.get('name'),
136
+ });
137
+ }}>
138
+ <input name="name" />
139
+ <button type="submit">Save</button>
140
+ </form>
141
+ );
142
+ }
143
+ ```
144
+
145
+ The shape of this code embeds the boundary's three properties:
146
+
147
+ - **Serialization** — the `formData` is a `FormData` (the wire format for a form submission), unwrapped to a plain object before the action is invoked.
148
+ - **Direction** — the form is client→server; everything in `rawInput` is potentially adversarial.
149
+ - **Trust** — the session is the server's authoritative claim about who is calling; `input.userId` is the client's claim about who to operate on; the authorization check compares the two.
150
+
151
+ A version of this code that skipped the schema parse, used the session's `userId` as if it were the same as `input.userId`, or trusted a client-supplied `isAdmin` claim would have a vulnerability at the boundary.
152
+
153
+ ## Verification
154
+
155
+ After applying this skill, verify:
156
+ - [ ] Every file that ships to the client has `'use client'` (or is reachable only through client imports) — the implicit-server default is intentional, not accidental.
157
+ - [ ] Every server action has `'use server'` at the function or file level — the function's network reachability is explicit.
158
+ - [ ] Server actions validate input with a runtime schema (Zod, valibot, io-ts) — types from TypeScript are not validation.
159
+ - [ ] Server actions re-derive trust from a server-authoritative source (session, JWT verification, database lookup) — client-supplied trust claims are never accepted.
160
+ - [ ] Modules holding secrets import `'server-only'` — the bundler will error if they leak.
161
+ - [ ] Modules touching `window`, `document`, or other browser globals import `'client-only'` — symmetric guardrail.
162
+ - [ ] Props passed from server to client components are serializable in the project's wire format — verified by build success and by code review for non-trivial types (Maps, class instances, Dates).
163
+ - [ ] FormData payloads with nested structure are validated after parsing — no `as` casts of `JSON.parse` results.
164
+ - [ ] No closures cross the boundary — only data, server-action references, and RSC primitives.
165
+ - [ ] Authentication, authorization, and rate-limiting live inside server actions and route handlers, not in client components.
166
+
167
+ ## Do NOT Use When
168
+
169
+ | Instead of this skill | Use | Why |
170
+ |---|---|---|
171
+ | Deciding when and where the UI is produced (CSR/SSR/SSG/RSC) | `rendering-models` | rendering-models owns the staging decision; client-server-boundary owns the serialization frontier — they compose but are distinct |
172
+ | Designing HTTP caching, status codes, content negotiation | `http-semantics` | http-semantics owns the wire protocol; client-server-boundary owns what data exists at the boundary |
173
+ | Organizing the frontend folder layout and module structure | `frontend-architecture` | frontend-architecture is wider — it includes state management, component layering, feature boundaries; the client-server-boundary is one axis it touches |
174
+ | Designing the JSON shape of an external API | `api-design` | api-design owns external surface contracts; client-server-boundary is the internal boundary inside a single application |
175
+ | Choosing between Zod / valibot / io-ts as a runtime validator | individual library docs + `api-design` | library choice is below this skill |
176
+ | Enforcing TypeScript discipline inside the program | `type-safety` | type-safety owns compile-time discipline; the boundary is one of the places where type safety stops |
177
+
178
+ ## Key Sources
179
+
180
+ - React team. [React Server Components RFC](https://github.com/reactjs/rfcs/blob/main/text/0188-server-components.md). Proposed Dec 2020. The canonical specification of the RSC wire format, including the rules for what can be serialized across the boundary and the role of `'use client'` / `'use server'`.
181
+ - Sebastian Markbåge (React core). ["The Future of Web Software Is Server Components"](https://www.youtube.com/watch?v=zMf_xeGPn6s). 2022 talk. The mental model of the boundary as a serialization protocol rather than a deployment topology.
182
+ - Vercel. [Next.js documentation — Server and Client Components](https://nextjs.org/docs/app/building-your-application/rendering/server-components). Reference for `'use client'` / `'use server'` semantics, the `server-only` and `client-only` packages, and the serialization rules in App Router.
183
+ - WHATWG. [HTML Living Standard — Structured clone algorithm](https://html.spec.whatwg.org/multipage/structured-data.html#structured-clone). Specification of the broader-than-JSON serialization set used by postMessage, IndexedDB, and Worker boundaries.
184
+ - Mark Erikson. ["Why React Server Components Are Important"](https://blog.isquaredsoftware.com/2023/04/whats-the-deal-with-react-server-components/). 2023. Practitioner-level explanation of the boundary's implications for bundle size, hydration, and the framework-author contract.
185
+ - Remix team. [Loader and Action documentation](https://remix.run/docs/en/main/route/loader). Reference for the function-named boundary convention that predates and informs RSC's directive-based model.
186
+ - OWASP. [Top 10:2021 — A01:2021 Broken Access Control](https://owasp.org/Top10/A01_2021-Broken_Access_Control/). The class of vulnerabilities that arise specifically from treating client-supplied trust claims as authoritative — the failure mode this skill exists to prevent.
187
+ - Hejlsberg, A. et al. [TypeScript Handbook — Type assertions and the `unknown` type](https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-assertions). The explicit acknowledgement that `as` casts do not validate at runtime — the gap that boundary-crossing validation must fill.
@@ -0,0 +1,120 @@
1
+ ---
2
+ name: code-review
3
+ description: "Use when reviewing a pull request, diff, or proposed code change for correctness, clarity, security, performance, and conformance to project conventions — whether the author is a human, an AI agent, or a peer. Covers the pre-review fact-gathering pass, the read-order strategy (tests first, then implementation, then call sites), the severity-grading rubric, the comment-phrasing discipline, and the no-rubber-stamp rule for AI-generated diffs. Do NOT use for AUTHORING the code (use `refactor` for behaviour-preserving changes or `skill-scaffold` for new skills), for chasing a known bug after merge (use `debugging`), or for security-only audits (use `owasp-security` for vulnerability-focused review)."
4
+ license: MIT
5
+ compatibility: Language-agnostic; assumes a diff or PR as input
6
+ allowed-tools: Read Grep Bash
7
+ metadata:
8
+ metadata: "{\"schema_version\":6,\"version\":\"1.0.0\",\"type\":\"workflow\",\"category\":\"quality\",\"scope\":\"portable\",\"owner\":\"skill-graph-maintainer\",\"freshness\":\"2026-05-04\",\"drift_check\":\"{\\\\\\\"last_verified\\\\\\\":\\\\\\\"2026-05-04\\\\\\\"}\",\"eval_artifacts\":\"present\",\"eval_state\":\"unverified\",\"routing_eval\":\"absent\",\"stability\":\"experimental\",\"keywords\":\"[\\\\\\\"code review\\\\\\\",\\\\\\\"review this PR\\\\\\\",\\\\\\\"review this diff\\\\\\\",\\\\\\\"review this change\\\\\\\",\\\\\\\"review this AI generated code\\\\\\\",\\\\\\\"PR review\\\\\\\",\\\\\\\"diff review\\\\\\\",\\\\\\\"severity grade\\\\\\\",\\\\\\\"reviewer rubric\\\\\\\",\\\\\\\"approve or block\\\\\\\",\\\\\\\"request changes\\\\\\\",\\\\\\\"review checklist\\\\\\\",\\\\\\\"review a colleague PR\\\\\\\",\\\\\\\"review my own code\\\\\\\",\\\\\\\"code quality review\\\\\\\"]\",\"examples\":\"[\\\\\\\"review this PR for correctness and project conventions\\\\\\\",\\\\\\\"this diff was generated by an AI agent — what should I check?\\\\\\\",\\\\\\\"should I approve this change or request more work?\\\\\\\",\\\\\\\"what's the right severity for missing test coverage on a refactor?\\\\\\\",\\\\\\\"review my own code before I open the PR\\\\\\\",\\\\\\\"review this 600-line diff — where do I start?\\\\\\\",\\\\\\\"this PR adds a new endpoint — review for security and correctness\\\\\\\",\\\\\\\"phrase a request-changes comment without sounding harsh\\\\\\\"]\",\"anti_examples\":\"[\\\\\\\"fix this bug that production users are reporting\\\\\\\",\\\\\\\"refactor this 200-line function into smaller pieces\\\\\\\",\\\\\\\"scaffold a new skill that teaches code review\\\\\\\",\\\\\\\"write a guide explaining our review conventions\\\\\\\",\\\\\\\"audit this code for SQL injection and XSS specifically\\\\\\\"]\",\"relations\":\"{\\\\\\\"boundary\\\\\\\":[{\\\\\\\"skill\\\\\\\":\\\\\\\"refactor\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"refactor produces the change being reviewed; code-review evaluates the change. Reviewer and author are distinct roles even when the same person fills them\\\\\\\"},{\\\\\\\"skill\\\\\\\":\\\\\\\"debugging\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"debugging chases an observed failure; code-review catches problems before merge\\\\\\\"},{\\\\\\\"skill\\\\\\\":\\\\\\\"owasp-security\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"owasp-security is a security-specific deep audit; code-review is the holistic per-PR pass that includes security as one of several concerns\\\\\\\"},{\\\\\\\"skill\\\\\\\":\\\\\\\"testing-strategy\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"testing-strategy decides what to test; code-review evaluates whether the implemented tests adequately cover the change\\\\\\\"}],\\\\\\\"related\\\\\\\":[\\\\\\\"testing-strategy\\\\\\\",\\\\\\\"naming-conventions\\\\\\\",\\\\\\\"owasp-security\\\\\\\"],\\\\\\\"verify_with\\\\\\\":[\\\\\\\"testing-strategy\\\\\\\"]}\",\"portability\":\"{\\\\\\\"readiness\\\\\\\":\\\\\\\"scripted\\\\\\\",\\\\\\\"targets\\\\\\\":[\\\\\\\"skill-md\\\\\\\"]}\",\"lifecycle\":\"{\\\\\\\"stale_after_days\\\\\\\":365,\\\\\\\"review_cadence\\\\\\\":\\\\\\\"quarterly\\\\\\\"}\",\"skill_graph_source_repo\":\"https://github.com/jacob-balslev/skill-graph\",\"skill_graph_protocol\":\"Skill Metadata Protocol v5\",\"skill_graph_project\":\"Skill Graph\",\"skill_graph_canonical_skill\":\"skills/code-review/SKILL.md\"}"
9
+ skill_graph_source_repo: "https://github.com/jacob-balslev/skill-graph"
10
+ skill_graph_protocol: Skill Metadata Protocol v4
11
+ skill_graph_project: Skill Graph
12
+ skill_graph_canonical_skill: skills/code-review/SKILL.md
13
+ ---
14
+
15
+ # Code Review
16
+
17
+ ## Coverage
18
+
19
+ - Pre-review fact-gathering: understanding the PR's stated purpose, the linked issue, the size of the diff, and any context the author called out
20
+ - Read-order strategy: tests first (do they describe the change correctly?), then the implementation, then the call sites that consume the changed surface
21
+ - Severity-grading rubric: blocker / change-requested / suggestion / nit / praise — and when each is appropriate
22
+ - Comment-phrasing discipline: how to ask questions instead of make accusations, how to cite line numbers and references, how to distinguish an objective rule from a stylistic preference
23
+ - The no-rubber-stamp rule for AI-generated diffs: deliberate verification of the generated code's claims, especially around tests, error handling, and security
24
+ - Self-review pass: how to review your own diff before opening the PR, catching the obvious issues so the human reviewer can focus on the non-obvious
25
+ - Tools that complement the review: lint output, type-check output, test results, and how to interpret each in context
26
+ - The merge decision: when "approve", "request changes", and "close without merge" are appropriate
27
+
28
+ ## Philosophy
29
+
30
+ A code review is a *conversation*, not a verdict. The reviewer's job is not to prove they could have written the code differently; it is to ensure the change ships in a state the team can maintain. Reviews fail when they are either rubber-stamped (no verification, just a thumbs-up) or weaponised (every review becomes a referendum on the author's competence). The reviewer's leverage comes from reading code the author has been staring at for hours — the reviewer sees the obvious mistakes the author cannot.
31
+
32
+ For AI-generated diffs the bar is higher, not lower. Karpathy's "vibe hangover" is real: AI-generated code typically *looks* correct, has reasonable variable names, and compiles cleanly — and contains 1.7-2.74× more security vulnerabilities than human-authored equivalents. A reviewer rubber-stamping an AI diff is not saving time; they are deferring debugging cost to whichever colleague debugs the production failure.
33
+
34
+ ## Workflow
35
+
36
+ The review is six phases. Skipping any phase is a rubber stamp; doing them out of order produces low-signal comments that confuse the author.
37
+
38
+ ### Phase 1 — Pre-review fact-gathering (5 minutes)
39
+
40
+ 1. Read the **PR title and description**. Identify the stated purpose in one sentence.
41
+ 2. Read the **linked issue or task**. Confirm the diff matches the issue's acceptance criteria.
42
+ 3. Note the **diff size**: <50 lines is a quick review, 50-300 is a normal review, 300-1000 is a slow review, 1000+ is a "should this have been split?" review.
43
+ 4. Skim the **list of changed files**. Form a hypothesis: "this change should touch X, Y, Z." If the diff touches files outside that hypothesis, ask why before reading the code.
44
+
45
+ ### Phase 2 — Read tests first (10-30 minutes)
46
+
47
+ 1. Open the test files BEFORE the implementation files.
48
+ 2. For each new or modified test, read the *assertion* — what does the test claim is true?
49
+ 3. For each new or modified test, read the *setup* — what state does the test put the code in?
50
+ 4. The tests should describe the change in plain language. If the tests are unclear, the implementation will be too.
51
+ 5. **Missing tests** for new behaviour is a *change-requested* signal at minimum, often a *blocker* for production paths.
52
+
53
+ ### Phase 3 — Read implementation (30-90 minutes)
54
+
55
+ Read in the order the diff is presented (chronological by file path). Apply the rubric below to each diff hunk.
56
+
57
+ | Concern | Look for | Severity if missing |
58
+ |---|---|---|
59
+ | **Correctness** | Does this implement what the PR claims? Edge cases handled? Off-by-one? | **Blocker** |
60
+ | **Type safety / null handling** | Unguarded null deref, untyped boundary, `any` escape | **Blocker** if production-path; otherwise change-requested |
61
+ | **Security** | SQL injection, XSS, auth bypass, secret in code, missing CSRF | **Blocker** |
62
+ | **Test coverage** | New code path with no test, new branch with no test | **Change-requested** at minimum |
63
+ | **Performance** | N+1 query, unbounded loop, sync I/O in hot path | **Change-requested** if observable; **blocker** if catastrophic |
64
+ | **Project conventions** | Naming, file location, import order, lint cleanliness | **Suggestion** unless project doc enforces |
65
+ | **Documentation drift** | Stale comment, wrong API description, broken cross-reference | **Change-requested** if user-visible |
66
+ | **Naming clarity** | Misleading name, abbreviation that hides meaning | **Suggestion** unless the name actively lies |
67
+ | **Stylistic preference** | "I'd write this differently" with no objective rule | **Nit** at most; often delete |
68
+
69
+ ### Phase 4 — Read call sites (10-30 minutes)
70
+
71
+ For every changed public surface (exported function, route, schema), grep for callers. Confirm the diff's contract matches what callers expect. The most expensive bugs are introduced at the contract layer because the implementation looked fine in isolation.
72
+
73
+ ### Phase 5 — Author the review (15-30 minutes)
74
+
75
+ Write comments in the order: **blockers, change-requested, suggestions, nits, praise**. Each comment must:
76
+
77
+ - Cite the line number explicitly.
78
+ - State the *concern* before the *fix*: "this returns null on missing input — should it throw? callers do not currently null-check."
79
+ - Distinguish an objective rule (cite the rule) from a preference ("style nit").
80
+ - Avoid ad-hominem. The diff is the subject, not the author.
81
+
82
+ For AI-generated diffs, add deliberate verification comments: "AI-generated — confirmed test exists for the happy path. Did the author verify the empty-input case? It's not in the diff."
83
+
84
+ ### Phase 6 — The merge decision
85
+
86
+ | Verdict | When |
87
+ |---|---|
88
+ | **Approve** | All blockers absent, change-requested resolved, suggestions optional |
89
+ | **Approve with comments** | Blockers absent, suggestions worth raising but not blocking |
90
+ | **Request changes** | Any blocker present, OR any change-requested item the author should address |
91
+ | **Close without merge** | The diff implements the wrong thing, OR the issue is no longer valid |
92
+
93
+ A review without a verdict is incomplete. Don't leave PRs open with comments and no decision.
94
+
95
+ ## Self-Review (Before Opening the PR)
96
+
97
+ Run the same six phases on your own diff before opening the PR. The author's self-review catches 60-80% of the issues a reviewer would otherwise raise, leaving the reviewer's attention free for the non-obvious. Self-review is not optional — it is the cheapest place to catch the obvious mistakes.
98
+
99
+ ## Evals
100
+
101
+ This skill ships a comprehension-eval artifact at [`examples/evals/code-review.json`](https://github.com/jacob-balslev/skill-graph/blob/main/examples/evals/code-review.json). The checklist below is the reviewer gate for proposed changes; the eval file is the grader surface.
102
+
103
+ ## Verification
104
+
105
+ - [ ] PR description matches the diff scope (no surprise files or scope creep)
106
+ - [ ] Tests exist for new behaviour and pass locally / in CI
107
+ - [ ] All blockers and change-requested items have line-cited comments
108
+ - [ ] AI-generated content is verified, not rubber-stamped
109
+ - [ ] Naming, security, and convention concerns are graded by severity, not lumped together
110
+ - [ ] The merge decision is explicit (approve / request-changes / close)
111
+
112
+ ## Do NOT Use When
113
+
114
+ | Use instead | When |
115
+ |---|---|
116
+ | `refactor` | Authoring the change being reviewed |
117
+ | `debugging` | Investigating a failure that already shipped |
118
+ | `owasp-security` | Conducting a security-specific deep audit (the holistic review covers security as one concern; OWASP is the deep dive) |
119
+ | `testing-strategy` | Deciding what tests to write before authoring the diff |
120
+ | `skill-scaffold` | Authoring a new skill from scratch (skill content review IS code review, but the authoring workflow is the scaffold's domain) |
@@ -0,0 +1,43 @@
1
+ ---
2
+ name: color-system-design
3
+ description: "Use when designing a color system — palette construction, semantic color tokens, WCAG contrast ratios, perceptual uniformity in OKLCH/LCH, and light/dark mode parity. Do NOT use for single brand-color picks, runtime theme-switching mechanics, or non-color design tokens."
4
+ license: CC-BY-4.0
5
+ metadata:
6
+ metadata: "{\"schema_version\":6,\"version\":\"1.0.0\",\"type\":\"capability\",\"category\":\"design\",\"scope\":\"portable\",\"owner\":\"skill-graph-maintainer\",\"freshness\":\"2026-05-12\",\"drift_check\":\"{\\\\\\\"last_verified\\\\\\\":\\\\\\\"2026-05-12\\\\\\\"}\",\"eval_artifacts\":\"planned\",\"eval_state\":\"unverified\",\"routing_eval\":\"absent\",\"stability\":\"experimental\",\"keywords\":\"[\\\\\\\"color palette design\\\\\\\",\\\\\\\"semantic color tokens\\\\\\\",\\\\\\\"wcag contrast ratio\\\\\\\",\\\\\\\"apca contrast\\\\\\\",\\\\\\\"oklch color space\\\\\\\",\\\\\\\"perceptual uniformity\\\\\\\",\\\\\\\"color scales\\\\\\\",\\\\\\\"light dark parity\\\\\\\",\\\\\\\"color accessibility\\\\\\\",\\\\\\\"p3 color gamut\\\\\\\",\\\\\\\"color-mix\\\\\\\",\\\\\\\"color palette light dark mode\\\\\\\",\\\\\\\"pick color scheme\\\\\\\"]\",\"triggers\":\"[\\\\\\\"color system\\\\\\\",\\\\\\\"color palette\\\\\\\",\\\\\\\"color tokens\\\\\\\",\\\\\\\"wcag contrast\\\\\\\",\\\\\\\"oklch\\\\\\\"]\",\"examples\":\"[\\\\\\\"Build a 10-step color scale from a brand seed color with perceptually even lightness steps\\\\\\\",\\\\\\\"Map semantic intents (success, warning, danger, info) to scale colors with WCAG AA contrast against both light and dark surfaces\\\\\\\",\\\\\\\"Audit an existing palette for AA contrast failures and propose minimal changes\\\\\\\"]\",\"anti_examples\":\"[\\\\\\\"Pick the brand's primary color from scratch with no constraints\\\\\\\",\\\\\\\"Implement the prefers-color-scheme media query and toggle UI\\\\\\\",\\\\\\\"Choose spacing values for the layout grid\\\\\\\"]\",\"relations\":\"{\\\\\\\"related\\\\\\\":[\\\\\\\"theme-system-design\\\\\\\",\\\\\\\"dark-mode-implementation\\\\\\\",\\\\\\\"visual-design-foundations\\\\\\\",\\\\\\\"a11y\\\\\\\"],\\\\\\\"boundary\\\\\\\":[{\\\\\\\"skill\\\\\\\":\\\\\\\"theme-system-design\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"theme-system-design structures how color decisions become tokens and reach components; this skill produces those color decisions.\\\\\\\"},{\\\\\\\"skill\\\\\\\":\\\\\\\"a11y\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"a11y owns the WCAG criteria themselves; this skill applies them when constructing palettes and selecting pairings.\\\\\\\"}]}\",\"skill_graph_source_repo\":\"https://github.com/jacob-balslev/skill-graph\",\"skill_graph_protocol\":\"Skill Metadata Protocol v5\",\"skill_graph_project\":\"Skill Graph\",\"skill_graph_canonical_skill\":\"skills/color-system-design/SKILL.md\"}"
7
+ skill_graph_source_repo: "https://github.com/jacob-balslev/skill-graph"
8
+ skill_graph_protocol: Skill Metadata Protocol v4
9
+ skill_graph_project: Skill Graph
10
+ skill_graph_canonical_skill: skills/color-system-design/SKILL.md
11
+ ---
12
+
13
+ # Color System Design
14
+
15
+ ## Coverage
16
+ A color system has three layers: a palette of raw color values (organized as scales — typically 9 to 12 steps from very light to very dark within a single hue), a set of semantic tokens that name colors by purpose rather than appearance (background-surface, text-primary, border-subtle, danger-emphasis), and a mapping that resolves semantic tokens to palette values per theme. The palette is the vocabulary; the semantic tokens are the contract that components consume; the mapping is what changes between themes.
17
+
18
+ Color spaces matter for scale construction. sRGB and HSL are non-perceptually-uniform — equal numeric steps in lightness produce unequal perceived lightness changes, with notable cliffs around yellow and teal. OKLCH and CIELAB are perceptually uniform color spaces where equal L (lightness) steps look equal regardless of hue, making them the appropriate space for generating scales. The CSS Color Module Level 4 specifies oklch() and lch() as first-class CSS color functions, and color-mix() in lch/oklch space produces predictable interpolation. The display-p3 gamut, supported by most modern displays, allows more saturated colors than sRGB in the green/red regions; declaring color-gamut: p3 or using p3 color functions delivers them while CSS color fallbacks handle sRGB-only displays.
19
+
20
+ Contrast is governed by WCAG 2.1, which specifies a contrast ratio computed from relative luminance: 4.5:1 for normal text (AA), 3:1 for large text (AA, defined as 18pt+ or 14pt+ bold), and 7:1 for normal text (AAA). APCA (Accessible Perceptual Contrast Algorithm), the working draft for WCAG 3, uses a different model that better predicts perceived text legibility, with thresholds expressed as Lc values (60 Lc for body text, 75 Lc for small text). Tooling should compute both, but WCAG 2.1 remains the legally referenced standard in most jurisdictions as of 2026.
21
+
22
+ Semantic tokens decouple the system from a single visual treatment. text-primary on a light theme might be near-black at L=0.15; on a dark theme it might be near-white at L=0.96. Both resolve to the same component token and meet the same contrast requirement against their respective backgrounds. The discipline is to define semantic tokens by intent and contrast pair (text-on-surface, text-on-emphasis), never by appearance (text-dark-gray).
23
+
24
+ ## Philosophy
25
+ Color choices are constraints applied to perception, not free decisions. Perceptual uniformity, contrast minima, color-blindness considerations (8% of men have some form of color vision deficiency), and gamut limits are real and observable. A palette that ignores them produces accessibility violations and uneven scales that designers have to compensate for with one-off tweaks.
26
+
27
+ Semantic tokens are worth the indirection because color meanings outlive specific values. "Danger" stays danger when the brand red shifts a few degrees; components keep working. Tying components directly to palette values turns every brand refresh into a code change.
28
+
29
+ ## Verification
30
+ - Every text/background pair used in the product meets WCAG 2.1 AA at minimum; an automated check runs in CI against the token combinations.
31
+ - Scales are generated in OKLCH or LCH and exported to sRGB or display-p3; equal step indices have equal lightness within ±2 L units.
32
+ - Semantic tokens are named by intent (background-surface, danger-emphasis) not by appearance (gray-50, red-700) in component code.
33
+ - Light and dark themes provide every semantic token; no token is light-only or dark-only.
34
+ - Color is not the only signal for state — error states pair red with an icon and text, not red alone, to remain accessible to color-blind users.
35
+ - The palette has been previewed under simulated protanopia, deuteranopia, and tritanopia, and important distinctions remain visible.
36
+ - Brand color is anchored at a specific scale step (e.g., brand at step 600) so the surrounding scale is generated rather than hand-tuned.
37
+
38
+ ## Do NOT Use When
39
+ - The task is picking a single brand color with no system implications. That is a brand decision, not a system decision.
40
+ - You are implementing the runtime mechanics of theme switching, persistence, and asset variants. Use theme-system-design and dark-mode-implementation.
41
+ - The work is non-color tokens — spacing, typography, motion. Use typography-system or visual-design-foundations.
42
+ - The concern is purely accessibility-criterion lookup rather than palette construction. Use a11y.
43
+ - You need to choose color values for a single illustration or marketing graphic with no token impact. Treat as art direction, not system design.
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: component-architecture
3
+ description: "Use when structuring a component library or design system for reuse across products, themes, and teams: layering of primitives, composites, and product-specific assemblies; component API design (props, polymorphism, compound components, render props vs hooks vs slots); the open-closed principle for component evolution; the headless/styled split for theming; controlled vs uncontrolled state contracts; ref forwarding and imperative escape hatches; composition over configuration trade-offs; and the cross-product reuse problem. Do NOT use for within-product module composition (use design-module-composition), design system meta-architecture (use design-system-architecture), the visual language itself (use visual-design-foundations or tokens), tactical hooks (library docs), or state-management decisions that are not component-API-shaped (use state-management)."
4
+ license: MIT
5
+ allowed-tools: Read Grep
6
+ metadata:
7
+ metadata: "{\"schema_version\":6,\"version\":\"1.0.0\",\"type\":\"capability\",\"category\":\"design\",\"domain\":\"design/component-systems\",\"scope\":\"reference\",\"owner\":\"skill-graph-maintainer\",\"freshness\":\"2026-05-16\",\"drift_check\":\"{\\\\\\\"last_verified\\\\\\\":\\\\\\\"2026-05-16\\\\\\\"}\",\"eval_artifacts\":\"planned\",\"eval_state\":\"unverified\",\"routing_eval\":\"absent\",\"comprehension_state\":\"present\",\"stability\":\"experimental\",\"keywords\":\"[\\\\\\\"component library design\\\\\\\",\\\\\\\"atomic design layering\\\\\\\",\\\\\\\"component primitives\\\\\\\",\\\\\\\"component composites\\\\\\\",\\\\\\\"compound components\\\\\\\",\\\\\\\"polymorphic component\\\\\\\",\\\\\\\"asChild prop\\\\\\\",\\\\\\\"headless component\\\\\\\",\\\\\\\"styled component\\\\\\\",\\\\\\\"controlled component\\\\\\\",\\\\\\\"uncontrolled component\\\\\\\",\\\\\\\"ref forwarding\\\\\\\",\\\\\\\"render props\\\\\\\",\\\\\\\"component slots\\\\\\\",\\\\\\\"compose components\\\\\\\",\\\\\\\"component prop API\\\\\\\",\\\\\\\"component reuse across products\\\\\\\",\\\\\\\"decomposing a large component to maintain it\\\\\\\"]\",\"triggers\":\"[\\\\\\\"structure components for reuse\\\\\\\",\\\\\\\"how do I design this component API\\\\\\\",\\\\\\\"controlled or uncontrolled\\\\\\\",\\\\\\\"should I use props or composition\\\\\\\",\\\\\\\"compound component pattern\\\\\\\",\\\\\\\"headless vs styled\\\\\\\",\\\\\\\"primitive vs composite\\\\\\\"]\",\"examples\":\"[\\\\\\\"design the API surface for a Dialog component that must work in multiple products with different visual languages\\\\\\\",\\\\\\\"decide whether a Form component should be controlled, uncontrolled, or both\\\\\\\",\\\\\\\"structure a component library so primitives can be themed without rewriting the composites\\\\\\\",\\\\\\\"refactor a 30-prop component into a compound API that surfaces the right primitives\\\\\\\"]\",\"anti_examples\":\"[\\\\\\\"decide where the form's state lives across page navigations (use state-management)\\\\\\\",\\\\\\\"pick the design tokens for color and spacing (use visual-design-foundations)\\\\\\\",\\\\\\\"decide how a single product's modules are wired together internally (use design-module-composition)\\\\\\\",\\\\\\\"implement a specific React hook for form management (library docs / tactical decision)\\\\\\\",\\\\\\\"decide where state lives across the app — server, client UI, URL, or persistent (use state-management)\\\\\\\",\\\\\\\"design the application-level folder structure, routing, build, and deployment (use frontend-architecture)\\\\\\\"]\",\"relations\":\"{\\\\\\\"related\\\\\\\":[\\\\\\\"design-system-architecture\\\\\\\",\\\\\\\"design-module-composition\\\\\\\",\\\\\\\"visual-design-foundations\\\\\\\",\\\\\\\"state-management\\\\\\\",\\\\\\\"frontend-architecture\\\\\\\",\\\\\\\"typography-system\\\\\\\",\\\\\\\"color-system-design\\\\\\\"],\\\\\\\"boundary\\\\\\\":[{\\\\\\\"skill\\\\\\\":\\\\\\\"design-module-composition\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"design-module-composition owns how a SINGLE PRODUCT's modules compose internally — layout, slots, named regions, within-product composition patterns. This skill owns the layer above: how components are STRUCTURED to be reusable across products, with API surfaces that survive multiple visual languages and interaction contracts. They compose: this skill says how to build the components; design-module-composition says how a product wires them up.\\\\\\\"},{\\\\\\\"skill\\\\\\\":\\\\\\\"design-system-architecture\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"design-system-architecture owns the META structure of a design system: tokens, foundations, governance, documentation, distribution. This skill owns one stratum inside that: how components themselves are structured. A design system is a system of components plus tokens plus foundations plus distribution; this skill is the component stratum.\\\\\\\"},{\\\\\\\"skill\\\\\\\":\\\\\\\"visual-design-foundations\\\\\\\",\\\\\\\"reason\\\\\\\":\\\\\\\"visual-design-foundations owns the design language itself: color theory, typography, spacing, grid, motion. This skill owns the structural mechanism by which that language is delivered to product code — components that bind to tokens and surface the language in reusable form.\\\\\\\"}],\\\\\\\"verify_with\\\\\\\":[\\\\\\\"design-system-architecture\\\\\\\",\\\\\\\"design-module-composition\\\\\\\"]}\",\"mental_model\":\"|\",\"purpose\":\"|\",\"boundary\":\"|\",\"analogy\":\"Component architecture is to a UI library what API design is to a backend service — the public contract is the only thing consumers see; every consumer depends on shape, behavior, and naming for things that may seem internal to the author; once a version ships, every prop and slot becomes a thing future versions must continue to support, just as every endpoint and field of a public API does. The headless/styled split is to component libraries what the data-plane/control-plane split is to distributed systems: separating the part that changes slowly (behavior, contracts) from the part that changes fast (visual treatment, theming).\",\"misconception\":\"|\",\"concept\":\"{\\\\\\\"definition\\\\\\\":\\\\\\\"Component architecture is the architectural discipline of structuring a library of UI components so that they can be reused across products, themes, and teams without each reuse requiring a rewrite. The discipline answers four interlocking questions: (1) at what LAYER does a given concern belong — primitive, composite, product-specific assembly; (2) what is the API SURFACE — which props, slots, refs, callbacks, render functions, and which are open for extension vs closed for modification; (3) what STATE CONTRACT does the component expose — controlled, uncontrolled, hybrid; (4) what THEMING and styling mechanism allows the component's behavior to remain stable while its visual language changes. The discipline is distinct from the visual design language itself (which colors, which type scale) and from within-product wiring (which screens compose which modules) — it is the architectural stratum that makes both possible by producing components whose API outlives any single product instance and any single visual treatment.\\\\\\\",\\\\\\\"mental_model\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"purpose\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"boundary\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"taxonomy\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"analogy\\\\\\\":\\\\\\\"|\\\\\\\",\\\\\\\"misconception\\\\\\\":\\\\\\\"|\\\\\\\"}\",\"skill_graph_source_repo\":\"https://github.com/jacob-balslev/skill-graph\",\"skill_graph_protocol\":\"Skill Metadata Protocol v5\",\"skill_graph_project\":\"Skill Graph\",\"skill_graph_canonical_skill\":\"skills/component-architecture/SKILL.md\",\"skill_graph_export_description\":\"shortened for Agent Skills 1024-character description limit; canonical source keeps the full routing contract\",\"skill_graph_canonical_description_length\":\"1107\"}"
8
+ skill_graph_source_repo: "https://github.com/jacob-balslev/skill-graph"
9
+ skill_graph_protocol: Skill Metadata Protocol v4
10
+ skill_graph_project: Skill Graph
11
+ skill_graph_canonical_skill: skills/component-architecture/SKILL.md
12
+ ---
13
+
14
+ # Component Architecture
15
+
16
+ ## Coverage
17
+
18
+ The architectural discipline of structuring a library of UI components so they can be reused across products, themes, and teams. Covers the layering of primitives, composites, and product-specific assemblies; the composition-over-configuration principle and its trade-offs; the headless/styled split as the mechanism for behavior reuse across visual languages; controlled / uncontrolled / hybrid state contracts; the open-closed principle adapted to component evolution; polymorphism via `as` and `asChild`; extension mechanisms (props, children, slots, render props, compound components, ref forwarding); and the API-as-contract framing that makes component libraries survive multi-product, multi-year reuse.
19
+
20
+ ## Philosophy
21
+
22
+ The component's API is the contract between its author and every future consumer. Every prop, every slot, every event is a public surface that becomes a thing future versions must continue to support — or break consumers. Component architecture is the discipline of designing those contracts with the knowledge that you cannot predict every consumer and that the contract will be inhabited by integrations you didn't anticipate.
23
+
24
+ The discipline is upstream of any specific library, framework, or visual language. Layering, composition, the headless/styled split, the controlled/uncontrolled distinction, and the open-closed principle are properties of how components are *structured* — independent of which framework implements them and which design tokens style them. A team that internalizes these properties produces libraries that survive a decade of framework changes, brand refreshes, and product evolution. A team that does not produces libraries that work for the first product and require a rewrite for the second.
25
+
26
+ For agents working in component-heavy codebases, the discipline is the framework that lets the agent reason locally. Pick up a component, classify it by layer (primitive / composite / product-specific), inspect its API surface (props, slots, events), identify its state contract (controlled / uncontrolled / hybrid), and use it correctly without internalizing every idiosyncrasy. Without the framework, the agent pattern-matches against whatever the codebase already does — which means proliferating the codebase's existing architectural mistakes.
27
+
28
+ ## The Layering Principle
29
+
30
+ | Layer | What it is | Change rate | Reuse scope | Examples |
31
+ |---|---|---|---|---|
32
+ | **Primitive** | Smallest reusable unit; behavior only or behavior + minimal styling | Rare | All products | Button, Input, Checkbox, Popover, Dialog Root |
33
+ | **Composite** | Combines primitives into recurring patterns | Moderate | Most products | FormField (label + input + error), Card, DataTable |
34
+ | **Product-specific assembly** | Combines composites into unique product surfaces | Frequent | One product | CheckoutForm, SettingsPanel, DashboardWidget |
35
+
36
+ Dependencies flow downward (composites depend on primitives; assemblies depend on composites). Reversing the flow couples primitives to specific use cases and destroys reuse.
37
+
38
+ ## Composition Over Configuration
39
+
40
+ | Pattern | When to use | What it costs | What it scales |
41
+ |---|---|---|---|
42
+ | **Configuration (props)** | Small closed enum of variations; combinations are independent | Each new prop is more API surface; combinations multiply | Acceptable up to ~5-7 independent props; gets dangerous beyond |
43
+ | **Composition (children, slots, sub-components)** | Open-ended variation; structure matters | More code at each consumer; more concepts | Scales indefinitely; new variations are additive, not multiplicative |
44
+
45
+ Refactor sign: a configured component with >10 props that are mostly independent is a candidate for the compound-component refactor.
46
+
47
+ ## The Headless / Styled Split
48
+
49
+ | Layer | Owns | Examples |
50
+ |---|---|---|
51
+ | **Headless** | Keyboard navigation, focus management, ARIA, internal state, event emission | Radix Primitives, Headless UI, Ariakit, React Aria, Tanstack Table |
52
+ | **Styled** | Visual treatment, layout, spacing, typography binding | shadcn/ui (Radix + Tailwind), Mantine, MUI theme, your design system |
53
+
54
+ The split is the architectural mechanism that solves cross-product reuse when the same interaction patterns must look different in different products. Behavior evolves independently of styling; styling evolves independently of behavior.
55
+
56
+ ## State Contract Patterns
57
+
58
+ | Contract | Who owns value | API shape | When to use |
59
+ |---|---|---|---|
60
+ | **Controlled** | Consumer | `value` + `onChange` | Value participates in larger state (form, store, URL) |
61
+ | **Uncontrolled** | Component (internal) | `defaultValue` + `onChange` (event-shaped) | Value is the component's business alone |
62
+ | **Hybrid** | Both supported | Both `value` (controlled path) and `defaultValue` (uncontrolled path) | Default for any new component; serves both consumer kinds |
63
+ | **Imperative-only** | Refs and methods | `ref.current.play()`, etc. | Rare; for cases where declarative APIs are awkward (video, focus) |
64
+
65
+ Default to hybrid. Consumers choose by passing `value` or `defaultValue`.
66
+
67
+ ## Extension Mechanisms
68
+
69
+ | Mechanism | What it opens | When to use |
70
+ |---|---|---|
71
+ | **Props (config)** | Closed set of variations | Variations are small, closed, combinatorially independent |
72
+ | **Children / slots** | Structure | Consumer composes inner content |
73
+ | **Compound components** (`Dialog.Root`, `Dialog.Trigger`, `Dialog.Content`) | Structure + implicit shared state via context | Multi-part components with structural variation |
74
+ | **Render props / render functions** | Rendering | Consumer overrides how something renders, with access to internal state |
75
+ | **Forward refs / imperative handles** | Imperative access | Escape hatch for cases declarative APIs cannot reach (focus, scroll, play) |
76
+ | **Polymorphism (`as` / `asChild`)** | Element type | Consumer chooses the semantic tag rendered |
77
+
78
+ ## The Polymorphism Patterns
79
+
80
+ | Pattern | Syntax | Pros | Cons |
81
+ |---|---|---|---|
82
+ | **`as` prop** | `<Button as="a" href="...">` | React-idiomatic; familiar | Hard to type correctly; doesn't compose well across libraries |
83
+ | **`asChild`** (Radix) | `<Button asChild><a href="...">...</a></Button>` | Cleaner accessibility; consumer sees the semantic element | Unfamiliar at first encounter |
84
+ | **Slot-based** (Vue, Svelte) | Framework slot mechanism | Native framework support | Limited to that framework |
85
+
86
+ For cross-library compatibility in React, `asChild` (and the underlying Radix Slot pattern) has become the modern default.
87
+
88
+ ## Verification
89
+
90
+ After applying this skill, verify:
91
+ - [ ] Each component has been classified by layer (primitive / composite / product-specific); the dependency direction is downward only.
92
+ - [ ] Configuration-explosion candidates (components with many independent boolean/enum props) have been considered for composition refactors.
93
+ - [ ] Headless behavior is separated from styled presentation when the component is intended for cross-product or cross-theme reuse.
94
+ - [ ] State contracts are deliberate (controlled / uncontrolled / hybrid / imperative); the default is hybrid for inputs.
95
+ - [ ] Polymorphic components use a deliberate pattern (`as` or `asChild`) — not an accidental any-tag escape hatch.
96
+ - [ ] Compound components share state via context and document the requirement that sub-components live within the parent.
97
+ - [ ] Accessibility (keyboard, focus, ARIA, screen-reader announcement) is built into the primitive layer, not retrofitted.
98
+ - [ ] The API surface is documented (every prop, every slot, every event, every imperative method) and stable; breaking changes follow a deprecation cycle.
99
+ - [ ] Tokens (color, spacing, type) are the binding mechanism for visual properties, not hardcoded values; the styled layer binds to tokens, not literals.
100
+ - [ ] The component library has been tested with multiple actual consumers (multiple products, multiple themes) to verify reusability claims.
101
+
102
+ ## Do NOT Use When
103
+
104
+ | Instead of this skill | Use | Why |
105
+ |---|---|---|
106
+ | Wiring a specific product's screens from components | `design-module-composition` | design-module-composition owns within-product assembly; this skill owns the components being assembled |
107
+ | Designing the design system's overall structure (tokens, foundations, governance, distribution) | `design-system-architecture` | design-system-architecture owns meta-structure; this skill owns the component stratum |
108
+ | Picking the design language (color, type, spacing decisions) | `visual-design-foundations` | visual-design-foundations owns the language; this skill owns the structural mechanism delivering it |
109
+ | Deciding where component state lives across the app | `state-management` | state-management owns location and ownership; this skill owns the component's state-contract API surface |
110
+ | Picking React hook patterns for internal component state | Library docs (React, Vue, etc.) | Tactical implementation; below this skill |
111
+ | Designing the app's folder structure | `folder-structure` or `frontend-architecture` | This skill cares about components, not where they live on disk |
112
+ | Component-level accessibility audit | `a11y` | a11y owns the discipline of checking accessibility; this skill bakes the property into the architecture |
113
+ | Form-specific component architecture (validation, submit) | `form-ux-architecture` | form-ux-architecture owns the form-specific patterns; this skill is the broader framing |
114
+
115
+ ## Key Sources
116
+
117
+ - Frost, B. (2016). *Atomic Design*. Brad Frost Web. The canonical layering framework: atoms / molecules / organisms / templates / pages. Establishes the discipline of layering as a property of well-structured component libraries.
118
+ - Meyer, B. (1988). *Object-Oriented Software Construction*. Prentice Hall. The original articulation of the open-closed principle ("software entities should be open for extension, but closed for modification") — adapted in this skill to component evolution.
119
+ - Radix UI. [Radix Primitives documentation](https://www.radix-ui.com/primitives/docs/overview/introduction). The modern reference implementation of the headless component pattern, the compound-component pattern, and the `asChild` polymorphism pattern. Establishes the contract that has become widely adopted across the React ecosystem.
120
+ - Adobe. [React Aria documentation](https://react-spectrum.adobe.com/react-aria/). The reference implementation of accessibility-first headless components. Demonstrates the architectural commitment to keyboard, focus, and screen-reader support as primitive-layer concerns.
121
+ - Erikson, M. (2020). ["Compound Components"](https://kentcdodds.com/blog/compound-components-with-react-hooks) [Kent C. Dodds]. Canonical modern articulation of the compound-component pattern with hooks-based React.
122
+ - shadcn. [shadcn/ui documentation](https://ui.shadcn.com/). The 'registry' distribution model (copy into the consumer's repo) and the canonical example of the headless-primitive + styled-wrapper layered architecture.
123
+ - Vue Team. [Vue.js Slots documentation](https://vuejs.org/guide/components/slots.html). The reference framework-native slot mechanism that predates and inspired React's compound-component patterns; demonstrates that the architectural principles apply across frameworks.
124
+ - Liskov, B. (1987). "Data Abstraction and Hierarchy." *Proceedings of OOPSLA '87 Addendum*. The Liskov Substitution Principle — adapted in this skill as the constraint that polymorphic substitutions must preserve invariants.
125
+ - Garlan, D., & Shaw, M. (1993). "An Introduction to Software Architecture." *Advances in Software Engineering and Knowledge Engineering*, Vol. 1. The foundational treatment of layered architectures as a software-architecture pattern; provides the dependency-direction reasoning this skill adapts to components.
126
+ - Gamma, E., Helm, R., Johnson, R., & Vlissides, J. (1994). *Design Patterns: Elements of Reusable Object-Oriented Software*. Addison-Wesley. The Composite, Decorator, and Strategy patterns underlie much of the composition-vs-configuration framing; the foundational reference for reuse-via-composition.