@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.
- package/CHANGELOG.md +247 -0
- package/LICENSE +200 -0
- package/NOTICE +62 -0
- package/README.md +398 -0
- package/SKILL_GRAPH.md +443 -0
- package/bin/skill-graph.js +374 -0
- package/docs/ADOPTION.md +117 -0
- package/docs/CONFORMANCE.md +66 -0
- package/docs/PRIMER.md +384 -0
- package/docs/QUICKSTART-30MIN.md +333 -0
- package/docs/ROUTING-METRICS.md +120 -0
- package/docs/SKILL-MD-FORMAT-COMPATIBILITY.md +127 -0
- package/docs/SKILL_AUDIT_CHECKLIST.md +199 -0
- package/docs/SKILL_AUDIT_LOOP.md +195 -0
- package/docs/SKILL_METADATA_PROTOCOL.md +609 -0
- package/docs/_archived/marketplace-publication-priority-2026-05-18.md +239 -0
- package/docs/adr/0001-predicate-set.md +69 -0
- package/docs/adr/0002-json-ld-context.md +82 -0
- package/docs/adr/0003-ontoclean-rigidity-tags.md +65 -0
- package/docs/adr/0004-persistent-identifiers.md +74 -0
- package/docs/adr/0005-freshness-consolidation.md +70 -0
- package/docs/adr/0006-revise-predicate-rename.md +105 -0
- package/docs/adr/0007-audit-loop-cadence.md +99 -0
- package/docs/adr/0008-skill-surface-split-and-curation-policy.md +93 -0
- package/docs/category-consumers.md +168 -0
- package/docs/concept-map.md +194 -0
- package/docs/diagrams/drift-states.mmd +21 -0
- package/docs/diagrams/manifest-pipeline.mmd +25 -0
- package/docs/diagrams/routing-harness.mmd +41 -0
- package/docs/diagrams/starter-graph.mmd +53 -0
- package/docs/field-decision-guide.md +315 -0
- package/docs/field-rationale.md +211 -0
- package/docs/field-reference.generated.md +624 -0
- package/docs/field-reference.md +1426 -0
- package/docs/glossary.md +190 -0
- package/docs/head-noun-glossary.md +63 -0
- package/docs/images/audit-phases.png +0 -0
- package/docs/images/drift-states.png +0 -0
- package/docs/images/graded-mode.png +0 -0
- package/docs/images/manifest-pipeline.png +0 -0
- package/docs/images/routing-harness.png +0 -0
- package/docs/images/skill-anatomy.png +0 -0
- package/docs/images/starter-graph.png +0 -0
- package/docs/images/system-model.png +0 -0
- package/docs/integrations/github-actions.md +155 -0
- package/docs/manifest-field-mapping.md +443 -0
- package/docs/marketplace-publication-queue.generated.md +240 -0
- package/docs/marketplace-release-agent-prompt.md +82 -0
- package/docs/marketplace-skill-candidate-list.md +272 -0
- package/docs/marketplace-syndication.md +222 -0
- package/docs/migration-sample-review.md +155 -0
- package/docs/migrations/v4-to-v5.md +168 -0
- package/docs/migrations/v5-to-v6.md +221 -0
- package/docs/name-exceptions.yaml +37 -0
- package/docs/plans/marketplace-p1-public-migration-plan.md +41 -0
- package/docs/plans/multi-root-workspace.md +148 -0
- package/docs/plans/scripts-roadmap.md +107 -0
- package/docs/plans/v4-schema-bump.md +160 -0
- package/docs/plans/wave-2-extraction.md +122 -0
- package/docs/positioning-vs-marketplaces.md +175 -0
- package/docs/proposals/skill-audit-loop-positioning.md +160 -0
- package/docs/quality-doctrine.md +138 -0
- package/docs/recommended-skills.md +150 -0
- package/docs/research/skill-comprehension-eval-research.md +1830 -0
- package/docs/research/skill-retrieval-evidence.md +66 -0
- package/docs/skill-metadata-protocol.md +471 -0
- package/docs/skills-sh-maintainer-cleanup-request.md +80 -0
- package/examples/audits/a11y/findings.md +52 -0
- package/examples/audits/a11y/scorecard.md +21 -0
- package/examples/audits/a11y/verdict.md +44 -0
- package/examples/audits/debugging/findings.md +59 -0
- package/examples/audits/debugging/scorecard.md +22 -0
- package/examples/audits/debugging/verdict.md +33 -0
- package/examples/audits/documentation/findings.md +59 -0
- package/examples/audits/documentation/scorecard.md +22 -0
- package/examples/audits/documentation/verdict.md +33 -0
- package/examples/evals/a11y.json +140 -0
- package/examples/evals/api-design.json +52 -0
- package/examples/evals/code-review.json +52 -0
- package/examples/evals/data-modeling.json +52 -0
- package/examples/evals/database-migration.json +52 -0
- package/examples/evals/debugging.json +118 -0
- package/examples/evals/dependency-architecture.json +52 -0
- package/examples/evals/design-system-architecture.json +52 -0
- package/examples/evals/error-tracking.json +52 -0
- package/examples/evals/event-contract-design.json +52 -0
- package/examples/evals/form-ux-architecture.json +52 -0
- package/examples/evals/framework-fit-analysis.json +52 -0
- package/examples/evals/graph-audit.json +139 -0
- package/examples/evals/information-architecture.json +52 -0
- package/examples/evals/interaction-feedback.json +52 -0
- package/examples/evals/interaction-patterns.json +52 -0
- package/examples/evals/layout-composition.json +52 -0
- package/examples/evals/lint-overlay.json +117 -0
- package/examples/evals/microcopy.json +52 -0
- package/examples/evals/observability-modeling.json +52 -0
- package/examples/evals/pattern-recognition.json +96 -0
- package/examples/evals/performance-engineering.json +52 -0
- package/examples/evals/refactor.json +128 -0
- package/examples/evals/semiotics.json +52 -0
- package/examples/evals/skill-infrastructure.json +96 -0
- package/examples/evals/skill-router.json +140 -0
- package/examples/evals/skill-router.routing.json +113 -0
- package/examples/evals/system-interface-contracts.json +52 -0
- package/examples/evals/task-analysis.json +52 -0
- package/examples/evals/testing-strategy.json +118 -0
- package/examples/evals/type-safety.json +249 -0
- package/examples/evals/visual-design-foundations.json +52 -0
- package/examples/evals/webhook-integration.json +52 -0
- package/examples/exports/a11y.skill-md.md +80 -0
- package/examples/exports/debugging.skill-md.md +80 -0
- package/examples/exports/refactor.skill-md.md +78 -0
- package/examples/exports/testing-strategy.skill-md.md +81 -0
- package/examples/projects/markdown-static-site/README.md +115 -0
- package/examples/projects/markdown-static-site/skills/content-source-router/SKILL.md +131 -0
- package/examples/projects/markdown-static-site/skills/image-optimization-pipeline-config/SKILL.md +132 -0
- package/examples/projects/markdown-static-site/skills/link-rot-detection/SKILL.md +103 -0
- package/examples/projects/markdown-static-site/skills/markdown-post-frontmatter-validation/SKILL.md +133 -0
- package/examples/projects/markdown-static-site/skills/migrate-posts-to-v2-frontmatter/SKILL.md +140 -0
- package/examples/projects/saas-stripe-postgres/README.md +208 -0
- package/examples/projects/saas-stripe-postgres/db/migrations/0004_canonicalize_orders.sql +37 -0
- package/examples/projects/saas-stripe-postgres/db/schema.sql +112 -0
- package/examples/projects/saas-stripe-postgres/skills/migrate-orders-to-canonical-schema/SKILL.md +149 -0
- package/examples/projects/saas-stripe-postgres/skills/nextjs-server-action-validation/SKILL.md +154 -0
- package/examples/projects/saas-stripe-postgres/skills/payment-provider-router/SKILL.md +153 -0
- package/examples/projects/saas-stripe-postgres/skills/postgres-rls-pattern/SKILL.md +163 -0
- package/examples/projects/saas-stripe-postgres/skills/stripe-webhook-signature-verification/SKILL.md +137 -0
- package/examples/protocol/skill-metadata-template.md +301 -0
- package/examples/protocol/skills.manifest.sample.json +13245 -0
- package/examples/skill-metadata-template.md +317 -0
- package/examples/skills.manifest.sample.json +13519 -0
- package/examples/tests/v3-1-skos-fixture/SKILL.md +93 -0
- package/marketplace/README.md +17 -0
- package/marketplace/skills/a11y/SKILL.md +66 -0
- package/marketplace/skills/acid-fundamentals/SKILL.md +106 -0
- package/marketplace/skills/agent-engineering/SKILL.md +386 -0
- package/marketplace/skills/agent-eval-design/SKILL.md +55 -0
- package/marketplace/skills/ai-native-development/SKILL.md +294 -0
- package/marketplace/skills/api-design/SKILL.md +60 -0
- package/marketplace/skills/architecture-decision-records/SKILL.md +55 -0
- package/marketplace/skills/background-jobs/SKILL.md +265 -0
- package/marketplace/skills/bounded-context-mapping/SKILL.md +55 -0
- package/marketplace/skills/cap-theorem-tradeoffs/SKILL.md +127 -0
- package/marketplace/skills/client-server-boundary/SKILL.md +187 -0
- package/marketplace/skills/code-review/SKILL.md +120 -0
- package/marketplace/skills/color-system-design/SKILL.md +43 -0
- package/marketplace/skills/component-architecture/SKILL.md +126 -0
- package/marketplace/skills/compression/SKILL.md +112 -0
- package/marketplace/skills/conceptual-modeling/SKILL.md +181 -0
- package/marketplace/skills/connection-pooling/SKILL.md +105 -0
- package/marketplace/skills/constraint-awareness/SKILL.md +287 -0
- package/marketplace/skills/content-monitor/SKILL.md +209 -0
- package/marketplace/skills/context-engineering/SKILL.md +320 -0
- package/marketplace/skills/context-graph/SKILL.md +174 -0
- package/marketplace/skills/context-management/SKILL.md +174 -0
- package/marketplace/skills/context-window/SKILL.md +239 -0
- package/marketplace/skills/contract-testing/SKILL.md +120 -0
- package/marketplace/skills/cron-scheduling/SKILL.md +223 -0
- package/marketplace/skills/dark-mode-implementation/SKILL.md +47 -0
- package/marketplace/skills/data-modeling/SKILL.md +59 -0
- package/marketplace/skills/data-modeling-fundamentals/SKILL.md +117 -0
- package/marketplace/skills/database-migration/SKILL.md +429 -0
- package/marketplace/skills/debugging/SKILL.md +67 -0
- package/marketplace/skills/dependency-architecture/SKILL.md +58 -0
- package/marketplace/skills/design-module-composition/SKILL.md +43 -0
- package/marketplace/skills/design-system-architecture/SKILL.md +61 -0
- package/marketplace/skills/design-thinking/SKILL.md +44 -0
- package/marketplace/skills/diagnosis/SKILL.md +296 -0
- package/marketplace/skills/diff-analysis/SKILL.md +188 -0
- package/marketplace/skills/e2e-test-design/SKILL.md +113 -0
- package/marketplace/skills/entity-relationship-modeling/SKILL.md +218 -0
- package/marketplace/skills/epistemic-grounding/SKILL.md +112 -0
- package/marketplace/skills/error-boundary/SKILL.md +235 -0
- package/marketplace/skills/error-tracking/SKILL.md +261 -0
- package/marketplace/skills/eval-driven-development/SKILL.md +147 -0
- package/marketplace/skills/evaluation/SKILL.md +113 -0
- package/marketplace/skills/event-contract-design/SKILL.md +60 -0
- package/marketplace/skills/event-storming/SKILL.md +56 -0
- package/marketplace/skills/form-ux-architecture/SKILL.md +60 -0
- package/marketplace/skills/framework-fit-analysis/SKILL.md +59 -0
- package/marketplace/skills/frontend-architecture/SKILL.md +43 -0
- package/marketplace/skills/generative-ui/SKILL.md +118 -0
- package/marketplace/skills/graph-audit/SKILL.md +81 -0
- package/marketplace/skills/guardrails/SKILL.md +118 -0
- package/marketplace/skills/hooks-patterns/SKILL.md +185 -0
- package/marketplace/skills/http-semantics/SKILL.md +136 -0
- package/marketplace/skills/ideation/SKILL.md +41 -0
- package/marketplace/skills/indexing-strategy/SKILL.md +108 -0
- package/marketplace/skills/information-architecture/SKILL.md +59 -0
- package/marketplace/skills/integration-test-design/SKILL.md +111 -0
- package/marketplace/skills/intent-recognition/SKILL.md +136 -0
- package/marketplace/skills/interaction-feedback/SKILL.md +59 -0
- package/marketplace/skills/interaction-patterns/SKILL.md +59 -0
- package/marketplace/skills/journey-mapping/SKILL.md +41 -0
- package/marketplace/skills/keywords/SKILL.md +213 -0
- package/marketplace/skills/knowledge-modeling/SKILL.md +232 -0
- package/marketplace/skills/layout-composition/SKILL.md +59 -0
- package/marketplace/skills/linguistics/SKILL.md +429 -0
- package/marketplace/skills/lint-overlay/SKILL.md +76 -0
- package/marketplace/skills/mental-models/SKILL.md +126 -0
- package/marketplace/skills/merge-queue/SKILL.md +94 -0
- package/marketplace/skills/methodology/SKILL.md +317 -0
- package/marketplace/skills/microcopy/SKILL.md +232 -0
- package/marketplace/skills/middleware-patterns/SKILL.md +363 -0
- package/marketplace/skills/mobile-responsive-ux/SKILL.md +287 -0
- package/marketplace/skills/mutation-testing/SKILL.md +112 -0
- package/marketplace/skills/naming-conventions/SKILL.md +112 -0
- package/marketplace/skills/observability-modeling/SKILL.md +59 -0
- package/marketplace/skills/ontology-modeling/SKILL.md +67 -0
- package/marketplace/skills/owasp-security/SKILL.md +153 -0
- package/marketplace/skills/pattern-recognition/SKILL.md +472 -0
- package/marketplace/skills/performance-budgets/SKILL.md +185 -0
- package/marketplace/skills/performance-engineering/SKILL.md +58 -0
- package/marketplace/skills/performance-testing/SKILL.md +125 -0
- package/marketplace/skills/printify/SKILL.md +42 -0
- package/marketplace/skills/prioritization/SKILL.md +118 -0
- package/marketplace/skills/problem-framing/SKILL.md +41 -0
- package/marketplace/skills/problem-locating-solving/SKILL.md +203 -0
- package/marketplace/skills/project-knowledge-extraction/SKILL.md +54 -0
- package/marketplace/skills/prompt-craft/SKILL.md +134 -0
- package/marketplace/skills/prompt-injection-defense/SKILL.md +132 -0
- package/marketplace/skills/property-based-testing/SKILL.md +100 -0
- package/marketplace/skills/prototyping/SKILL.md +43 -0
- package/marketplace/skills/query-optimization/SKILL.md +144 -0
- package/marketplace/skills/real-time-updates/SKILL.md +324 -0
- package/marketplace/skills/ref-patterns/SKILL.md +284 -0
- package/marketplace/skills/refactor/SKILL.md +65 -0
- package/marketplace/skills/rendering-models/SKILL.md +142 -0
- package/marketplace/skills/replication-patterns/SKILL.md +110 -0
- package/marketplace/skills/research-synthesis/SKILL.md +41 -0
- package/marketplace/skills/route-handler-design/SKILL.md +347 -0
- package/marketplace/skills/schema-evolution/SKILL.md +140 -0
- package/marketplace/skills/security-fundamentals/SKILL.md +139 -0
- package/marketplace/skills/semantic-center/SKILL.md +194 -0
- package/marketplace/skills/semantic-relations/SKILL.md +250 -0
- package/marketplace/skills/semantics/SKILL.md +366 -0
- package/marketplace/skills/semiotics/SKILL.md +230 -0
- package/marketplace/skills/seo-strategy/SKILL.md +260 -0
- package/marketplace/skills/server-actions-design/SKILL.md +243 -0
- package/marketplace/skills/server-components-design/SKILL.md +190 -0
- package/marketplace/skills/sharding-strategy/SKILL.md +123 -0
- package/marketplace/skills/shopify/SKILL.md +42 -0
- package/marketplace/skills/skill-infrastructure/SKILL.md +320 -0
- package/marketplace/skills/skill-router/SKILL.md +71 -0
- package/marketplace/skills/skill-scaffold/SKILL.md +105 -0
- package/marketplace/skills/snapshot-testing/SKILL.md +120 -0
- package/marketplace/skills/spec-driven-development/SKILL.md +148 -0
- package/marketplace/skills/state-machine-modeling/SKILL.md +56 -0
- package/marketplace/skills/state-management/SKILL.md +134 -0
- package/marketplace/skills/streaming-architecture/SKILL.md +194 -0
- package/marketplace/skills/summarization/SKILL.md +156 -0
- package/marketplace/skills/suspense-patterns/SKILL.md +265 -0
- package/marketplace/skills/system-interface-contracts/SKILL.md +59 -0
- package/marketplace/skills/task-analysis/SKILL.md +201 -0
- package/marketplace/skills/taxonomy-design/SKILL.md +66 -0
- package/marketplace/skills/test-coverage-strategy/SKILL.md +108 -0
- package/marketplace/skills/test-doubles-design/SKILL.md +98 -0
- package/marketplace/skills/test-driven-development/SKILL.md +96 -0
- package/marketplace/skills/testing-strategy/SKILL.md +67 -0
- package/marketplace/skills/theme-system-design/SKILL.md +43 -0
- package/marketplace/skills/tool-call-flow/SKILL.md +229 -0
- package/marketplace/skills/tool-call-strategy/SKILL.md +292 -0
- package/marketplace/skills/transaction-isolation/SKILL.md +98 -0
- package/marketplace/skills/type-safety/SKILL.md +177 -0
- package/marketplace/skills/typography-system/SKILL.md +43 -0
- package/marketplace/skills/usability-testing/SKILL.md +43 -0
- package/marketplace/skills/user-research/SKILL.md +43 -0
- package/marketplace/skills/vercel-composition-patterns/SKILL.md +157 -0
- package/marketplace/skills/version-control/SKILL.md +233 -0
- package/marketplace/skills/visual-design-foundations/SKILL.md +59 -0
- package/marketplace/skills/visual-hierarchy/SKILL.md +43 -0
- package/marketplace/skills/webhook-integration/SKILL.md +331 -0
- package/marketplace/skills/writing-humanizer/SKILL.md +380 -0
- package/package.json +67 -0
- package/schemas/manifest.schema.json +811 -0
- package/schemas/manifest.v2.schema.json +164 -0
- package/schemas/manifest.v3.schema.json +758 -0
- package/schemas/manifest.v4.schema.json +755 -0
- package/schemas/manifest.v5.schema.json +755 -0
- package/schemas/manifest.v6.schema.json +811 -0
- package/schemas/skill.context.jsonld +279 -0
- package/schemas/skill.schema.json +919 -0
- package/schemas/skill.v2.schema.json +201 -0
- package/schemas/skill.v3.schema.json +827 -0
- package/schemas/skill.v4.schema.json +822 -0
- package/schemas/skill.v5.schema.json +830 -0
- package/schemas/skill.v6.schema.json +946 -0
- package/schemas/vocabulary/keywords.json +180 -0
- package/schemas/vocabulary/workspace_tags.json +23 -0
- package/scripts/__tests__/migrate-skill-v2-to-v3.test.js +161 -0
- package/scripts/__tests__/migrate-skill-v3-to-v4.test.js +158 -0
- package/scripts/__tests__/test-export-parser-drift.js +149 -0
- package/scripts/__tests__/test-marketplace-export.js +114 -0
- package/scripts/__tests__/test-router-paths.js +82 -0
- package/scripts/__tests__/test-stability-promotion.js +244 -0
- package/scripts/__tests__/test-v3-1-alias-contract.js +109 -0
- package/scripts/__tests__/test-v3-1-skos-runtime.js +116 -0
- package/scripts/backfill-schema-version.js +198 -0
- package/scripts/build-field-reference.js +160 -0
- package/scripts/build-retrieval-baseline.js +511 -0
- package/scripts/check-markdown-links.js +211 -0
- package/scripts/check-protocol-consistency.js +979 -0
- package/scripts/export-marketplace-skills.js +610 -0
- package/scripts/export-skill.js +374 -0
- package/scripts/generate-manifest.js +787 -0
- package/scripts/lib/alias-contract.js +83 -0
- package/scripts/lib/audit-prompt-builder.js +771 -0
- package/scripts/lib/mock-grader.js +134 -0
- package/scripts/lib/parse-frontmatter.js +429 -0
- package/scripts/lib/roots.js +119 -0
- package/scripts/lint/check-archetype-sections.js +185 -0
- package/scripts/lint/check-category-enum.js +83 -0
- package/scripts/lint/check-routing-eval.js +146 -0
- package/scripts/lint/check-routing-quality.js +211 -0
- package/scripts/lint/check-stability-promotion.js +220 -0
- package/scripts/lint/format-code-frame.js +206 -0
- package/scripts/marketplace-install.js +125 -0
- package/scripts/migrate-category-to-enum.js +169 -0
- package/scripts/migrate-skill-v2-to-v3.js +424 -0
- package/scripts/migrate-skill-v3-to-v4.js +200 -0
- package/scripts/migrate-skill-v5-to-v6.js +304 -0
- package/scripts/restructure-by-category.js +85 -0
- package/scripts/seed-publication-classification.js +282 -0
- package/scripts/skill-audit.js +893 -0
- package/scripts/skill-graph-drift.js +483 -0
- package/scripts/skill-graph-route.js +766 -0
- package/scripts/skill-graph-routing-eval.js +393 -0
- package/scripts/skill-lint.js +1317 -0
- package/scripts/skill-overlap.js +213 -0
- package/scripts/verify-skill-md-export.js +201 -0
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
---
|
|
2
|
+
# yaml-language-server: $schema=https://skillgraph.dev/schemas/skill.v6.schema.json
|
|
3
|
+
schema_version: 6
|
|
4
|
+
name: postgres-rls-pattern
|
|
5
|
+
description: "Use when writing or reviewing Postgres queries in a multi-tenant SaaS where every table row must be scoped to a single organization. Enforces the FORCE ROW LEVEL SECURITY + USING + WITH CHECK triple on every tenant-bound table, and wraps application queries in an `orgQuery(orgId)` helper that sets `app.current_org_id` before each statement. Do NOT use for cross-org system queries such as billing cron jobs or admin panels (those bypass RLS intentionally via the service role); use a service-role query wrapper instead."
|
|
6
|
+
version: 0.1.0
|
|
7
|
+
type: capability
|
|
8
|
+
category: engineering
|
|
9
|
+
domain: engineering/database
|
|
10
|
+
scope: portable
|
|
11
|
+
owner: saas-stripe-postgres-example
|
|
12
|
+
freshness: "2026-05-18"
|
|
13
|
+
drift_check:
|
|
14
|
+
last_verified: "2026-05-18"
|
|
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: "Postgres >=14 with row-level security enabled; assumes pg or postgres.js driver."
|
|
25
|
+
allowed-tools: Read Grep
|
|
26
|
+
keywords:
|
|
27
|
+
- postgres row level security
|
|
28
|
+
- RLS multi-tenant
|
|
29
|
+
- orgQuery wrapper
|
|
30
|
+
- FORCE ROW LEVEL SECURITY
|
|
31
|
+
- SET app.current_org_id
|
|
32
|
+
- tenant data isolation
|
|
33
|
+
- cross-tenant data leak prevention
|
|
34
|
+
- multi-tenant postgres
|
|
35
|
+
- row security policy
|
|
36
|
+
- using with check policy
|
|
37
|
+
triggers:
|
|
38
|
+
- postgres-rls-pattern
|
|
39
|
+
paths:
|
|
40
|
+
- "lib/db.ts"
|
|
41
|
+
- "db/schema.sql"
|
|
42
|
+
- "db/migrations/*.sql"
|
|
43
|
+
examples:
|
|
44
|
+
- "how do I prevent one tenant's data from appearing in another tenant's queries?"
|
|
45
|
+
- "write the RLS policy for the orders table in a multi-tenant SaaS"
|
|
46
|
+
- "set up the orgQuery helper so every query is automatically scoped to the current org"
|
|
47
|
+
- "add row level security to a new subscriptions table"
|
|
48
|
+
anti_examples:
|
|
49
|
+
- "run a billing cron job that needs to read all orgs"
|
|
50
|
+
- "write a migration that backfills data across all organizations"
|
|
51
|
+
- "query the database without any tenant context for an admin dashboard"
|
|
52
|
+
relations:
|
|
53
|
+
boundary:
|
|
54
|
+
- skill: migrate-orders-to-canonical-schema
|
|
55
|
+
reason: "migrate-orders-to-canonical-schema changes column layout; this skill defines the RLS policy that must be updated alongside any schema change on tenant-bound tables"
|
|
56
|
+
- skill: nextjs-server-action-validation
|
|
57
|
+
reason: "nextjs-server-action-validation validates the input layer; this skill governs the query layer — both are required but at different tiers"
|
|
58
|
+
depends_on: []
|
|
59
|
+
verify_with:
|
|
60
|
+
- migrate-orders-to-canonical-schema
|
|
61
|
+
portability:
|
|
62
|
+
readiness: portable
|
|
63
|
+
targets:
|
|
64
|
+
- skill-md
|
|
65
|
+
lifecycle:
|
|
66
|
+
stale_after_days: 180
|
|
67
|
+
review_cadence: quarterly
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
# Postgres RLS Pattern
|
|
71
|
+
|
|
72
|
+
## Coverage
|
|
73
|
+
|
|
74
|
+
- The three-part policy triple — `FORCE ROW LEVEL SECURITY`, `USING (org_id = current_setting('app.current_org_id')::uuid)`, and `WITH CHECK (org_id = current_setting('app.current_org_id')::uuid)` — and why omitting any one part leaves a gap
|
|
75
|
+
- The `orgQuery(orgId)` application wrapper — a single function that opens a transaction, sets `app.current_org_id`, runs the caller's query, and commits; why setting the variable once at session start is unsafe under connection pooling
|
|
76
|
+
- Service role bypass — legitimate cross-org operations (billing cron, admin panel, migration backfills) that must use a connection string that skips RLS, and why those code paths must be isolated from application code
|
|
77
|
+
- Policy audit checklist — grepping for `query()` calls without a preceding `SET app.current_org_id` as a CI-safe audit gate
|
|
78
|
+
- New-table checklist — steps to add RLS to a table that was created before RLS was enforced on the schema
|
|
79
|
+
|
|
80
|
+
## Philosophy
|
|
81
|
+
|
|
82
|
+
Row-level security on Postgres is the difference between "we checked org_id in the WHERE clause" and "the database rejects cross-org reads at the storage layer." Application-level checks are deleted by a single missing WHERE clause; RLS cannot be bypassed unless you use the service role explicitly. The cost is a session variable that must be set before every query and a discipline of never using the service role for application queries. Both costs are cheap relative to the consequence of a cross-tenant data leak.
|
|
83
|
+
|
|
84
|
+
## Schema Pattern
|
|
85
|
+
|
|
86
|
+
```sql
|
|
87
|
+
-- 1. Enable and force RLS on every tenant-bound table
|
|
88
|
+
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
|
|
89
|
+
ALTER TABLE orders FORCE ROW LEVEL SECURITY;
|
|
90
|
+
|
|
91
|
+
-- 2. SELECT policy — only rows where org_id matches the session variable
|
|
92
|
+
CREATE POLICY orders_org_select ON orders
|
|
93
|
+
FOR SELECT
|
|
94
|
+
USING (org_id = current_setting('app.current_org_id', true)::uuid);
|
|
95
|
+
|
|
96
|
+
-- 3. INSERT policy — only allow inserts that match the session variable
|
|
97
|
+
CREATE POLICY orders_org_insert ON orders
|
|
98
|
+
FOR INSERT
|
|
99
|
+
WITH CHECK (org_id = current_setting('app.current_org_id', true)::uuid);
|
|
100
|
+
|
|
101
|
+
-- 4. UPDATE policy — USING (read filter) AND WITH CHECK (write filter)
|
|
102
|
+
CREATE POLICY orders_org_update ON orders
|
|
103
|
+
FOR UPDATE
|
|
104
|
+
USING (org_id = current_setting('app.current_org_id', true)::uuid)
|
|
105
|
+
WITH CHECK (org_id = current_setting('app.current_org_id', true)::uuid);
|
|
106
|
+
|
|
107
|
+
-- 5. DELETE policy
|
|
108
|
+
CREATE POLICY orders_org_delete ON orders
|
|
109
|
+
FOR DELETE
|
|
110
|
+
USING (org_id = current_setting('app.current_org_id', true)::uuid);
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Application Wrapper Pattern
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
// lib/db.ts
|
|
117
|
+
import postgres from "postgres";
|
|
118
|
+
|
|
119
|
+
const sql = postgres(process.env.DATABASE_URL!);
|
|
120
|
+
|
|
121
|
+
/** Tenant-scoped query: sets app.current_org_id for every statement. */
|
|
122
|
+
export async function orgQuery<T>(
|
|
123
|
+
orgId: string,
|
|
124
|
+
fn: (sql: postgres.Sql) => Promise<T>
|
|
125
|
+
): Promise<T> {
|
|
126
|
+
return sql.begin(async (tx) => {
|
|
127
|
+
await tx`SELECT set_config('app.current_org_id', ${orgId}, true)`;
|
|
128
|
+
return fn(tx);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** System query: bypasses RLS. Use ONLY for cron jobs, migrations, and admin. */
|
|
133
|
+
export async function systemQuery<T>(fn: (sql: postgres.Sql) => Promise<T>): Promise<T> {
|
|
134
|
+
return fn(sql);
|
|
135
|
+
}
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Usage in a Server Action:
|
|
139
|
+
|
|
140
|
+
```typescript
|
|
141
|
+
import { orgQuery } from "@/lib/db";
|
|
142
|
+
|
|
143
|
+
export async function getOrders(orgId: string) {
|
|
144
|
+
return orgQuery(orgId, (tx) => tx`SELECT * FROM orders ORDER BY created_at DESC`);
|
|
145
|
+
}
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
## Verification
|
|
149
|
+
|
|
150
|
+
- [ ] Every tenant-bound table has `ENABLE ROW LEVEL SECURITY` AND `FORCE ROW LEVEL SECURITY`
|
|
151
|
+
- [ ] Every DML operation (SELECT, INSERT, UPDATE, DELETE) has a corresponding policy on each table
|
|
152
|
+
- [ ] `WITH CHECK` is present on INSERT and UPDATE policies (not just `USING`)
|
|
153
|
+
- [ ] `orgQuery` sets the variable inside a transaction, not at session start
|
|
154
|
+
- [ ] No application code calls `systemQuery` (grep for `systemQuery` in `apps/` and `lib/` — any hit is a finding)
|
|
155
|
+
- [ ] Every new migration that adds a table includes the RLS policy triple in the same migration file
|
|
156
|
+
|
|
157
|
+
## Do NOT Use When
|
|
158
|
+
|
|
159
|
+
| Use instead | When |
|
|
160
|
+
|---|---|
|
|
161
|
+
| `systemQuery` wrapper | The query legitimately crosses org boundaries (billing cron, migration backfill, admin panel) |
|
|
162
|
+
| `migrate-orders-to-canonical-schema` | The task is a schema migration that also needs to update RLS policies |
|
|
163
|
+
| (a database skill without multi-tenancy scope) | The application is single-tenant and org_id isolation is not a requirement |
|
package/examples/projects/saas-stripe-postgres/skills/stripe-webhook-signature-verification/SKILL.md
ADDED
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
---
|
|
2
|
+
# yaml-language-server: $schema=https://skillgraph.dev/schemas/skill.v6.schema.json
|
|
3
|
+
schema_version: 6
|
|
4
|
+
name: stripe-webhook-signature-verification
|
|
5
|
+
description: "Use when validating incoming Stripe webhook requests in a Node.js or Next.js backend before processing any payment event. Verifies the `stripe-signature` header against `STRIPE_WEBHOOK_SECRET` using Stripe's HMAC-SHA256 scheme, and rejects replays older than 300 seconds. Do NOT use for general HTTP signature validation (use a generic crypto-signature skill), for processing the webhook payload after signature is confirmed (use payment-provider-router), or for Stripe API calls that are not webhook-driven."
|
|
6
|
+
version: 0.1.0
|
|
7
|
+
type: capability
|
|
8
|
+
category: engineering
|
|
9
|
+
domain: engineering/payments
|
|
10
|
+
scope: portable
|
|
11
|
+
owner: saas-stripe-postgres-example
|
|
12
|
+
freshness: "2026-05-18"
|
|
13
|
+
drift_check:
|
|
14
|
+
last_verified: "2026-05-18"
|
|
15
|
+
truth_source_hashes:
|
|
16
|
+
stripe-webhook-docs: "sha256:placeholder-record-with-node-scripts-skill-graph-drift-js"
|
|
17
|
+
eval_artifacts: none
|
|
18
|
+
eval_state: unverified
|
|
19
|
+
routing_eval: absent
|
|
20
|
+
stability: experimental
|
|
21
|
+
license: MIT
|
|
22
|
+
compatibility:
|
|
23
|
+
runtimes:
|
|
24
|
+
- node
|
|
25
|
+
node: ">=20"
|
|
26
|
+
notes: "Stripe SDK >=14; expects raw request body (not parsed JSON) for signature verification."
|
|
27
|
+
allowed-tools: Read Grep
|
|
28
|
+
keywords:
|
|
29
|
+
- stripe webhook signature verification
|
|
30
|
+
- stripe-signature header
|
|
31
|
+
- webhook hmac verification
|
|
32
|
+
- STRIPE_WEBHOOK_SECRET
|
|
33
|
+
- stripe constructEvent
|
|
34
|
+
- replay attack prevention
|
|
35
|
+
- webhook security
|
|
36
|
+
- payment webhook validation
|
|
37
|
+
- stripe webhook secret
|
|
38
|
+
triggers:
|
|
39
|
+
- stripe-webhook-signature-verification
|
|
40
|
+
paths:
|
|
41
|
+
- "app/api/webhooks/stripe/route.ts"
|
|
42
|
+
- "lib/stripe/webhook.ts"
|
|
43
|
+
examples:
|
|
44
|
+
- "how do I verify that a webhook is really from Stripe?"
|
|
45
|
+
- "my webhook handler is returning 400 — is the signature verification failing?"
|
|
46
|
+
- "set up the Stripe webhook endpoint in a Next.js App Router API route"
|
|
47
|
+
- "reject replayed webhook events older than 5 minutes"
|
|
48
|
+
anti_examples:
|
|
49
|
+
- "process the Stripe payment_intent.succeeded event payload"
|
|
50
|
+
- "call the Stripe API to create a payment intent"
|
|
51
|
+
- "validate a generic HTTP signature that is not from Stripe"
|
|
52
|
+
relations:
|
|
53
|
+
boundary:
|
|
54
|
+
- skill: payment-provider-router
|
|
55
|
+
reason: "payment-provider-router decides which downstream handler receives the verified event; this skill verifies authenticity before any routing happens"
|
|
56
|
+
- skill: nextjs-server-action-validation
|
|
57
|
+
reason: "nextjs-server-action-validation validates user-submitted form input via Zod; this skill validates Stripe's HMAC signature — different trust boundary, different mechanism"
|
|
58
|
+
depends_on:
|
|
59
|
+
- skill: postgres-rls-pattern
|
|
60
|
+
reason: "idempotency key lookups that prevent double-processing run inside the RLS-scoped query layer; this skill activates before those lookups"
|
|
61
|
+
verify_with:
|
|
62
|
+
- nextjs-server-action-validation
|
|
63
|
+
portability:
|
|
64
|
+
readiness: portable
|
|
65
|
+
targets:
|
|
66
|
+
- skill-md
|
|
67
|
+
lifecycle:
|
|
68
|
+
stale_after_days: 90
|
|
69
|
+
review_cadence: quarterly
|
|
70
|
+
---
|
|
71
|
+
|
|
72
|
+
# Stripe Webhook Signature Verification
|
|
73
|
+
|
|
74
|
+
## Coverage
|
|
75
|
+
|
|
76
|
+
- The raw-body requirement — why `stripe.webhooks.constructEvent()` requires the unparsed `Buffer` from the request body, and how Next.js App Router routes expose it via `request.arrayBuffer()`
|
|
77
|
+
- HMAC-SHA256 verification — how `constructEvent(rawBody, signature, secret)` reconstructs and compares the Stripe signature internally
|
|
78
|
+
- Replay protection — the 300-second tolerance window Stripe checks against the `t=` timestamp embedded in the `stripe-signature` header; when to tighten it
|
|
79
|
+
- Environment-specific secrets — `STRIPE_WEBHOOK_SECRET` for production vs `whsec_...` from the Stripe CLI `--forward-to` session in development; why they must never be swapped
|
|
80
|
+
- Idempotency key pattern — recording the `event.id` in Postgres before processing so a retried delivery does not double-charge or double-fulfill
|
|
81
|
+
|
|
82
|
+
## Philosophy
|
|
83
|
+
|
|
84
|
+
A webhook that skips signature verification is an unauthenticated public endpoint that can trigger payment processing. The verification step is load-bearing security, not a convenience check. Stripe's SDK makes verification a single call, but two failure modes are common in practice: the request body gets parsed (by a body-parser middleware) before the raw bytes reach the verification call, which silently corrupts the HMAC comparison; and the wrong webhook secret is loaded from environment variables, producing a 400 that is hard to distinguish from a replay rejection. Both failures look the same to the caller — a rejected webhook — and both are invisible until a real event is dropped.
|
|
85
|
+
|
|
86
|
+
## Verification
|
|
87
|
+
|
|
88
|
+
1. **Confirm raw body access.** In Next.js App Router: `const rawBody = Buffer.from(await request.arrayBuffer())`. Do NOT pass `await request.json()` or `await request.text()` — both transform the bytes.
|
|
89
|
+
|
|
90
|
+
2. **Retrieve and verify.**
|
|
91
|
+
|
|
92
|
+
```typescript
|
|
93
|
+
import Stripe from "stripe";
|
|
94
|
+
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!);
|
|
95
|
+
|
|
96
|
+
const sig = request.headers.get("stripe-signature") ?? "";
|
|
97
|
+
let event: Stripe.Event;
|
|
98
|
+
try {
|
|
99
|
+
event = stripe.webhooks.constructEvent(
|
|
100
|
+
rawBody,
|
|
101
|
+
sig,
|
|
102
|
+
process.env.STRIPE_WEBHOOK_SECRET!
|
|
103
|
+
);
|
|
104
|
+
} catch (err) {
|
|
105
|
+
return Response.json({ error: "Signature verification failed" }, { status: 400 });
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
3. **Check idempotency before processing.**
|
|
110
|
+
|
|
111
|
+
```sql
|
|
112
|
+
INSERT INTO webhook_events (event_id, processed_at)
|
|
113
|
+
VALUES ($1, now())
|
|
114
|
+
ON CONFLICT (event_id) DO NOTHING
|
|
115
|
+
RETURNING event_id;
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
If the `RETURNING` clause returns no rows, the event was already processed — return 200 immediately without re-running side effects.
|
|
119
|
+
|
|
120
|
+
4. **Route the verified event** to `payment-provider-router`.
|
|
121
|
+
|
|
122
|
+
## Failure Mode Reference
|
|
123
|
+
|
|
124
|
+
| Failure | Symptom | Fix |
|
|
125
|
+
|---------|---------|-----|
|
|
126
|
+
| Body parsed before verification | 400 on every real Stripe event | Use `arrayBuffer()`, not `json()` or `text()` |
|
|
127
|
+
| Wrong webhook secret | 400 with "No signatures found matching the expected signature" | Verify `STRIPE_WEBHOOK_SECRET` matches the endpoint in the Stripe dashboard |
|
|
128
|
+
| Replay attack | 400 with "Timestamp too old" | Legitimate if tolerance is tight; check `t=` value in the `stripe-signature` header |
|
|
129
|
+
| Secret from wrong environment | Events verify in dev but fail in production | Use per-environment secrets; never share between environments |
|
|
130
|
+
|
|
131
|
+
## Do NOT Use When
|
|
132
|
+
|
|
133
|
+
| Use instead | When |
|
|
134
|
+
|---|---|
|
|
135
|
+
| `payment-provider-router` | You have a verified event and need to decide which handler processes it |
|
|
136
|
+
| `nextjs-server-action-validation` | You are validating user-submitted form data, not a Stripe webhook |
|
|
137
|
+
| (a generic HTTP signature skill) | You are verifying webhooks from a non-Stripe provider with a different signing scheme |
|
|
@@ -0,0 +1,301 @@
|
|
|
1
|
+
---
|
|
2
|
+
# yaml-language-server: $schema=https://skillgraph.dev/schemas/skill.v4.schema.json
|
|
3
|
+
#
|
|
4
|
+
# ============================================================================
|
|
5
|
+
# SCAFFOLD — this file is a skill template, not a production skill.
|
|
6
|
+
# ============================================================================
|
|
7
|
+
#
|
|
8
|
+
# Adopters COPY this file to `skills/<new-name>/SKILL.md` and then edit it to
|
|
9
|
+
# author a new skill. Every `# TEMPLATE NOTE:` YAML comment and every
|
|
10
|
+
# `> **TEMPLATE NOTE:**` body blockquote is authoring scaffolding that MUST be
|
|
11
|
+
# stripped from the derived copy before shipping.
|
|
12
|
+
#
|
|
13
|
+
# Field values here are deliberate authoring-time defaults, not aspirational
|
|
14
|
+
# targets. In particular `eval_artifacts: planned`, `eval_state: unverified`,
|
|
15
|
+
# and `routing_eval: absent` (see comment on the routing_eval line below)
|
|
16
|
+
# encode the correct starting state for a brand-new un-verified skill —
|
|
17
|
+
# flipping them to `present` on this scaffold would make every derived skill
|
|
18
|
+
# inherit a false attestation until the author noticed.
|
|
19
|
+
#
|
|
20
|
+
# Build automation treats this file specially: the sample manifest
|
|
21
|
+
# generator ingests it only under `--include-template`, and the library-wide
|
|
22
|
+
# harness counts it as the 9th "skill" only when the flag is set. It is NOT
|
|
23
|
+
# routable in day-to-day skill dispatch — `scope: reference` keeps it out of
|
|
24
|
+
# the normal routing pool.
|
|
25
|
+
# ============================================================================
|
|
26
|
+
schema_version: 4
|
|
27
|
+
name: skill-metadata-template
|
|
28
|
+
# TEMPLATE NOTE: Be pushy in your description — Claude tends to under-trigger
|
|
29
|
+
# skills, so descriptions should read as commands ("Use when X", "Activate
|
|
30
|
+
# this skill whenever Y") not as polite suggestions ("This skill provides Z").
|
|
31
|
+
# State both WHAT the skill does AND WHEN to use it, and include an explicit
|
|
32
|
+
# negative boundary ("Do NOT use for ..." with a pointer to the right
|
|
33
|
+
# alternative skill). The 3-test quality gate for descriptions is:
|
|
34
|
+
# (1) names a real domain object (file path, function name, route),
|
|
35
|
+
# (2) has an explicit "Do NOT use for X (use Y)" exclusion clause,
|
|
36
|
+
# (3) names a concrete trigger (code pattern, file path, command).
|
|
37
|
+
# Keep the description concise enough to route well, but do not treat runtime
|
|
38
|
+
# wording guidelines as protocol limits.
|
|
39
|
+
# for Anthropic's own guidance on pushy descriptions.
|
|
40
|
+
description: "Use when creating a new SKILL.md, adapting an existing skill to a different archetype, or teaching an author the canonical frontmatter and body structure. Covers schema-conformant frontmatter, archetype-aware body layout, semantic-layer discipline (description vs Coverage), teaching-layer mechanics (TEMPLATE NOTE blockquotes and YAML comments), and the authoring gate. Do NOT use when modifying an already-written skill (edit that skill directly) or when writing general technical documentation (use the documentation skill)."
|
|
41
|
+
version: 1.0.0
|
|
42
|
+
type: capability
|
|
43
|
+
category: knowledge
|
|
44
|
+
# TEMPLATE NOTE: domain is the OPTIONAL hierarchical domain path (slash-
|
|
45
|
+
# delimited, lowercase kebab-case segments). Use it only when the skill library
|
|
46
|
+
# is large enough that a tree structure helps readers find related skills.
|
|
47
|
+
# Remove this line entirely when the flat `category` above is sufficient.
|
|
48
|
+
domain: skill-system/authoring
|
|
49
|
+
scope: reference
|
|
50
|
+
owner: skill-graph-maintainer
|
|
51
|
+
freshness: "2026-04-17"
|
|
52
|
+
# TEMPLATE NOTE: drift_check is an object. `last_verified` is required.
|
|
53
|
+
# `truth_source_hashes` is optional — record it with `node scripts/skill-graph-drift.js
|
|
54
|
+
# --record --apply <skill-dir>`.
|
|
55
|
+
drift_check:
|
|
56
|
+
last_verified: "2026-04-17"
|
|
57
|
+
# TEMPLATE NOTE: eval_artifacts, eval_state, and routing_eval are the three
|
|
58
|
+
# orthogonal eval-health axes introduced in schema_version 2. Set eval_artifacts
|
|
59
|
+
# to `planned` only as a temporary state — move to `present` once the artifact
|
|
60
|
+
# ships. Set eval_state to `unverified` when no run has been recorded yet.
|
|
61
|
+
#
|
|
62
|
+
# routing_eval: `present` is LINT-ENFORCED since [Unreleased]. Setting `present`
|
|
63
|
+
# requires (1) populated `examples` + `anti_examples` below, AND (2) a passing
|
|
64
|
+
# run of `node scripts/skill-graph-routing-eval.js --skill <name>`. Lint check
|
|
65
|
+
# 12 surfaces each failing prompt. Default to `absent` when authoring; flip
|
|
66
|
+
# to `present` only after the harness agrees. See docs/field-reference.md §
|
|
67
|
+
# routing_eval for the full enforcement contract.
|
|
68
|
+
#
|
|
69
|
+
# SCAFFOLD NOTE — on this specific file (`examples/skill-metadata-template.md`),
|
|
70
|
+
# routing_eval MUST stay `absent` even though the harness happens to report
|
|
71
|
+
# every case passing. The scaffold's job is to model the correct authoring-
|
|
72
|
+
# time default for a brand-new un-verified skill. If this line were flipped
|
|
73
|
+
# to `present`, every skill copy-pasted from the scaffold would inherit a
|
|
74
|
+
# false attestation until the author noticed and downgraded. In your
|
|
75
|
+
# derived copy, leave this line `absent` at first commit; flip it to
|
|
76
|
+
# `present` only after `node scripts/skill-graph-routing-eval.js --skill
|
|
77
|
+
# <your-skill-name>` exits 0 on YOUR skill's own examples + anti_examples.
|
|
78
|
+
eval_artifacts: planned
|
|
79
|
+
eval_state: unverified
|
|
80
|
+
routing_eval: absent
|
|
81
|
+
# TEMPLATE NOTE: Optional. Populate eval_last_run only after the skill has a
|
|
82
|
+
# real eval receipt (scorecard, grader history, CI run). Leave it absent for a
|
|
83
|
+
# brand-new skill with eval_state: unverified.
|
|
84
|
+
# eval_last_run:
|
|
85
|
+
# at: "2026-05-12T09:30:00Z"
|
|
86
|
+
# status: pass
|
|
87
|
+
# runner: "node scripts/skill-audit.js --graded"
|
|
88
|
+
# receipt: "examples/audits/<skill>/scorecard.md"
|
|
89
|
+
# TEMPLATE NOTE: stability values are `experimental` / `stable` / `frozen` /
|
|
90
|
+
# `deprecated`. When you move a skill to `deprecated`, the schema's `allOf`
|
|
91
|
+
# rule REQUIRES you to also add `superseded_by: <replacement-skill-name>` —
|
|
92
|
+
# without it the skill fails validation. A deprecated + superseded skill looks
|
|
93
|
+
# like:
|
|
94
|
+
#
|
|
95
|
+
# stability: deprecated
|
|
96
|
+
# superseded_by: new-skill-name
|
|
97
|
+
#
|
|
98
|
+
# The replacement must be a real skill in the same library. Omit `superseded_by`
|
|
99
|
+
# for any stability other than `deprecated`. See `docs/field-reference.md §
|
|
100
|
+
# superseded_by` for the full rules and the schema's `allOf` enforcement.
|
|
101
|
+
stability: stable
|
|
102
|
+
license: MIT
|
|
103
|
+
# TEMPLATE NOTE: compatibility is an object. Prefer structured fields
|
|
104
|
+
# (`runtimes`, `node`) over free-text `notes`.
|
|
105
|
+
compatibility:
|
|
106
|
+
notes: "Markdown, YAML, JSON Schema"
|
|
107
|
+
allowed-tools: Read Grep
|
|
108
|
+
# TEMPLATE NOTE: keywords are the pushy activation surface for authoring tasks.
|
|
109
|
+
# Keep terms that a human would type when starting a new skill.
|
|
110
|
+
keywords:
|
|
111
|
+
- how to write a SKILL.md file
|
|
112
|
+
- SKILL.md frontmatter YAML
|
|
113
|
+
- Skill Metadata Protocol v4
|
|
114
|
+
- Skill Graph schema fields
|
|
115
|
+
- skill archetype capability vs workflow
|
|
116
|
+
- skill description routing contract
|
|
117
|
+
- drift_check eval_artifacts routing_eval
|
|
118
|
+
- new skill scaffold template
|
|
119
|
+
- SKILL.md authoring gate
|
|
120
|
+
# TEMPLATE NOTE: triggers is present because this skill is routable by explicit label.
|
|
121
|
+
# Remove this block if your skill activates only by keyword or path matching.
|
|
122
|
+
triggers:
|
|
123
|
+
- skill-metadata-template
|
|
124
|
+
# TEMPLATE NOTE: paths is present because this template is the entry point whenever
|
|
125
|
+
# examples/skill-metadata-template.md itself is touched. the protocol supports gitignore-style negation —
|
|
126
|
+
# e.g. `- "!skills/experimental/**"` excludes a subdirectory from an otherwise broad
|
|
127
|
+
# glob. Remove this block if your skill is purely conceptual and has no file surface.
|
|
128
|
+
#
|
|
129
|
+
# Previous versions of this block also listed `skills/**/SKILL.md` but that glob is
|
|
130
|
+
# owned by `graph-audit` (the audit tooling that verifies every SKILL.md against the
|
|
131
|
+
# schema). Two skills claiming the same glob produces router ambiguity — the scope
|
|
132
|
+
# tiebreaker (`codebase` > `reference`) picks graph-audit anyway, and reference-scope
|
|
133
|
+
# skills are looked-up rather than path-routed. Lesson: each path glob should map to
|
|
134
|
+
# ONE canonical skill; `scripts/skill-overlap.js` surfaces duplicates as warnings.
|
|
135
|
+
paths:
|
|
136
|
+
- examples/skill-metadata-template.md
|
|
137
|
+
# TEMPLATE NOTE: examples is new in v0.5.0. 2–5 realistic user prompts the skill
|
|
138
|
+
# SHOULD activate for. Improves retrieval recall over keywords alone. Write in
|
|
139
|
+
# the user's voice, not imperative abstract form. See docs/field-reference.md §
|
|
140
|
+
# examples for full guidance. Omit this block for purely label-routed skills.
|
|
141
|
+
examples:
|
|
142
|
+
- "I'm writing a new skill from scratch — where do I start?"
|
|
143
|
+
- "how do I pick between capability and workflow for my skill type?"
|
|
144
|
+
- "what's the difference between description and the ## Coverage section?"
|
|
145
|
+
# TEMPLATE NOTE: anti_examples names near-miss prompts that should route ELSEWHERE.
|
|
146
|
+
# Pair with relations.boundary to tell the router which skill owns the confusable
|
|
147
|
+
# territory. Leave this block absent until you have seen the router misfire —
|
|
148
|
+
# speculative anti_examples rarely match reality. See docs/field-reference.md §
|
|
149
|
+
# anti_examples.
|
|
150
|
+
anti_examples:
|
|
151
|
+
- "refactor this skill to be more concise" # → refactor, not authoring
|
|
152
|
+
- "my skill's routing isn't activating — why?" # → skill-router, not template
|
|
153
|
+
# TEMPLATE NOTE: workspace_tags replaces v3 project_tags. Omit it for ambient / cross-project
|
|
154
|
+
# skills (the common case). Add literal project handles or semantic tags when
|
|
155
|
+
# the skill is relevant to a subset of projects in a multi-project workspace.
|
|
156
|
+
# See docs/field-decision-guide.md § 4 for the full decision tree.
|
|
157
|
+
#
|
|
158
|
+
# Example — this template is useful across every skill-authoring project, but
|
|
159
|
+
# the semantic tag scopes it to the Skill Graph authoring workflow rather than
|
|
160
|
+
# arbitrary project docs. A workspace config at `.skill-graph/config.json` can
|
|
161
|
+
# map your literal project handles to tag sets that include `skill-authoring`,
|
|
162
|
+
# so one tag reaches many projects.
|
|
163
|
+
workspace_tags:
|
|
164
|
+
- skill-authoring
|
|
165
|
+
relations:
|
|
166
|
+
# TEMPLATE NOTE: boundary items may be bare skill names OR `{skill, reason}`
|
|
167
|
+
# objects (v3). Reasons are strongly recommended — they make the boundary
|
|
168
|
+
# self-documenting. Adjacency has been removed here because `documentation`
|
|
169
|
+
# is already declared as `verify_with` — adjacent ("often used together")
|
|
170
|
+
# would be redundant and asymmetric.
|
|
171
|
+
boundary:
|
|
172
|
+
- skill: refactor
|
|
173
|
+
reason: "refactor is behavior-preserving code modification, not skill authoring"
|
|
174
|
+
- skill: skill-router
|
|
175
|
+
reason: "skill-router dispatches between existing skills at request time; this template creates a NEW skill"
|
|
176
|
+
- skill: graph-audit
|
|
177
|
+
reason: "graph-audit verifies the authored metadata of an existing skill; this template is the authoring-time guide"
|
|
178
|
+
verify_with:
|
|
179
|
+
- documentation
|
|
180
|
+
# TEMPLATE NOTE: grounding is REQUIRED for grounded skills that make concrete
|
|
181
|
+
# repo claims. Remove this entire block if your skill has grounding_mode: universal
|
|
182
|
+
# and does not anchor to truth sources in the repo.
|
|
183
|
+
grounding:
|
|
184
|
+
domain_object: Skill authoring for the Skill Metadata Protocol frontmatter
|
|
185
|
+
grounding_mode: repo_specific
|
|
186
|
+
truth_sources:
|
|
187
|
+
- path: docs/skill-metadata-protocol.md
|
|
188
|
+
anchor: the-40-authored-fields-grouped-by-purpose
|
|
189
|
+
note: "Protocol anatomy and field requiredness"
|
|
190
|
+
- path: schemas/skill.schema.json
|
|
191
|
+
line_range:
|
|
192
|
+
start: 480
|
|
193
|
+
end: 590
|
|
194
|
+
note: "Grounding schema shape"
|
|
195
|
+
- path: SKILL_AUDIT_CHECKLIST.md
|
|
196
|
+
anchor: canonical-checklist
|
|
197
|
+
note: "Audit checklist this template supports"
|
|
198
|
+
failure_modes:
|
|
199
|
+
- placeholder_sludge
|
|
200
|
+
- cargo_cult_meta_sections
|
|
201
|
+
- description_coverage_collapse
|
|
202
|
+
- authoring_gate_skipped
|
|
203
|
+
evidence_priority: repo_code_first
|
|
204
|
+
# TEMPLATE NOTE: portability declares which external agent runtimes this skill is
|
|
205
|
+
# known to work on. `readiness` is the operational rating: `declared` (claim only),
|
|
206
|
+
# `scripted` (export tooling exists), or `verified` (proven with a receipt). `targets`
|
|
207
|
+
# is the list of destination runtimes. Today the supported portable target is `skill-md`
|
|
208
|
+
# (see `schemas/skill.schema.json`). Other runtimes (cursor, windsurf, copilot, agents-md)
|
|
209
|
+
# were removed from the enum in 0.3.0 pending working transforms — re-add via RFC if
|
|
210
|
+
# adoption pressure appears. Remove this block if the skill is internal-only.
|
|
211
|
+
portability:
|
|
212
|
+
readiness: scripted
|
|
213
|
+
targets:
|
|
214
|
+
- skill-md
|
|
215
|
+
# TEMPLATE NOTE: lifecycle declares maintenance policy for the drift sentinel.
|
|
216
|
+
# `stale_after_days` flags the skill as STALE when more than N days have passed
|
|
217
|
+
# since `drift_check.last_verified`. Integration skills (third-party APIs) want
|
|
218
|
+
# shorter values; pure-concept skills want longer. Omit if staleness is not
|
|
219
|
+
# meaningful for your skill.
|
|
220
|
+
lifecycle:
|
|
221
|
+
stale_after_days: 180
|
|
222
|
+
review_cadence: quarterly
|
|
223
|
+
# TEMPLATE NOTE: runtime_telemetry is optional. It points at a JSONL feed of
|
|
224
|
+
# real-world success/failure receipts so consumers can corroborate or override
|
|
225
|
+
# `eval_state`. Omit the entire block when no feedback pipeline exists — the
|
|
226
|
+
# skill is still graded on authored `eval_state` and `eval_artifacts`.
|
|
227
|
+
# Each run receipt should carry at minimum `{ timestamp, skill, outcome }`.
|
|
228
|
+
# `metrics.sample_size` and `metrics.success_rate` are the aggregate summary;
|
|
229
|
+
# consumers may compute their own from the raw feed.
|
|
230
|
+
runtime_telemetry:
|
|
231
|
+
feedback_source: .skill-graph/telemetry/skill-metadata-template.jsonl
|
|
232
|
+
last_updated: "2026-04-17"
|
|
233
|
+
metrics:
|
|
234
|
+
sample_size: 0
|
|
235
|
+
success_rate: 0
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
# Skill Template — Scaffold
|
|
239
|
+
|
|
240
|
+
> **SCAFFOLD — NOT A PRODUCTION SKILL.** This file is the starting point authors copy when creating a new skill. It lives at `examples/skill-metadata-template.md` deliberately; production skills live at `skills/<name>/SKILL.md`. The authoring flow is: copy → rename → adapt → strip teaching annotations → verify → commit. Until you have completed those steps, the file you are editing is a *scaffold*, not a skill.
|
|
241
|
+
|
|
242
|
+
> **TEMPLATE NOTE — HOW TO READ THIS FILE:** This file is a real, valid, schema-conformant Skill Metadata Protocol skill whose *subject* is skill authoring itself. Read it as a finished specimen of the contract, then adapt it by (1) renaming the identity, (2) rewriting `description`, `## Coverage`, `## Philosophy`, and `## Key Files` for your subject, (3) rewriting `## Verification` to be your skill's self-check, (4) removing any section or field that does not apply to your archetype, and (5) stripping the `> **TEMPLATE NOTE:**` blockquotes and `# TEMPLATE NOTE:` YAML comments — they are authoring scaffolding, never skill content. Never ship placeholder sludge (`your-skill-name`, `path/to/file`, `todo`). If a section does not apply, remove it — do not keep it and fill it with fake content.
|
|
243
|
+
|
|
244
|
+
> **TEMPLATE NOTE — CONDITIONAL FIELDS:** `extends` is valid only when `type: overlay`. `routing_bundles` only applies when routing-group ownership is part of the skill contract. `triggers` and `paths` are shown because this template is both label-routable and file-activated; most skills need only one. `grounding` is REQUIRED for `scope: codebase` skills; remove the block entirely for `scope: portable` or `scope: reference`. `workspace_tags` is optional — omit for ambient / cross-project skills. `lifecycle` is optional — omit when staleness is not meaningful. `runtime_telemetry` is optional — omit when no feedback pipeline exists. Generated manifest health fields belong in `skills.manifest.json`, not in the authored `SKILL.md`.
|
|
245
|
+
|
|
246
|
+
## Coverage
|
|
247
|
+
|
|
248
|
+
- Frontmatter identity: `name`, `description`, `version`, `type`, `category`, `scope`, `owner`, and the governance fields required by every Skill Metadata Protocol skill
|
|
249
|
+
- Semantic layer discipline: how `description:` (routing contract, ≤ 3 sentences) differs from `## Coverage` (scope map, bulleted topic list) and why each must stay in its own layer
|
|
250
|
+
- Teaching-layer delivery: how to use `> **TEMPLATE NOTE:**` blockquotes and `# TEMPLATE NOTE:` YAML comments to teach authors without cargo-culting meta sections into every new skill
|
|
251
|
+
- Archetype-driven body structure: which `## H2` sections each of the four archetypes (`capability`, `workflow`, `router`, `overlay`) must contain
|
|
252
|
+
- Grounding via `grounding`: when a skill should declare truth sources and failure modes, and when it should stay `grounding_mode: universal`
|
|
253
|
+
- drift evidence: when to record `drift_check.truth_source_hashes` and how the drift sentinel consumes them
|
|
254
|
+
- v4 workspace tagging: when to add `workspace_tags`, when to leave a skill ambient, and how workspace semantic-tag mapping composes
|
|
255
|
+
- Adapter workflow: how to strip a template down, how to detect and remove cargo-culted meta, and how to verify a new skill against `schemas/skill.schema.json` before committing
|
|
256
|
+
|
|
257
|
+
## Philosophy
|
|
258
|
+
|
|
259
|
+
A template teaches by example, not by placeholder. A concrete, internally consistent specimen of a finished skill is a more reliable authoring reference than any amount of abstract scaffolding. The teaching layer — meta-commentary about how to read and adapt the template — must live in structurally distinct slots that disappear when the author tightens a new skill, never in the `## H2` section slots that AI agents copy verbatim when adapting the file.
|
|
260
|
+
|
|
261
|
+
## Key Files
|
|
262
|
+
|
|
263
|
+
| File | Purpose |
|
|
264
|
+
|---|---|
|
|
265
|
+
| `docs/skill-metadata-protocol.md` | Authoritative field semantics: required vs optional, conditional requiredness, relationship to the plain `SKILL.md` format, archetype section map |
|
|
266
|
+
| `schemas/skill.schema.json` | Enforceable JSON Schema for the frontmatter protocol |
|
|
267
|
+
| `SKILL_AUDIT_CHECKLIST.md` | The audit checklist every new skill should pass before commit |
|
|
268
|
+
|
|
269
|
+
## Verification
|
|
270
|
+
|
|
271
|
+
Use this checklist as the authoring gate before committing a skill adapted from this template. Every item must pass.
|
|
272
|
+
|
|
273
|
+
- [ ] Every retained field has a real reason to exist in the new skill
|
|
274
|
+
- [ ] Every removed field was removed because of archetype or grounding mismatch, not laziness
|
|
275
|
+
- [ ] Body sections match the skill's declared archetype per `docs/skill-metadata-protocol.md § Archetype section map`
|
|
276
|
+
- [ ] `description:` is ≤ 3 sentences, contains pushy trigger phrases, and names an explicit negative boundary
|
|
277
|
+
- [ ] `## Coverage` is a scope map of distinct topics, not a one-line restate of the description
|
|
278
|
+
- [ ] `drift_check` is an object with `last_verified`; `truth_source_hashes` has been recorded when truth sources exist
|
|
279
|
+
- [ ] `compatibility` is an object (not a free-text string) when present
|
|
280
|
+
- [ ] `eval_artifacts` matches actual artifact presence (if `present`, an eval file exists under `examples/evals/` or alongside the skill); `eval_state` reflects whether a real passing run has been recorded; `routing_eval` reflects whether trigger/routing coverage is explicitly checked
|
|
281
|
+
- [ ] All `relations` entries point to skills that exist in the target repo; `boundary` entries with unclear rationale use the `{skill, reason}` form
|
|
282
|
+
- [ ] `workspace_tags` is present when the skill is project-specific OR absent when the skill is ambient — not left at a stale value
|
|
283
|
+
- [ ] No placeholder sludge (`your-skill-name`, `path/to/file`, `todo`) remains
|
|
284
|
+
- [ ] No `> **TEMPLATE NOTE:**` blockquotes or `# TEMPLATE NOTE:` YAML comments remain in the adapted skill
|
|
285
|
+
- [ ] The adapted skill validates against `schemas/skill.schema.json` as a real skill
|
|
286
|
+
|
|
287
|
+
## Do NOT Use When
|
|
288
|
+
|
|
289
|
+
| Instead of this template | Use | Why |
|
|
290
|
+
|---|---|---|
|
|
291
|
+
| `skill-metadata-template` | the target skill directly | Editing an existing skill is refactor-in-place, not authoring from a template |
|
|
292
|
+
| `skill-metadata-template` | `documentation` | General technical writing is not skill authoring; use `documentation` for docs, guides, and specs |
|
|
293
|
+
| `skill-metadata-template` | `docs/skill-metadata-protocol.md` | When you need the full field reference, read the contract document directly |
|
|
294
|
+
|
|
295
|
+
## References
|
|
296
|
+
|
|
297
|
+
- `docs/skill-metadata-protocol.md § Relationship to the SKILL.md format` - how Skill Metadata Protocol extends the base format
|
|
298
|
+
- `docs/skill-metadata-protocol.md § Example Template Rule` — the no-placeholder-sludge rule this template enforces
|
|
299
|
+
- `docs/skill-metadata-protocol.md § Archetype section map` — required H2 sections per archetype
|
|
300
|
+
- `docs/manifest-field-mapping.md § Migration Note — v2 → v3` — the field-name cleanup the v4 bump introduced
|
|
301
|
+
- `SKILL_AUDIT_CHECKLIST.md` — the checklist this template's Verification section is derived from
|