@ketecode/loom 0.0.0-stage → 0.1.0

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 (656) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +516 -2
  3. package/agents/accessibility-reviewer/AGENT.md +70 -0
  4. package/agents/accessibility-reviewer/evals/triggers.json +15 -0
  5. package/agents/agent-evaluator/AGENT.md +74 -0
  6. package/agents/agent-evaluator/evals/triggers.json +15 -0
  7. package/agents/architect/AGENT.md +82 -0
  8. package/agents/architect/evals/triggers.json +17 -0
  9. package/agents/billing-reviewer/AGENT.md +68 -0
  10. package/agents/billing-reviewer/evals/triggers.json +16 -0
  11. package/agents/code-reviewer/AGENT.md +51 -0
  12. package/agents/code-reviewer/evals/triggers.json +14 -0
  13. package/agents/code-simplifier/AGENT.md +74 -0
  14. package/agents/code-simplifier/evals/triggers.json +15 -0
  15. package/agents/cpp-build-resolver/AGENT.md +73 -0
  16. package/agents/cpp-build-resolver/evals/triggers.json +16 -0
  17. package/agents/cpp-reviewer/AGENT.md +59 -0
  18. package/agents/cpp-reviewer/evals/triggers.json +16 -0
  19. package/agents/csharp-build-resolver/AGENT.md +84 -0
  20. package/agents/csharp-build-resolver/evals/triggers.json +17 -0
  21. package/agents/csharp-reviewer/AGENT.md +88 -0
  22. package/agents/csharp-reviewer/evals/triggers.json +17 -0
  23. package/agents/dart-build-resolver/AGENT.md +80 -0
  24. package/agents/dart-build-resolver/evals/triggers.json +17 -0
  25. package/agents/dart-reviewer/AGENT.md +66 -0
  26. package/agents/dart-reviewer/evals/triggers.json +17 -0
  27. package/agents/database-reviewer/AGENT.md +72 -0
  28. package/agents/database-reviewer/evals/triggers.json +16 -0
  29. package/agents/django-reviewer/AGENT.md +61 -0
  30. package/agents/django-reviewer/evals/triggers.json +15 -0
  31. package/agents/doc-updater/AGENT.md +92 -0
  32. package/agents/doc-updater/evals/triggers.json +14 -0
  33. package/agents/e2e-runner/AGENT.md +88 -0
  34. package/agents/e2e-runner/evals/triggers.json +16 -0
  35. package/agents/fastapi-reviewer/AGENT.md +63 -0
  36. package/agents/fastapi-reviewer/evals/triggers.json +15 -0
  37. package/agents/flutter-reviewer/AGENT.md +70 -0
  38. package/agents/flutter-reviewer/evals/triggers.json +15 -0
  39. package/agents/fsharp-build-resolver/AGENT.md +81 -0
  40. package/agents/fsharp-build-resolver/evals/triggers.json +15 -0
  41. package/agents/fsharp-reviewer/AGENT.md +77 -0
  42. package/agents/fsharp-reviewer/evals/triggers.json +15 -0
  43. package/agents/go-build-resolver/AGENT.md +85 -0
  44. package/agents/go-build-resolver/evals/triggers.json +16 -0
  45. package/agents/go-reviewer/AGENT.md +66 -0
  46. package/agents/go-reviewer/evals/triggers.json +16 -0
  47. package/agents/healthcare-reviewer/AGENT.md +65 -0
  48. package/agents/healthcare-reviewer/evals/triggers.json +16 -0
  49. package/agents/i18n-reviewer/AGENT.md +64 -0
  50. package/agents/i18n-reviewer/evals/triggers.json +16 -0
  51. package/agents/infra-reviewer/AGENT.md +93 -0
  52. package/agents/infra-reviewer/evals/triggers.json +15 -0
  53. package/agents/java-build-resolver/AGENT.md +82 -0
  54. package/agents/java-build-resolver/evals/triggers.json +16 -0
  55. package/agents/java-reviewer/AGENT.md +64 -0
  56. package/agents/java-reviewer/evals/triggers.json +16 -0
  57. package/agents/kotlin-build-resolver/AGENT.md +89 -0
  58. package/agents/kotlin-build-resolver/evals/triggers.json +16 -0
  59. package/agents/kotlin-reviewer/AGENT.md +75 -0
  60. package/agents/kotlin-reviewer/evals/triggers.json +16 -0
  61. package/agents/mle-reviewer/AGENT.md +68 -0
  62. package/agents/mle-reviewer/evals/triggers.json +16 -0
  63. package/agents/network-config-reviewer/AGENT.md +68 -0
  64. package/agents/network-config-reviewer/evals/triggers.json +17 -0
  65. package/agents/payments-reviewer/AGENT.md +64 -0
  66. package/agents/payments-reviewer/evals/triggers.json +16 -0
  67. package/agents/performance-optimizer/AGENT.md +86 -0
  68. package/agents/performance-optimizer/evals/triggers.json +16 -0
  69. package/agents/perl-build-resolver/AGENT.md +84 -0
  70. package/agents/perl-build-resolver/evals/triggers.json +15 -0
  71. package/agents/perl-reviewer/AGENT.md +77 -0
  72. package/agents/perl-reviewer/evals/triggers.json +15 -0
  73. package/agents/php-build-resolver/AGENT.md +88 -0
  74. package/agents/php-build-resolver/evals/triggers.json +16 -0
  75. package/agents/php-reviewer/AGENT.md +61 -0
  76. package/agents/php-reviewer/evals/triggers.json +15 -0
  77. package/agents/planner/AGENT.md +75 -0
  78. package/agents/planner/evals/triggers.json +17 -0
  79. package/agents/pr-test-analyzer/AGENT.md +82 -0
  80. package/agents/pr-test-analyzer/evals/triggers.json +16 -0
  81. package/agents/python-build-resolver/AGENT.md +87 -0
  82. package/agents/python-build-resolver/evals/triggers.json +16 -0
  83. package/agents/python-reviewer/AGENT.md +63 -0
  84. package/agents/python-reviewer/evals/triggers.json +15 -0
  85. package/agents/rag-reviewer/AGENT.md +71 -0
  86. package/agents/rag-reviewer/evals/triggers.json +16 -0
  87. package/agents/react-reviewer/AGENT.md +70 -0
  88. package/agents/react-reviewer/evals/triggers.json +16 -0
  89. package/agents/refactor-cleaner/AGENT.md +82 -0
  90. package/agents/refactor-cleaner/evals/triggers.json +16 -0
  91. package/agents/ruby-build-resolver/AGENT.md +93 -0
  92. package/agents/ruby-build-resolver/evals/triggers.json +16 -0
  93. package/agents/ruby-reviewer/AGENT.md +62 -0
  94. package/agents/ruby-reviewer/evals/triggers.json +16 -0
  95. package/agents/rust-build-resolver/AGENT.md +98 -0
  96. package/agents/rust-build-resolver/evals/triggers.json +16 -0
  97. package/agents/rust-reviewer/AGENT.md +78 -0
  98. package/agents/rust-reviewer/evals/triggers.json +15 -0
  99. package/agents/security-reviewer/AGENT.md +84 -0
  100. package/agents/security-reviewer/evals/triggers.json +16 -0
  101. package/agents/silent-failure-hunter/AGENT.md +66 -0
  102. package/agents/silent-failure-hunter/evals/triggers.json +16 -0
  103. package/agents/solidity-reviewer/AGENT.md +70 -0
  104. package/agents/solidity-reviewer/evals/triggers.json +16 -0
  105. package/agents/swift-build-resolver/AGENT.md +85 -0
  106. package/agents/swift-build-resolver/evals/triggers.json +15 -0
  107. package/agents/swift-reviewer/AGENT.md +75 -0
  108. package/agents/swift-reviewer/evals/triggers.json +15 -0
  109. package/agents/typescript-build-resolver/AGENT.md +76 -0
  110. package/agents/typescript-build-resolver/evals/triggers.json +15 -0
  111. package/agents/typescript-reviewer/AGENT.md +76 -0
  112. package/agents/typescript-reviewer/evals/triggers.json +15 -0
  113. package/agents/vue-reviewer/AGENT.md +75 -0
  114. package/agents/vue-reviewer/evals/triggers.json +15 -0
  115. package/bin/kete-loom.js +683 -0
  116. package/commands/aside.md +19 -0
  117. package/commands/build-fix.md +26 -0
  118. package/commands/campaign.md +19 -0
  119. package/commands/changelog.md +36 -0
  120. package/commands/checkpoint.md +26 -0
  121. package/commands/codemap.md +25 -0
  122. package/commands/commit.md +26 -0
  123. package/commands/deps-audit.md +32 -0
  124. package/commands/epic-decompose.md +21 -0
  125. package/commands/explain.md +37 -0
  126. package/commands/feature-dev.md +22 -0
  127. package/commands/hookify.md +23 -0
  128. package/commands/i18n-check.md +39 -0
  129. package/commands/issue-sync.md +22 -0
  130. package/commands/jira.md +19 -0
  131. package/commands/learn.md +23 -0
  132. package/commands/loom.md +21 -0
  133. package/commands/loop.md +20 -0
  134. package/commands/model-route.md +27 -0
  135. package/commands/onboard.md +35 -0
  136. package/commands/orchestrate.md +21 -0
  137. package/commands/plan-feature.md +36 -0
  138. package/commands/postmortem.md +42 -0
  139. package/commands/pr-describe.md +39 -0
  140. package/commands/pr.md +22 -0
  141. package/commands/prd.md +41 -0
  142. package/commands/project-init.md +21 -0
  143. package/commands/refactor-clean.md +24 -0
  144. package/commands/resume-session.md +22 -0
  145. package/commands/review.md +35 -0
  146. package/commands/save-session.md +37 -0
  147. package/commands/security-scan.md +32 -0
  148. package/commands/sessions.md +21 -0
  149. package/commands/skill-create.md +21 -0
  150. package/commands/tdd.md +36 -0
  151. package/commands/test-coverage.md +24 -0
  152. package/commands/threat-model.md +36 -0
  153. package/commands/update-docs.md +25 -0
  154. package/commands/verify.md +21 -0
  155. package/hooks/block-dangerous-commands/HOOK.md +30 -0
  156. package/hooks/block-dangerous-commands/cases.json +50 -0
  157. package/hooks/block-dangerous-commands/hook.js +75 -0
  158. package/hooks/block-no-verify/HOOK.md +25 -0
  159. package/hooks/block-no-verify/cases.json +30 -0
  160. package/hooks/block-no-verify/hook.js +43 -0
  161. package/hooks/format-on-edit/HOOK.md +24 -0
  162. package/hooks/format-on-edit/hook.js +89 -0
  163. package/hooks/guard-secrets/HOOK.md +19 -0
  164. package/hooks/guard-secrets/cases.json +110 -0
  165. package/hooks/guard-secrets/hook.js +44 -0
  166. package/hooks/load-session-context/HOOK.md +20 -0
  167. package/hooks/load-session-context/hook.js +56 -0
  168. package/hooks/protect-files/HOOK.md +24 -0
  169. package/hooks/protect-files/cases.json +27 -0
  170. package/hooks/protect-files/hook.js +39 -0
  171. package/hooks/run.js +132 -0
  172. package/mcp/atlassian.json +11 -0
  173. package/mcp/chrome-devtools.json +18 -0
  174. package/mcp/cloudflare.json +11 -0
  175. package/mcp/context7.json +11 -0
  176. package/mcp/fetch.json +17 -0
  177. package/mcp/figma.json +11 -0
  178. package/mcp/git.json +17 -0
  179. package/mcp/github.json +11 -0
  180. package/mcp/linear.json +11 -0
  181. package/mcp/memory.json +18 -0
  182. package/mcp/notion.json +11 -0
  183. package/mcp/playwright.json +18 -0
  184. package/mcp/sentry.json +11 -0
  185. package/mcp/stripe.json +11 -0
  186. package/mcp/supabase.json +11 -0
  187. package/mcp/time.json +17 -0
  188. package/package.json +59 -4
  189. package/profiles.json +165 -0
  190. package/rules/common.md +21 -0
  191. package/rules/cpp.md +29 -0
  192. package/rules/csharp.md +25 -0
  193. package/rules/dart.md +29 -0
  194. package/rules/fsharp.md +28 -0
  195. package/rules/git.md +26 -0
  196. package/rules/go.md +29 -0
  197. package/rules/java.md +29 -0
  198. package/rules/kotlin.md +27 -0
  199. package/rules/perl.md +26 -0
  200. package/rules/php.md +28 -0
  201. package/rules/python.md +30 -0
  202. package/rules/ruby.md +27 -0
  203. package/rules/rust.md +26 -0
  204. package/rules/security.md +29 -0
  205. package/rules/swift.md +28 -0
  206. package/rules/testing.md +25 -0
  207. package/rules/typescript.md +29 -0
  208. package/schemas/skill-frontmatter.schema.json +52 -0
  209. package/scripts/lib/audit.js +96 -0
  210. package/scripts/lib/frontmatter.js +65 -0
  211. package/scripts/lib/hooks-install.js +292 -0
  212. package/scripts/lib/i18n.js +51 -0
  213. package/scripts/lib/inventory.js +85 -0
  214. package/scripts/lib/lint.js +158 -0
  215. package/scripts/lib/mcp-install.js +284 -0
  216. package/scripts/lib/profiles.js +128 -0
  217. package/scripts/lib/render.js +86 -0
  218. package/scripts/lib/rules-install.js +118 -0
  219. package/scripts/lib/skills.js +86 -0
  220. package/scripts/lib/targets.js +113 -0
  221. package/skills/accounting-api-integration/SKILL.md +81 -0
  222. package/skills/accounting-api-integration/evals/triggers.json +17 -0
  223. package/skills/accounting-api-integration/references/quickbooks.md +48 -0
  224. package/skills/accounting-api-integration/references/xero.md +45 -0
  225. package/skills/agent-harness-design/SKILL.md +125 -0
  226. package/skills/agent-harness-design/evals/triggers.json +21 -0
  227. package/skills/ai-media-generation/SKILL.md +89 -0
  228. package/skills/ai-media-generation/evals/triggers.json +16 -0
  229. package/skills/ai-media-generation/references/job-pipeline.md +76 -0
  230. package/skills/angular-patterns/SKILL.md +122 -0
  231. package/skills/angular-patterns/evals/triggers.json +16 -0
  232. package/skills/api-design/SKILL.md +96 -0
  233. package/skills/api-design/evals/triggers.json +18 -0
  234. package/skills/api-design/references/conventions.md +133 -0
  235. package/skills/architecture-decision-records/SKILL.md +98 -0
  236. package/skills/architecture-decision-records/evals/triggers.json +17 -0
  237. package/skills/article-writing/SKILL.md +108 -0
  238. package/skills/article-writing/evals/triggers.json +16 -0
  239. package/skills/aspnet-core-patterns/SKILL.md +149 -0
  240. package/skills/aspnet-core-patterns/evals/triggers.json +16 -0
  241. package/skills/auth-patterns/SKILL.md +104 -0
  242. package/skills/auth-patterns/evals/triggers.json +17 -0
  243. package/skills/auth-patterns/references/oauth-oidc.md +64 -0
  244. package/skills/autonomous-loops/SKILL.md +99 -0
  245. package/skills/autonomous-loops/evals/triggers.json +14 -0
  246. package/skills/aws-patterns/SKILL.md +91 -0
  247. package/skills/aws-patterns/evals/triggers.json +16 -0
  248. package/skills/azure-patterns/SKILL.md +86 -0
  249. package/skills/azure-patterns/evals/triggers.json +16 -0
  250. package/skills/benchmark-methodology/SKILL.md +88 -0
  251. package/skills/benchmark-methodology/evals/triggers.json +16 -0
  252. package/skills/benchmark-methodology/references/language-harnesses.md +130 -0
  253. package/skills/bgp-diagnostics/SKILL.md +84 -0
  254. package/skills/bgp-diagnostics/evals/triggers.json +18 -0
  255. package/skills/bgp-diagnostics/references/bgp-reference.md +81 -0
  256. package/skills/bioinformatics-workflows/SKILL.md +108 -0
  257. package/skills/bioinformatics-workflows/evals/triggers.json +16 -0
  258. package/skills/bioinformatics-workflows/references/commands.md +71 -0
  259. package/skills/bioinformatics-workflows/references/formats.md +24 -0
  260. package/skills/bioinformatics-workflows/references/workflow-managers.md +107 -0
  261. package/skills/brand-voice/SKILL.md +112 -0
  262. package/skills/brand-voice/evals/triggers.json +16 -0
  263. package/skills/browser-qa/SKILL.md +99 -0
  264. package/skills/browser-qa/evals/triggers.json +16 -0
  265. package/skills/bun-runtime/SKILL.md +93 -0
  266. package/skills/bun-runtime/evals/triggers.json +16 -0
  267. package/skills/cisco-ios-config/SKILL.md +101 -0
  268. package/skills/cisco-ios-config/evals/triggers.json +18 -0
  269. package/skills/cisco-ios-config/references/verification.md +63 -0
  270. package/skills/clickhouse-patterns/SKILL.md +101 -0
  271. package/skills/clickhouse-patterns/evals/triggers.json +18 -0
  272. package/skills/clickhouse-patterns/references/engines-and-views.md +138 -0
  273. package/skills/clinical-decision-support/SKILL.md +90 -0
  274. package/skills/clinical-decision-support/evals/triggers.json +16 -0
  275. package/skills/clinical-decision-support/references/cds-hooks.md +76 -0
  276. package/skills/clinical-decision-support/references/regulatory-boundaries.md +37 -0
  277. package/skills/code-tour/SKILL.md +97 -0
  278. package/skills/code-tour/evals/triggers.json +14 -0
  279. package/skills/codebase-onboarding/SKILL.md +112 -0
  280. package/skills/codebase-onboarding/evals/triggers.json +14 -0
  281. package/skills/cold-outreach-sequences/SKILL.md +90 -0
  282. package/skills/cold-outreach-sequences/evals/triggers.json +16 -0
  283. package/skills/content-repurposing/SKILL.md +82 -0
  284. package/skills/content-repurposing/evals/triggers.json +16 -0
  285. package/skills/context-budget/SKILL.md +84 -0
  286. package/skills/context-budget/evals/triggers.json +14 -0
  287. package/skills/conventional-commits/SKILL.md +144 -0
  288. package/skills/conventional-commits/evals/triggers.json +16 -0
  289. package/skills/cpp-patterns/SKILL.md +129 -0
  290. package/skills/cpp-patterns/evals/triggers.json +16 -0
  291. package/skills/cpp-patterns/references/cmake-and-tooling.md +88 -0
  292. package/skills/cpp-patterns/references/undefined-behaviour.md +75 -0
  293. package/skills/cpp-testing/SKILL.md +131 -0
  294. package/skills/cpp-testing/evals/triggers.json +16 -0
  295. package/skills/csharp-patterns/SKILL.md +110 -0
  296. package/skills/csharp-patterns/evals/triggers.json +17 -0
  297. package/skills/csharp-patterns/references/analyzers.md +59 -0
  298. package/skills/csharp-testing/SKILL.md +85 -0
  299. package/skills/csharp-testing/evals/triggers.json +17 -0
  300. package/skills/csharp-testing/references/integration-tests.md +77 -0
  301. package/skills/css-architecture/SKILL.md +143 -0
  302. package/skills/css-architecture/evals/triggers.json +16 -0
  303. package/skills/customs-trade-compliance/SKILL.md +95 -0
  304. package/skills/customs-trade-compliance/evals/triggers.json +16 -0
  305. package/skills/customs-trade-compliance/references/incoterms-2020.md +42 -0
  306. package/skills/dart-patterns/SKILL.md +157 -0
  307. package/skills/dart-patterns/evals/triggers.json +18 -0
  308. package/skills/dart-testing/SKILL.md +164 -0
  309. package/skills/dart-testing/evals/triggers.json +18 -0
  310. package/skills/data-analysis-notebooks/SKILL.md +113 -0
  311. package/skills/data-analysis-notebooks/evals/triggers.json +16 -0
  312. package/skills/data-analysis-notebooks/references/dataframe-pitfalls.md +49 -0
  313. package/skills/data-analysis-notebooks/references/statistics-pitfalls.md +24 -0
  314. package/skills/data-pipelines/SKILL.md +90 -0
  315. package/skills/data-pipelines/evals/triggers.json +16 -0
  316. package/skills/data-pipelines/references/orchestrators.md +64 -0
  317. package/skills/database-migrations/SKILL.md +102 -0
  318. package/skills/database-migrations/evals/triggers.json +16 -0
  319. package/skills/database-migrations/references/recipes.md +98 -0
  320. package/skills/database-migrations/references/tools.md +21 -0
  321. package/skills/dbt-patterns/SKILL.md +96 -0
  322. package/skills/dbt-patterns/evals/triggers.json +16 -0
  323. package/skills/dbt-patterns/references/yaml-examples.md +114 -0
  324. package/skills/deep-research/SKILL.md +107 -0
  325. package/skills/deep-research/evals/triggers.json +14 -0
  326. package/skills/dependency-audit/SKILL.md +103 -0
  327. package/skills/dependency-audit/evals/triggers.json +16 -0
  328. package/skills/dependency-audit/references/tools.md +124 -0
  329. package/skills/deployment-strategies/SKILL.md +108 -0
  330. package/skills/deployment-strategies/evals/triggers.json +16 -0
  331. package/skills/django-patterns/SKILL.md +123 -0
  332. package/skills/django-patterns/evals/triggers.json +16 -0
  333. package/skills/docker-patterns/SKILL.md +132 -0
  334. package/skills/docker-patterns/evals/triggers.json +16 -0
  335. package/skills/docker-patterns/references/dockerfiles.md +105 -0
  336. package/skills/e2e-testing-playwright/SKILL.md +94 -0
  337. package/skills/e2e-testing-playwright/evals/triggers.json +16 -0
  338. package/skills/e2e-testing-playwright/references/config-and-ci.md +129 -0
  339. package/skills/ef-core-patterns/SKILL.md +117 -0
  340. package/skills/ef-core-patterns/evals/triggers.json +16 -0
  341. package/skills/email-deliverability/SKILL.md +99 -0
  342. package/skills/email-deliverability/evals/triggers.json +17 -0
  343. package/skills/email-deliverability/references/dns-records.md +85 -0
  344. package/skills/error-handling-patterns/SKILL.md +112 -0
  345. package/skills/error-handling-patterns/evals/triggers.json +18 -0
  346. package/skills/error-handling-patterns/references/language-idioms.md +49 -0
  347. package/skills/estimation-and-scoping/SKILL.md +97 -0
  348. package/skills/estimation-and-scoping/evals/triggers.json +14 -0
  349. package/skills/evm-dapp-integration/SKILL.md +73 -0
  350. package/skills/evm-dapp-integration/evals/triggers.json +16 -0
  351. package/skills/fastapi-patterns/SKILL.md +127 -0
  352. package/skills/fastapi-patterns/evals/triggers.json +16 -0
  353. package/skills/ffmpeg-media-processing/SKILL.md +94 -0
  354. package/skills/ffmpeg-media-processing/evals/triggers.json +16 -0
  355. package/skills/ffmpeg-media-processing/references/recipes.md +112 -0
  356. package/skills/fhir-integration/SKILL.md +81 -0
  357. package/skills/fhir-integration/evals/triggers.json +16 -0
  358. package/skills/fhir-integration/references/search-and-bundles.md +73 -0
  359. package/skills/fhir-integration/references/smart-on-fhir.md +50 -0
  360. package/skills/flask-patterns/SKILL.md +132 -0
  361. package/skills/flask-patterns/evals/triggers.json +16 -0
  362. package/skills/flutter-patterns/SKILL.md +99 -0
  363. package/skills/flutter-patterns/evals/triggers.json +16 -0
  364. package/skills/flutterwave-integration/SKILL.md +75 -0
  365. package/skills/flutterwave-integration/evals/triggers.json +16 -0
  366. package/skills/flutterwave-integration/references/api.md +73 -0
  367. package/skills/flutterwave-integration/references/webhooks.md +49 -0
  368. package/skills/fsharp-patterns/SKILL.md +133 -0
  369. package/skills/fsharp-patterns/evals/triggers.json +16 -0
  370. package/skills/fsharp-testing/SKILL.md +136 -0
  371. package/skills/fsharp-testing/evals/triggers.json +16 -0
  372. package/skills/gcp-patterns/SKILL.md +86 -0
  373. package/skills/gcp-patterns/evals/triggers.json +16 -0
  374. package/skills/git-workflow/SKILL.md +114 -0
  375. package/skills/git-workflow/evals/triggers.json +16 -0
  376. package/skills/github-actions-ci/SKILL.md +117 -0
  377. package/skills/github-actions-ci/evals/triggers.json +16 -0
  378. package/skills/github-api-automation/SKILL.md +101 -0
  379. package/skills/github-api-automation/evals/triggers.json +17 -0
  380. package/skills/go-patterns/SKILL.md +118 -0
  381. package/skills/go-patterns/evals/triggers.json +17 -0
  382. package/skills/go-patterns/references/concurrency.md +162 -0
  383. package/skills/go-testing/SKILL.md +154 -0
  384. package/skills/go-testing/evals/triggers.json +17 -0
  385. package/skills/hexagonal-architecture/SKILL.md +89 -0
  386. package/skills/hexagonal-architecture/evals/triggers.json +17 -0
  387. package/skills/hipaa-compliance/SKILL.md +91 -0
  388. package/skills/hipaa-compliance/evals/triggers.json +18 -0
  389. package/skills/hipaa-compliance/references/safeguards.md +68 -0
  390. package/skills/hl7v2-integration/SKILL.md +69 -0
  391. package/skills/hl7v2-integration/evals/triggers.json +16 -0
  392. package/skills/hl7v2-integration/references/messages-and-ack.md +78 -0
  393. package/skills/homelab-network-setup/SKILL.md +125 -0
  394. package/skills/homelab-network-setup/evals/triggers.json +18 -0
  395. package/skills/homelab-network-setup/references/firewall-and-dns.md +45 -0
  396. package/skills/homelab-network-setup/references/wireguard.md +72 -0
  397. package/skills/hubtel-integration/SKILL.md +77 -0
  398. package/skills/hubtel-integration/evals/triggers.json +16 -0
  399. package/skills/hubtel-integration/references/api.md +92 -0
  400. package/skills/i18n-localization/SKILL.md +114 -0
  401. package/skills/i18n-localization/evals/triggers.json +16 -0
  402. package/skills/i18n-localization/references/libraries.md +52 -0
  403. package/skills/incident-postmortem/SKILL.md +118 -0
  404. package/skills/incident-postmortem/evals/triggers.json +14 -0
  405. package/skills/inventory-demand-planning/SKILL.md +89 -0
  406. package/skills/inventory-demand-planning/evals/triggers.json +16 -0
  407. package/skills/inventory-demand-planning/references/formulas.md +62 -0
  408. package/skills/investor-materials/SKILL.md +127 -0
  409. package/skills/investor-materials/evals/triggers.json +16 -0
  410. package/skills/investor-materials/references/templates.md +74 -0
  411. package/skills/invoicing-and-tax/SKILL.md +84 -0
  412. package/skills/invoicing-and-tax/evals/triggers.json +17 -0
  413. package/skills/invoicing-and-tax/references/e-invoicing.md +24 -0
  414. package/skills/invoicing-and-tax/references/invoice-fields.md +38 -0
  415. package/skills/invoicing-and-tax/references/rounding.md +26 -0
  416. package/skills/java-patterns/SKILL.md +141 -0
  417. package/skills/java-patterns/evals/triggers.json +17 -0
  418. package/skills/java-testing/SKILL.md +142 -0
  419. package/skills/java-testing/evals/triggers.json +16 -0
  420. package/skills/jetpack-compose-patterns/SKILL.md +88 -0
  421. package/skills/jetpack-compose-patterns/evals/triggers.json +16 -0
  422. package/skills/jira-integration/SKILL.md +92 -0
  423. package/skills/jira-integration/evals/triggers.json +17 -0
  424. package/skills/jpa-hibernate/SKILL.md +92 -0
  425. package/skills/jpa-hibernate/evals/triggers.json +18 -0
  426. package/skills/jpa-hibernate/references/mapping.md +99 -0
  427. package/skills/kotlin-multiplatform/SKILL.md +97 -0
  428. package/skills/kotlin-multiplatform/evals/triggers.json +16 -0
  429. package/skills/kotlin-patterns/SKILL.md +128 -0
  430. package/skills/kotlin-patterns/evals/triggers.json +16 -0
  431. package/skills/kotlin-testing/SKILL.md +117 -0
  432. package/skills/kotlin-testing/evals/triggers.json +16 -0
  433. package/skills/ktor-patterns/SKILL.md +135 -0
  434. package/skills/ktor-patterns/evals/triggers.json +18 -0
  435. package/skills/kubernetes-patterns/SKILL.md +106 -0
  436. package/skills/kubernetes-patterns/evals/triggers.json +16 -0
  437. package/skills/kubernetes-patterns/references/manifests.md +115 -0
  438. package/skills/laravel-patterns/SKILL.md +136 -0
  439. package/skills/laravel-patterns/evals/triggers.json +16 -0
  440. package/skills/linear-integration/SKILL.md +98 -0
  441. package/skills/linear-integration/evals/triggers.json +17 -0
  442. package/skills/literature-review/SKILL.md +109 -0
  443. package/skills/literature-review/evals/triggers.json +16 -0
  444. package/skills/literature-review/references/appraisal.md +41 -0
  445. package/skills/literature-review/references/search-sources.md +39 -0
  446. package/skills/llm-app-patterns/SKILL.md +97 -0
  447. package/skills/llm-app-patterns/evals/triggers.json +17 -0
  448. package/skills/llm-evals/SKILL.md +98 -0
  449. package/skills/llm-evals/evals/triggers.json +16 -0
  450. package/skills/llm-evals/references/graders.md +66 -0
  451. package/skills/logistics-exception-management/SKILL.md +90 -0
  452. package/skills/logistics-exception-management/evals/triggers.json +16 -0
  453. package/skills/manim-animations/SKILL.md +106 -0
  454. package/skills/manim-animations/evals/triggers.json +16 -0
  455. package/skills/market-research/SKILL.md +117 -0
  456. package/skills/market-research/evals/triggers.json +16 -0
  457. package/skills/marketing-campaign/SKILL.md +111 -0
  458. package/skills/marketing-campaign/evals/triggers.json +16 -0
  459. package/skills/mcp-server-patterns/SKILL.md +127 -0
  460. package/skills/mcp-server-patterns/evals/triggers.json +18 -0
  461. package/skills/mcp-server-patterns/references/protocol-notes.md +68 -0
  462. package/skills/metrics-dashboards/SKILL.md +113 -0
  463. package/skills/metrics-dashboards/evals/triggers.json +16 -0
  464. package/skills/ml-experiment-workflow/SKILL.md +125 -0
  465. package/skills/ml-experiment-workflow/evals/triggers.json +16 -0
  466. package/skills/mongodb-patterns/SKILL.md +115 -0
  467. package/skills/mongodb-patterns/evals/triggers.json +18 -0
  468. package/skills/mongodb-patterns/references/indexes-and-aggregation.md +94 -0
  469. package/skills/mpesa-daraja-integration/SKILL.md +70 -0
  470. package/skills/mpesa-daraja-integration/evals/triggers.json +16 -0
  471. package/skills/mpesa-daraja-integration/references/api.md +103 -0
  472. package/skills/mpesa-daraja-integration/references/callbacks.md +74 -0
  473. package/skills/mtn-momo-integration/SKILL.md +66 -0
  474. package/skills/mtn-momo-integration/evals/triggers.json +16 -0
  475. package/skills/mtn-momo-integration/references/api.md +153 -0
  476. package/skills/mtn-momo-integration/references/callbacks.md +92 -0
  477. package/skills/mtn-momo-integration/references/sandbox-and-go-live.md +51 -0
  478. package/skills/mtn-momo-integration/scripts/sandbox-setup.js +79 -0
  479. package/skills/mysql-patterns/SKILL.md +96 -0
  480. package/skills/mysql-patterns/evals/triggers.json +16 -0
  481. package/skills/mysql-patterns/references/explain.md +34 -0
  482. package/skills/mysql-patterns/references/online-ddl.md +41 -0
  483. package/skills/nestjs-patterns/SKILL.md +114 -0
  484. package/skills/nestjs-patterns/evals/triggers.json +16 -0
  485. package/skills/nestjs-patterns/references/testing.md +68 -0
  486. package/skills/network-automation/SKILL.md +107 -0
  487. package/skills/network-automation/evals/triggers.json +18 -0
  488. package/skills/network-automation/references/tool-snippets.md +153 -0
  489. package/skills/network-troubleshooting/SKILL.md +152 -0
  490. package/skills/network-troubleshooting/evals/triggers.json +18 -0
  491. package/skills/network-troubleshooting/references/commands.md +33 -0
  492. package/skills/nextjs-patterns/SKILL.md +150 -0
  493. package/skills/nextjs-patterns/evals/triggers.json +18 -0
  494. package/skills/nextjs-patterns/references/caching.md +87 -0
  495. package/skills/node-backend-patterns/SKILL.md +103 -0
  496. package/skills/node-backend-patterns/evals/triggers.json +16 -0
  497. package/skills/node-backend-patterns/references/templates.md +122 -0
  498. package/skills/nuxt-patterns/SKILL.md +103 -0
  499. package/skills/nuxt-patterns/evals/triggers.json +16 -0
  500. package/skills/parallel-agent-orchestration/SKILL.md +106 -0
  501. package/skills/parallel-agent-orchestration/evals/triggers.json +14 -0
  502. package/skills/paystack-integration/SKILL.md +59 -0
  503. package/skills/paystack-integration/evals/triggers.json +14 -0
  504. package/skills/paystack-integration/references/api.md +73 -0
  505. package/skills/paystack-integration/references/mobile-money.md +50 -0
  506. package/skills/paystack-integration/references/webhooks.md +80 -0
  507. package/skills/pci-dss-scope/SKILL.md +103 -0
  508. package/skills/pci-dss-scope/evals/triggers.json +18 -0
  509. package/skills/pci-dss-scope/references/saq-and-data.md +36 -0
  510. package/skills/perl-patterns/SKILL.md +135 -0
  511. package/skills/perl-patterns/evals/triggers.json +18 -0
  512. package/skills/perl-testing/SKILL.md +126 -0
  513. package/skills/perl-testing/evals/triggers.json +17 -0
  514. package/skills/php-patterns/SKILL.md +116 -0
  515. package/skills/php-patterns/evals/triggers.json +16 -0
  516. package/skills/php-testing/SKILL.md +123 -0
  517. package/skills/php-testing/evals/triggers.json +16 -0
  518. package/skills/postgres-patterns/SKILL.md +103 -0
  519. package/skills/postgres-patterns/evals/triggers.json +17 -0
  520. package/skills/postgres-patterns/references/explain.md +59 -0
  521. package/skills/postgres-patterns/references/locks.md +53 -0
  522. package/skills/prd-writing/SKILL.md +124 -0
  523. package/skills/prd-writing/evals/triggers.json +15 -0
  524. package/skills/prisma-patterns/SKILL.md +83 -0
  525. package/skills/prisma-patterns/evals/triggers.json +18 -0
  526. package/skills/prisma-patterns/references/prisma-8.md +46 -0
  527. package/skills/prisma-patterns/references/workflow.md +50 -0
  528. package/skills/privacy-compliance/SKILL.md +121 -0
  529. package/skills/privacy-compliance/evals/triggers.json +18 -0
  530. package/skills/privacy-compliance/references/jurisdictions.md +51 -0
  531. package/skills/production-scheduling/SKILL.md +98 -0
  532. package/skills/production-scheduling/evals/triggers.json +16 -0
  533. package/skills/prompt-engineering/SKILL.md +92 -0
  534. package/skills/prompt-engineering/evals/triggers.json +16 -0
  535. package/skills/python-patterns/SKILL.md +107 -0
  536. package/skills/python-patterns/evals/triggers.json +16 -0
  537. package/skills/python-patterns/references/tooling.md +101 -0
  538. package/skills/python-testing/SKILL.md +126 -0
  539. package/skills/python-testing/evals/triggers.json +16 -0
  540. package/skills/python-testing/references/mocking.md +71 -0
  541. package/skills/pytorch-patterns/SKILL.md +139 -0
  542. package/skills/pytorch-patterns/evals/triggers.json +16 -0
  543. package/skills/pytorch-patterns/references/debugging.md +39 -0
  544. package/skills/quarkus-patterns/SKILL.md +93 -0
  545. package/skills/quarkus-patterns/evals/triggers.json +18 -0
  546. package/skills/rag-pipeline-patterns/SKILL.md +117 -0
  547. package/skills/rag-pipeline-patterns/evals/triggers.json +18 -0
  548. package/skills/rag-pipeline-patterns/references/evaluation.md +37 -0
  549. package/skills/rag-pipeline-patterns/references/retrieval-recipes.md +78 -0
  550. package/skills/rails-patterns/SKILL.md +132 -0
  551. package/skills/rails-patterns/evals/triggers.json +16 -0
  552. package/skills/react-native-patterns/SKILL.md +101 -0
  553. package/skills/react-native-patterns/evals/triggers.json +16 -0
  554. package/skills/react-patterns/SKILL.md +140 -0
  555. package/skills/react-patterns/evals/triggers.json +18 -0
  556. package/skills/react-performance/SKILL.md +107 -0
  557. package/skills/react-performance/evals/triggers.json +18 -0
  558. package/skills/redis-patterns/SKILL.md +109 -0
  559. package/skills/redis-patterns/evals/triggers.json +18 -0
  560. package/skills/redis-patterns/references/operations.md +61 -0
  561. package/skills/refactoring-safely/SKILL.md +107 -0
  562. package/skills/refactoring-safely/evals/triggers.json +17 -0
  563. package/skills/release-management/SKILL.md +141 -0
  564. package/skills/release-management/evals/triggers.json +16 -0
  565. package/skills/remotion-video/SKILL.md +91 -0
  566. package/skills/remotion-video/evals/triggers.json +16 -0
  567. package/skills/remotion-video/references/lambda.md +66 -0
  568. package/skills/returns-reverse-logistics/SKILL.md +97 -0
  569. package/skills/returns-reverse-logistics/evals/triggers.json +16 -0
  570. package/skills/ruby-patterns/SKILL.md +127 -0
  571. package/skills/ruby-patterns/evals/triggers.json +18 -0
  572. package/skills/ruby-testing/SKILL.md +113 -0
  573. package/skills/ruby-testing/evals/triggers.json +18 -0
  574. package/skills/runbook-writing/SKILL.md +101 -0
  575. package/skills/runbook-writing/evals/triggers.json +14 -0
  576. package/skills/rust-patterns/SKILL.md +118 -0
  577. package/skills/rust-patterns/evals/triggers.json +16 -0
  578. package/skills/rust-patterns/references/cargo-and-clippy.md +105 -0
  579. package/skills/rust-patterns/references/errors-and-traits.md +97 -0
  580. package/skills/rust-testing/SKILL.md +148 -0
  581. package/skills/rust-testing/evals/triggers.json +16 -0
  582. package/skills/rust-testing/references/fakes-proptest-async.md +113 -0
  583. package/skills/search-first/SKILL.md +73 -0
  584. package/skills/search-first/evals/triggers.json +14 -0
  585. package/skills/security-review/SKILL.md +58 -0
  586. package/skills/security-review/evals/triggers.json +14 -0
  587. package/skills/security-review/references/checklist.md +54 -0
  588. package/skills/security-review/scripts/scan-secrets.js +79 -0
  589. package/skills/seo-audit/SKILL.md +111 -0
  590. package/skills/seo-audit/evals/triggers.json +16 -0
  591. package/skills/seo-audit/references/checks.md +65 -0
  592. package/skills/session-handoff/SKILL.md +101 -0
  593. package/skills/session-handoff/evals/triggers.json +14 -0
  594. package/skills/skill-authoring/SKILL.md +87 -0
  595. package/skills/skill-authoring/evals/triggers.json +14 -0
  596. package/skills/skill-authoring/references/frontmatter.md +40 -0
  597. package/skills/slack-app-integration/SKILL.md +108 -0
  598. package/skills/slack-app-integration/evals/triggers.json +17 -0
  599. package/skills/smart-contract-security/SKILL.md +110 -0
  600. package/skills/smart-contract-security/evals/triggers.json +16 -0
  601. package/skills/smart-contract-security/references/vulnerability-checklist.md +79 -0
  602. package/skills/social-media-publishing/SKILL.md +84 -0
  603. package/skills/social-media-publishing/evals/triggers.json +17 -0
  604. package/skills/social-media-publishing/references/platform-apis.md +116 -0
  605. package/skills/solidity-patterns/SKILL.md +95 -0
  606. package/skills/solidity-patterns/evals/triggers.json +16 -0
  607. package/skills/spring-boot-patterns/SKILL.md +128 -0
  608. package/skills/spring-boot-patterns/evals/triggers.json +18 -0
  609. package/skills/spring-boot-patterns/references/testing.md +72 -0
  610. package/skills/stripe-integration/SKILL.md +69 -0
  611. package/skills/stripe-integration/evals/triggers.json +16 -0
  612. package/skills/stripe-integration/references/api.md +71 -0
  613. package/skills/stripe-integration/references/billing.md +58 -0
  614. package/skills/stripe-integration/references/webhooks.md +76 -0
  615. package/skills/subscription-billing-ops/SKILL.md +118 -0
  616. package/skills/subscription-billing-ops/evals/triggers.json +17 -0
  617. package/skills/subscription-billing-ops/references/proration.md +47 -0
  618. package/skills/subscription-billing-ops/references/revenue-metrics.md +38 -0
  619. package/skills/svelte-patterns/SKILL.md +122 -0
  620. package/skills/svelte-patterns/evals/triggers.json +16 -0
  621. package/skills/swift-patterns/SKILL.md +113 -0
  622. package/skills/swift-patterns/evals/triggers.json +16 -0
  623. package/skills/swift-patterns/references/concurrency-migration.md +40 -0
  624. package/skills/swift-testing/SKILL.md +121 -0
  625. package/skills/swift-testing/evals/triggers.json +16 -0
  626. package/skills/swift-testing/references/swift-testing-cheatsheet.md +81 -0
  627. package/skills/swiftui-patterns/SKILL.md +102 -0
  628. package/skills/swiftui-patterns/evals/triggers.json +16 -0
  629. package/skills/tdd-workflow/SKILL.md +67 -0
  630. package/skills/tdd-workflow/evals/triggers.json +14 -0
  631. package/skills/technical-writing/SKILL.md +95 -0
  632. package/skills/technical-writing/evals/triggers.json +14 -0
  633. package/skills/terraform-patterns/SKILL.md +122 -0
  634. package/skills/terraform-patterns/evals/triggers.json +16 -0
  635. package/skills/terraform-patterns/references/backends.md +67 -0
  636. package/skills/test-coverage-improvement/SKILL.md +107 -0
  637. package/skills/test-coverage-improvement/evals/triggers.json +16 -0
  638. package/skills/threat-modeling/SKILL.md +113 -0
  639. package/skills/threat-modeling/evals/triggers.json +16 -0
  640. package/skills/typescript-patterns/SKILL.md +122 -0
  641. package/skills/typescript-patterns/evals/triggers.json +16 -0
  642. package/skills/typescript-testing/SKILL.md +101 -0
  643. package/skills/typescript-testing/evals/triggers.json +16 -0
  644. package/skills/verification-loop/SKILL.md +70 -0
  645. package/skills/verification-loop/evals/triggers.json +14 -0
  646. package/skills/verification-loop/scripts/detect-checks.js +102 -0
  647. package/skills/vite-patterns/SKILL.md +117 -0
  648. package/skills/vite-patterns/evals/triggers.json +16 -0
  649. package/skills/vue-patterns/SKILL.md +104 -0
  650. package/skills/vue-patterns/evals/triggers.json +16 -0
  651. package/skills/web-accessibility/SKILL.md +119 -0
  652. package/skills/web-accessibility/evals/triggers.json +16 -0
  653. package/skills/web-performance/SKILL.md +107 -0
  654. package/skills/web-performance/evals/triggers.json +16 -0
  655. package/skills/web-scraping/SKILL.md +80 -0
  656. package/skills/web-scraping/evals/triggers.json +16 -0
@@ -0,0 +1,103 @@
1
+ ---
2
+ name: pci-dss-scope
3
+ description: Shrinks PCI DSS scope by keeping cardholder data off your own systems, using processor-hosted payment pages, redirects or iframe hosted fields, provider tokens instead of card numbers, strict rules on what never to log or store (full PAN, CVV, track data, PIN), and a high-level guide to which self-assessment questionnaire (SAQ A, A-EP, D and others) the design points to, with a clear not-legal-advice and not-QSA line. Use when designing card checkout, deciding between hosted fields and a custom card form, finding card numbers in logs or databases, or estimating PCI effort for a merchant.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. Works with any card processor (Stripe, Adyen, Paystack, Flutterwave, Braintree and others). Standard detail lives in references/saq-and-data.md and must be checked against the PCI SSC document library.
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: compliance
9
+ kete-loom/risk: writes-files
10
+ kete-loom/owner: "Kete-org"
11
+ ---
12
+
13
+ # PCI DSS scope
14
+
15
+ The cheapest PCI DSS control is card data that never touches your systems. Design so the browser or app sends card details straight to the processor, your servers only ever see a token, and nothing you run can read or alter the card form.
16
+
17
+ ## Boundary: this is not legal or assessor advice
18
+
19
+ - You help with architecture and code. Your acquirer (the merchant's bank) decides which validation the merchant must do, and a Qualified Security Assessor (QSA) or the acquirer decides the final scope and SAQ type.
20
+ - Say so once when the user asks "are we compliant" or "which SAQ", give the engineering view, and tell them to confirm with the acquirer or QSA.
21
+ - Never state that a system "is PCI compliant". Say what is in scope, what was removed from scope, and what remains.
22
+
23
+ ## Step 1: find the card data flow
24
+
25
+ Search the codebase and config for:
26
+
27
+ - Card form fields: `card_number`, `cardNumber`, `pan`, `cvv`, `cvc`, `expiry`, `exp_month`, inputs with `autocomplete="cc-number"` or `cc-csc`.
28
+ - Server endpoints or models that accept or store those fields, and any calls to processor "raw card" APIs (direct card charge, server-side tokenisation with raw PAN).
29
+ - Logs, error trackers, analytics, session replay, support tooling and data warehouse tables that could capture request bodies on checkout pages.
30
+ - Mobile apps: native card fields posting to your API instead of the processor SDK.
31
+
32
+ Draw the flow: where card data is entered, which system receives it first, and where tokens go.
33
+
34
+ ## Step 2: choose the lowest-scope pattern
35
+
36
+ Prefer, in this order:
37
+
38
+ 1. **Redirect to a processor-hosted payment page** (for example Stripe Checkout, Paystack or Flutterwave hosted checkout, Adyen Hosted Checkout). Card entry happens entirely on the processor's domain.
39
+ 2. **Processor iframe or hosted fields** (for example Stripe Elements, Adyen Drop-in or Components, Braintree Hosted Fields). Each card field is an iframe served by the processor; your page never has the card values.
40
+ 3. **Processor mobile SDK** with its own card UI, which returns a token or payment method id.
41
+ 4. **Your own card form that posts directly to the processor with JavaScript** (direct post, or your script calling a tokenisation API). Your page can read the card data, so your web server is in scope (typically SAQ A-EP territory).
42
+ 5. **Card data through your servers** (your API receives the PAN). This brings full scope (SAQ D or an onsite assessment). **Stop and ask the user** for the business reason before building it, and recommend 1 to 3 instead.
43
+
44
+ When asked to "add a card form", build option 1 or 2 unless the user gives a reason not to.
45
+
46
+ ## Step 3: tokens, not card numbers
47
+
48
+ - Store only the processor's token or payment method id, plus display data the processor returns: brand, last four digits, expiry month and year.
49
+ - Use the processor's customer and saved-payment-method APIs for repeat charges and subscriptions. Never build your own card vault.
50
+ - Webhooks and API responses may contain masked card data; persist only the fields you need.
51
+ - If a legacy table already holds full PANs, **stop and tell the user**. Plan a migration to processor tokens, then securely delete the PAN column and its backups. Don't quietly drop the data.
52
+
53
+ ## Step 4: what never to log or store
54
+
55
+ Sensitive authentication data must never be stored after authorisation, even encrypted:
56
+
57
+ - CVV, CVC, CVV2, CID (the 3 or 4 digit card verification code)
58
+ - Full magnetic stripe or chip track data
59
+ - PIN or PIN block
60
+
61
+ Never log or store a full PAN (card number) in your systems when using the patterns above. In code:
62
+
63
+ - Add a redaction filter to the logger, error tracker and APM that masks any 13 to 19 digit sequence passing a Luhn check, and drops fields named like the ones in Step 1. Test it with a known test card number such as `4242424242424242`.
64
+ - Turn off request body capture on checkout routes in error trackers and session replay.
65
+ - Never put card data in URLs, query strings, analytics events, emails, tickets or AI prompts.
66
+ - If a PAN must be shown, show at most the BIN (first six or eight digits) and last four; usually last four is enough.
67
+ - Use only the processor's documented test card numbers in tests and fixtures, never real cards.
68
+
69
+ ## Step 5: protect the payment page itself
70
+
71
+ Even with a redirect or iframe, the page that loads or links to the payment form can be attacked (for example a script that swaps the iframe or redirect URL for a fake one).
72
+
73
+ - Serve the checkout page over HTTPS with a strict Content Security Policy that lists only your own and the processor's script and frame origins.
74
+ - Keep third-party scripts (tag managers, chat widgets, A/B testing, ads) off checkout pages, or keep an inventory of each with a reason.
75
+ - Use Subresource Integrity on static third-party scripts where the vendor supports it.
76
+ - Monitor checkout pages for unexpected script or header changes.
77
+ - These controls matter most for iframe or hosted-fields pages: SAQ A eligibility for an embedded form depends on the page not being open to script attacks (see `references/saq-and-data.md`). A full redirect avoids that question, which is one reason it ranks first.
78
+
79
+ ## Step 6: estimate the SAQ at a high level
80
+
81
+ Use `references/saq-and-data.md` to map the chosen pattern to a likely SAQ, and list the eligibility conditions that must stay true. Present it as "likely SAQ, to confirm with your acquirer", never as a decision.
82
+
83
+ ## Never
84
+
85
+ - Never accept, forward or store card numbers on your servers when a hosted option exists, without the user's explicit, informed agreement.
86
+ - Never store CVV, track data or PIN, in any form, for any length of time after authorisation.
87
+ - Never log raw request bodies on payment routes.
88
+ - Never copy production payment data to test or staging.
89
+ - Never use real card numbers in tests, demos or screenshots.
90
+
91
+ ## Report format
92
+
93
+ ```
94
+ PCI scope review: <app or checkout>
95
+ Card entry pattern: <redirect | hosted fields | SDK | direct post | server-side>
96
+ Systems that see card data: <list, or "none: processor only">
97
+ Likely SAQ (confirm with acquirer or QSA): <type> because <reason>
98
+ Findings (highest risk first):
99
+ 1. [High|Medium|Low] <what> at <file:line or system> -> <fix>
100
+ Scope reductions available: <list>
101
+ Not checked: <systems you could not see>
102
+ This is engineering guidance, not legal or assessor advice.
103
+ ```
@@ -0,0 +1,18 @@
1
+ {
2
+ "should_trigger": [
3
+ "We want our own styled card form on checkout, how do we do that without pulling our servers into PCI scope?",
4
+ "I found full card numbers in our application logs, what do we do and how do we stop it?",
5
+ "Which PCI self-assessment questionnaire do we likely need if we use Stripe Elements?",
6
+ "Is it okay to save the CVV in the database so returning customers don't have to type it again?",
7
+ "Our mobile app posts card details to our API and then we call the processor, is that a PCI problem?",
8
+ "Hosted payment page or iframe fields: which keeps us at SAQ A?"
9
+ ],
10
+ "should_not_trigger": [
11
+ "Integrate Stripe subscriptions with trial periods and proration into our SaaS billing",
12
+ "My Paystack webhook signature check keeps failing, can you fix it?",
13
+ "We store patient insurance ids, do we need a BAA with our cloud provider?",
14
+ "Build a consent banner and data export for GDPR subject access requests",
15
+ "Review our payment service code for double charging and missing idempotency keys",
16
+ "Run a dependency audit on our checkout service and flag vulnerable npm packages"
17
+ ]
18
+ }
@@ -0,0 +1,36 @@
1
+ # SAQ types and card data rules
2
+
3
+ Engineering summary only. The PCI Security Standards Council (pcisecuritystandards.org) document library is the source of truth, and the acquirer decides which validation a merchant does. Check the current SAQ document and its eligibility criteria before telling a user which one applies.
4
+
5
+ ## Current standard
6
+
7
+ - PCI DSS v4.0.1 (published June 2024) is the current version this skill was written against; v4.0 was retired at the end of 2024. Requirements marked "future-dated" in v4.x became mandatory on 31 March 2025.
8
+ - SAQ A was revised in January 2025 (effective 31 March 2025): requirements 6.4.3 and 11.6.1 (payment page script management and change detection) and 12.3.1 were removed from it, and a new eligibility criterion was added that the merchant confirms its site is not susceptible to attacks from scripts that could affect the merchant's e-commerce systems. PCI SSC FAQ 1588 (February 2025) clarifies that this criterion concerns merchant pages that embed the processor's payment form (iframes), not pages that only redirect or link to the processor's page. Assessors differ on how much script control (page-level 6.4.3 and 11.6.1 style controls, or site-wide) satisfies it. Read the current SAQ A and FAQ, and let the acquirer or QSA decide.
9
+
10
+ ## Common SAQ types (high level)
11
+
12
+ | SAQ | Typical situation | What it means for engineering |
13
+ |---|---|---|
14
+ | A | Card-not-present merchant that fully outsources all cardholder data functions: redirect to a processor page, or processor iframes for every card field. No electronic storage, processing or transmission of card data on merchant systems | Keep it that way: no card fields of your own, protect the page that hosts the iframe or redirect (Step 5 of the skill), minimal stored data |
15
+ | A-EP | E-commerce merchant that outsources processing but whose website can affect the security of the payment transaction, for example a merchant page with direct post or JavaScript that handles card entry | Web servers serving the payment page are in scope: hardening, vulnerability scans, change control, script controls |
16
+ | B | Imprint machines or standalone dial-out terminals, no electronic card data storage | Not usually an engineering concern |
17
+ | B-IP | Standalone PTS-approved terminals with an IP connection to the processor | Network segmentation for the terminals |
18
+ | C-VT | Manual entry, one transaction at a time, into a processor's virtual terminal in a browser | Locked-down workstations; no card data storage |
19
+ | C | Payment application systems connected to the internet, no electronic storage | Larger scope: the payment application and its network |
20
+ | P2PE | Validated point-to-point encryption hardware solution only | Use the listed P2PE solution as validated |
21
+ | D (merchant) | Everything else, including any merchant that stores card data electronically or whose servers receive the PAN | Full PCI DSS requirements |
22
+ | D (service provider) | Service providers eligible to self-assess | Full requirements for service providers |
23
+
24
+ Higher-volume merchants may need an onsite assessment by a QSA and a Report on Compliance instead of an SAQ. The card brands and acquirer set those levels.
25
+
26
+ ## Data rules (PCI DSS v4.0.1 Requirement 3)
27
+
28
+ | Data element | Store? | Notes |
29
+ |---|---|---|
30
+ | Primary account number (PAN) | Only if needed, and then unreadable | Masked when displayed: at most BIN (first six or eight) and last four. Unreadable when stored: strong cryptography, truncation, tokenisation or one-way hashes with controls |
31
+ | Cardholder name, expiry, service code | Allowed if needed | Protected when stored with the PAN |
32
+ | Full track data (stripe or chip) | Never after authorisation | Even if encrypted |
33
+ | CVV2, CVC2, CID, CAV2 | Never after authorisation | Even if encrypted |
34
+ | PIN, PIN block | Never after authorisation | Even if encrypted |
35
+
36
+ Requirement 3.3.1 forbids keeping sensitive authentication data after authorisation. A processor token (for example a Stripe `pm_...` id or a Paystack `authorization_code`) is not a PAN, which is why tokenisation keeps systems out of scope.
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: perl-patterns
3
+ description: Modern Perl 5 conventions for writing and restructuring code - strict and warnings, lexical scope, references and nested data, Moo or Moose classes, try/catch error handling, cpanfile with cpanm or Carton, Perl::Critic policy and taint-safe system calls. Use when writing new Perl, modernising a legacy .pl or .pm script, choosing between Moo and Moose, or deciding how a Perl program should manage CPAN dependencies and shell out safely.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. Needs perl 5.10 or newer; guidance marks what needs 5.36 or 5.40.
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: coding
9
+ kete-loom/risk: writes-files
10
+ kete-loom/requires: "perl"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # Modern Perl patterns
15
+
16
+ Write Perl that a maintainer can read in five years. Match the project first, then apply these rules.
17
+
18
+ ## 0. Before you write
19
+
20
+ 1. Find the minimum perl the code must run on: `use v5.x` lines, `cpanfile` (`requires 'perl', '5.x'`), `Makefile.PL` (`MIN_PERL_VERSION`), `dist.ini`, CI matrix, and `perl -v` on the target host.
21
+ 2. Find the house OO system (Moo, Moose, Mouse, Object::Pad, hand-rolled `bless`) and the error style (die objects, Try::Tiny, `feature 'try'`). Keep using them.
22
+ 3. If the target perl is unknown and you need features newer than 5.10, **stop and ask** which perl ships in production.
23
+
24
+ ## 1. File header
25
+
26
+ Every file starts with strict and warnings. Pick one form:
27
+
28
+ ```perl
29
+ use v5.36; # strict, warnings, say, signatures; disables indirect and multidimensional
30
+ ```
31
+
32
+ ```perl
33
+ use strict;
34
+ use warnings; # for code that must run on perls older than 5.36
35
+ ```
36
+
37
+ - `use v5.40` adds the stable `try` feature and the builtin bundle (`true`, `false`, `trim`, ...). `finally` blocks are still experimental there.
38
+ - Modules end with `1;` unless the file uses `v5.38`+ (the `module_true` feature).
39
+ - Add `use utf8;` only when the source itself contains non-ASCII literals. Decode input and encode output explicitly (`open my $fh, '<:encoding(UTF-8)', $path`).
40
+
41
+ ## 2. Scope and variables
42
+
43
+ - Declare every variable with `my` in the smallest enclosing block. Use `state` for per-sub persistent values, not file-level globals.
44
+ - Never use `local $_` tricks or package globals to pass data between subs; pass arguments.
45
+ - `local` is only for dynamic globals you must change temporarily: `local $/;`, `local $@;`, `local $ENV{PATH}`.
46
+ - Use signatures on 5.36+: `sub fetch($url, %opt) { ... }`. Older code: `my ($self, %args) = @_;` on the first line.
47
+
48
+ ## 3. References and data structures
49
+
50
+ - Build nested data with literals: `my %cfg = (hosts => [ ... ], retry => { max => 3 });`.
51
+ - Dereference with postfix syntax on 5.24+: `$cfg->{hosts}->@*`, `$row->%{qw(id name)}`. Use `@{ $ref }` on older perls.
52
+ - Check shape before you trust it: `ref $x eq 'HASH'`, or `Scalar::Util::reftype` / `blessed` for objects.
53
+ - Copy deeply only when needed (`Storable::dclone`); assigning a ref shares the data.
54
+ - Avoid autovivification surprises: `exists $h{a} && exists $h{a}{b}` instead of testing `$h{a}{b}` directly, or use the `autovivification` pragma if the project already does.
55
+ - Know context: `my $n = @list` gives a count, `my ($first) = @list` gives an element, `return;` (not `return undef;`) for "nothing" so list callers get an empty list.
56
+
57
+ ## 4. Object orientation
58
+
59
+ Decision rule:
60
+
61
+ | Need | Use |
62
+ |---|---|
63
+ | Plain classes, fast startup, few dependencies | Moo |
64
+ | Introspection, meta-programming, MooseX extensions already in the project | Moose |
65
+ | perl 5.38+ and the team accepts an experimental feature | core `class` (`use feature 'class'`) |
66
+ | Tiny script with one data holder | a hash, not a class |
67
+
68
+ Moo class shape:
69
+
70
+ ```perl
71
+ package My::Client;
72
+ use v5.36;
73
+ use Moo;
74
+ use HTTP::Tiny;
75
+ use Types::Standard qw(Str Int);
76
+ use namespace::autoclean;
77
+
78
+ has base_url => (is => 'ro', isa => Str, required => 1);
79
+ has timeout => (is => 'ro', isa => Int, default => 10);
80
+ has _ua => (is => 'lazy');
81
+ sub _build__ua ($self) { HTTP::Tiny->new(timeout => $self->timeout) }
82
+
83
+ 1;
84
+ ```
85
+
86
+ - Prefer `is => 'ro'` and build new objects instead of mutating.
87
+ - Use roles (`Moo::Role`, `with`) for shared behaviour instead of deep inheritance.
88
+ - With Moose, end the class with `__PACKAGE__->meta->make_immutable;`.
89
+
90
+ ## 5. Error handling
91
+
92
+ - Fail with `die`, using `Carp::croak` in modules so the error points at the caller.
93
+ - For errors callers branch on, throw objects (an exception class with a `message` and a type) rather than matching message strings.
94
+ - Catching, by target perl:
95
+ - 5.40+: `use v5.40; try { ... } catch ($e) { ... }`.
96
+ - 5.34 to 5.38: `use feature 'try'; no warnings 'experimental::try';` only if the team accepts experimental code; otherwise Try::Tiny.
97
+ - Older: Try::Tiny (`try { } catch { warn $_ };` note the trailing semicolon and that `return` inside returns from the block, not the sub), or Syntax::Keyword::Try.
98
+ - Without Try::Tiny or `try`, never write `eval { ... }; if ($@)`: `$@` can be empty or clobbered by a destructor. Use `eval { ...; 1 } or do { my $err = $@ || 'unknown error'; ... };`.
99
+ - Check every system call: `open(...) or die "open $path: $!"`, `close $fh or die ...`. Or `use autodie;` file-wide.
100
+
101
+ ## 6. Dependencies (CPAN)
102
+
103
+ 1. Declare dependencies in a `cpanfile` (`requires 'Moo', '2.004';`, `on test => sub { requires 'Test2::V0'; };`).
104
+ 2. Install for development: `cpanm --installdeps .`.
105
+ 3. For reproducible apps, use Carton: `carton install` writes `cpanfile.snapshot` and `local/`; run with `carton exec perl script.pl` or `carton exec prove -lr t`. Commit `cpanfile.snapshot`, never `local/`.
106
+ 4. Do not install into the system perl with `sudo cpan`. Use local::lib, Carton, or perlbrew/plenv.
107
+ 5. Before adding a module, check it is maintained (MetaCPAN: recent release, CPAN Testers results) and that a core module (`List::Util`, `Scalar::Util`, `File::Spec`, `File::Temp`, `HTTP::Tiny`, `JSON::PP`, `Time::Piece`) does not already do the job.
108
+
109
+ ## 7. Perl::Critic and tidying
110
+
111
+ - Run `perlcritic --severity 3 lib/ bin/` (lower number is stricter; 5 is gentlest). Respect the project's `.perlcriticrc`.
112
+ - Fix the code rather than adding `## no critic`. If a disable is justified, name the policy and give the reason on the same line: `## no critic (ProhibitStringyEval) -- loads generated plugin code`.
113
+ - Format with `perltidy` using the project's `.perltidyrc`; do not reformat files you did not otherwise change.
114
+
115
+ ## 8. Security: input, files, shells
116
+
117
+ - Run untrusted-input programs (CGI, setuid, scripts fed by other users) under taint mode: `#!/usr/bin/perl -T`. Untaint only by matching a strict allow-list regex and using the capture: `my ($id) = $in =~ /\A(\d{1,10})\z/ or die "bad id";`.
118
+ - Under taint, set a safe environment before any command: `local $ENV{PATH} = '/usr/bin:/bin'; delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};`.
119
+ - Always three-arg `open` with a lexical handle: `open my $fh, '<', $path`. Never two-arg `open(FH, $path)`; a filename like `| rm -rf ~` runs a command.
120
+ - Run commands with the list form so no shell parses the arguments: `system('git', 'log', '--', $file) == 0 or die "git failed: $?";`.
121
+ - Capture output without a shell: `open my $ph, '-|', 'git', 'log', '--', $file or die $!;` or IPC::Run3 / IPC::Open3. Never interpolate input into backticks, `qx//` or one-string `system`.
122
+ - Anchor validation regexes with `\A` and `\z` (not `^` and `$`, which allow a trailing newline).
123
+ - Never `eval` a string built from input. Use `quotemeta` / `\Q...\E` when input goes into a regex.
124
+ - Database code: placeholders with DBI (`$dbh->prepare('SELECT * FROM t WHERE id = ?')`), never interpolated SQL. Set `RaiseError => 1`.
125
+
126
+ ## Never
127
+
128
+ - Never ship code without `use strict; use warnings` (or a `use v5.36`+ line).
129
+ - Never use `$&`, `$'` or `` $` `` in code that must run on perls older than 5.20 (global slowdown).
130
+ - Never rely on hash order; sort keys when output order matters.
131
+ - Never change the house OO system or error style in a patch that has another purpose.
132
+
133
+ ## Report back
134
+
135
+ End with: files changed, the minimum perl the code now needs, new CPAN dependencies (with versions) and whether `cpanfile` was updated, the `perlcritic` severity you ran and its result, and anything you did not verify (for example "did not run under -T").
@@ -0,0 +1,18 @@
1
+ {
2
+ "should_trigger": [
3
+ "Turn this old Perl script with global variables and no strict into modern Perl",
4
+ "Should I write this Perl class with Moo or Moose? It's a small CLI tool",
5
+ "How do I call an external command from Perl with a filename the user gave me, without shell injection?",
6
+ "Set up a cpanfile and Carton so our Perl app deploys the same module versions everywhere",
7
+ "What's the right way to catch exceptions in Perl 5.36, Try::Tiny or the try feature?",
8
+ "My nested Perl hash of arrays keeps autovivifying keys, how should I structure and access it?"
9
+ ],
10
+ "should_not_trigger": [
11
+ "Write Test::More tests for my Perl module and measure coverage with Devel::Cover",
12
+ "Review this Perl pull request for injection and two-arg open problems",
13
+ "cpanm fails building DBD::mysql with 'mysql_config not found', fix it",
14
+ "Can't locate My/Module.pm in @INC when I run the script from cron",
15
+ "Write idiomatic Ruby service objects for this Rails controller",
16
+ "Convert this Perl one-liner into a Python script"
17
+ ]
18
+ }
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: perl-testing
3
+ description: Perl test suites with Test::More or Test2::V0, run through prove - writing .t files, subtests, exception and warning checks, mocking with Test::MockModule or Test2::Mock, temp-file fixtures, and coverage reports from Devel::Cover. Use when adding or fixing tests for a Perl module or script, setting up a t/ directory, making a flaky prove run deterministic, or finding which Perl code paths no test exercises.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. Needs perl and prove; coverage needs Devel::Cover from CPAN.
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: testing
9
+ kete-loom/risk: runs-commands
10
+ kete-loom/requires: "perl, prove"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # Perl testing
15
+
16
+ Tests live in `t/*.t`, run with `prove`, and stay deterministic. Match the framework the project already uses.
17
+
18
+ ## 0. Before you start
19
+
20
+ 1. Find the test setup: `t/`, `xt/` (author tests), `cpanfile` `on test` block, `Makefile.PL` / `Build.PL` / `dist.ini`, CI config.
21
+ 2. Find the framework in existing tests: `use Test::More`, `use Test2::V0`, Test::Class, Test::Most. Keep it. New projects: Test2::V0.
22
+ 3. Run the suite once: `prove -lr t` (`-l` adds `lib/` to `@INC`, `-r` recurses). With Carton: `carton exec prove -lr t`. Dist::Zilla: `dzil test`.
23
+ 4. If it already fails, **stop and tell the user** which files fail before changing anything.
24
+
25
+ ## 1. File shape
26
+
27
+ Test::More:
28
+
29
+ ```perl
30
+ use strict;
31
+ use warnings;
32
+ use Test::More;
33
+
34
+ use My::Parser;
35
+
36
+ subtest 'parses a simple line' => sub {
37
+ my $r = My::Parser->new->parse("a=1");
38
+ is_deeply $r, { a => 1 }, 'key and value';
39
+ };
40
+
41
+ done_testing;
42
+ ```
43
+
44
+ Test2::V0 (enables strict and warnings itself):
45
+
46
+ ```perl
47
+ use Test2::V0;
48
+ use My::Parser;
49
+
50
+ is(My::Parser->new->parse("a=1"), { a => 1 }, 'deep compare with is');
51
+ like(dies { My::Parser->new->parse(undef) }, qr/no input/, 'dies on undef');
52
+
53
+ done_testing;
54
+ ```
55
+
56
+ - End every file with `done_testing;` instead of a hard-coded plan.
57
+ - One behaviour per `subtest`, named as a sentence.
58
+ - Name every assertion; the name is what a failure prints.
59
+
60
+ ## 2. Assertions to reach for
61
+
62
+ | Check | Test::More | Test2::V0 |
63
+ |---|---|---|
64
+ | Scalar equal | `is` | `is` |
65
+ | Deep structure | `is_deeply` | `is` (with `hash`/`array` builders for partial checks) |
66
+ | Regex | `like` | `like` |
67
+ | Dies | `eval` + `like $@` or Test::Fatal `exception { }` | `dies { }`, `lives { }` |
68
+ | Warns | Test::Warnings / Test::Warn | `warning { }`, `warnings { }`, `no_warnings { }` |
69
+ | Object | `isa_ok`, `can_ok` | `isa_ok`, `can_ok` |
70
+
71
+ - Add Test::Warnings (or `Test2::Plugin::NoWarnings`) so an unexpected warning fails the test.
72
+ - Compare numbers with a tolerance for floats; do not use `is` on computed floats.
73
+
74
+ ## 3. Fixtures and isolation
75
+
76
+ - Temp files: `File::Temp qw(tempdir)` with `tempdir(CLEANUP => 1)`. Never write into the repo or `/tmp` by fixed name.
77
+ - Small data files go in `t/data/`; locate them with `FindBin` or `File::Spec->catfile(...)` relative to the test file.
78
+ - Shared helpers go in `t/lib/` and load with `use lib 't/lib';`.
79
+ - Environment: `local $ENV{TZ} = 'UTC';` inside the test, never global changes.
80
+ - Time: inject a clock, or override with Test::MockTime; do not sleep.
81
+
82
+ ## 4. Mocking
83
+
84
+ Mock only slow or external boundaries (network, clock, external commands). Never mock the module under test.
85
+
86
+ Test::MockModule:
87
+
88
+ ```perl
89
+ use Test::MockModule;
90
+ my $mock = Test::MockModule->new('HTTP::Tiny');
91
+ $mock->redefine(get => sub { { success => 1, content => '{"ok":1}' } });
92
+ # restored automatically when $mock goes out of scope
93
+ ```
94
+
95
+ Test2::Mock (with Test2::V0): `my $m = mock 'HTTP::Tiny' => (override => [ get => sub { ... } ]);`.
96
+
97
+ - Use `redefine` (fails if the sub does not exist) rather than `mock` so a typo or API rename breaks the test.
98
+ - For external commands, wrap the call in one sub in your code and mock that sub.
99
+ - Keep the mock object in a lexical that lives for the whole test; once it goes out of scope the real sub returns.
100
+
101
+ ## 5. Running
102
+
103
+ - Single file, verbose: `prove -lv t/parser.t`.
104
+ - Parallel: `prove -lr -j4 t` (only if tests do not share files or ports).
105
+ - Author/release tests: `prove -lr xt` with `AUTHOR_TESTING=1` or `RELEASE_TESTING=1`, as the project expects.
106
+ - Shuffle to find order dependence: `prove -lr --shuffle t`.
107
+
108
+ ## 6. Coverage with Devel::Cover
109
+
110
+ 1. Install: `cpanm Devel::Cover` (or add to the `on develop` block of `cpanfile`).
111
+ 2. Clear old data and run: `cover -delete && HARNESS_PERL_SWITCHES=-MDevel::Cover prove -lr t && cover`.
112
+ For ExtUtils::MakeMaker or Module::Build dists, `cover -test` does the same.
113
+ 3. Read `cover_db/coverage.html`, or `cover -report text` in a terminal. Look at branch and condition columns, not only statement.
114
+ 4. Add tests for uncovered branches that carry behaviour (error paths, input validation). Do not write tests that only execute lines.
115
+ 5. Add `cover_db/` to `.gitignore`.
116
+
117
+ ## Rules
118
+
119
+ - Never delete, skip (`skip`, `todo`) or weaken an existing test to make the suite pass without telling the user why.
120
+ - No real network in `t/`. Live tests go in `xt/` behind an env var.
121
+ - Fixed seeds (`srand 42` only inside the test) and fixed time.
122
+ - If a test cannot be made green after three focused attempts, stop and report what you tried.
123
+
124
+ ## Report back
125
+
126
+ End with: test files added or changed, the exact `prove` command run, the pass/fail counts from its summary, coverage before and after if measured, and what is left untested.
@@ -0,0 +1,17 @@
1
+ {
2
+ "should_trigger": [
3
+ "Write Test::More tests for lib/My/Invoice.pm including the error cases",
4
+ "How do I mock HTTP::Tiny in a Perl test so it doesn't hit the network?",
5
+ "Set up Devel::Cover for our Perl project and show me which branches aren't tested",
6
+ "Migrate our t/ directory from Test::More to Test2::V0",
7
+ "prove -lr t passes alone but fails with -j4, help me make these Perl tests independent"
8
+ ],
9
+ "should_not_trigger": [
10
+ "Refactor this Perl module to use Moo instead of hand-written bless",
11
+ "Review my Perl changes for missing strict and unsafe system calls",
12
+ "Test::More won't install, cpanm says the build failed on make test, fix the dependency",
13
+ "Write RSpec tests for this Ruby class",
14
+ "Write pytest fixtures for the invoice module",
15
+ "Add Playwright end-to-end tests for the checkout page"
16
+ ]
17
+ }
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: php-patterns
3
+ description: Modern PHP 8 conventions for writing new code and restructuring old code, covering declare(strict_types=1), typed and readonly properties, backed enums, constructor promotion, exception hierarchies, PSR-4 autoloading through Composer, PSR-12 style, PHPStan or Psalm at a high level, and safe handling of SQL, output escaping, passwords and unserialize. Use when writing or modernising PHP 8.x classes, designing a Composer package or PHP service, or asking how idiomatic typed PHP should look.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. Needs php and composer; PHPStan or Psalm and PHP-CS-Fixer or PHP_CodeSniffer are used if the project has them.
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: coding
9
+ kete-loom/risk: runs-commands
10
+ kete-loom/requires: "php, composer"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # PHP patterns
15
+
16
+ Write PHP that a static analyser can fully understand: every file strict, every value typed, no magic you can't see. Follow the project's existing conventions and framework first (Laravel, Symfony and others have their own); these rules fill the gaps.
17
+
18
+ ## 0. Before you write
19
+
20
+ 1. Read `composer.json`: the `require.php` constraint and `config.platform.php` set the lowest PHP version you may target. Do not use a feature newer than that (see the table in section 2).
21
+ 2. Note `autoload.psr-4` namespaces so new classes land in the right folder with the right namespace.
22
+ 3. Find the quality tools: `phpstan.neon(.dist)`, `psalm.xml`, `.php-cs-fixer(.dist).php`, `phpcs.xml(.dist)`, `rector.php`, and the `scripts` section of `composer.json`. Use those commands, not your own.
23
+ 4. Search the codebase for an existing exception, value object, enum or helper before adding one.
24
+
25
+ ## 1. Every file
26
+
27
+ - Start with `<?php`, then `declare(strict_types=1);` as the first statement, then the namespace and `use` lines. No closing `?>` in pure-PHP files.
28
+ - One class, interface, trait or enum per file; file name equals the class name; path matches the PSR-4 prefix.
29
+ - Type every parameter, return and property. Use `void`, `never`, `?T`, union `A|B`, and `mixed` only when the value really is anything.
30
+ - Mark classes `final` unless they are designed for extension. Keep constructors free of I/O.
31
+ - Follow PSR-12 (or PER Coding Style) layout; let the project's fixer format it rather than formatting by hand.
32
+
33
+ `strict_types` applies to calls made *from* that file. Without it, `strlen(123)` and `function f(int $x)` called with `"5"` silently coerce. Adding it to an old file can turn a silent coercion into a `TypeError`: run the tests after adding it.
34
+
35
+ ## 2. Language features by version
36
+
37
+ | Feature | Since | Use for |
38
+ |---|---|---|
39
+ | Constructor promotion, `match`, nullsafe `?->`, named arguments, union types, `#[Attributes]` | 8.0 | Short value objects, exhaustive branching |
40
+ | Enums (pure and backed), `readonly` properties, `never`, first-class callables `f(...)`, `new` in initialisers | 8.1 | Closed sets of values, immutable data |
41
+ | `readonly` classes, DNF types `(A&B)\|null`, `true`/`false`/`null` as standalone types | 8.2 | Immutable DTOs |
42
+ | Typed class constants, `#[\Override]`, `json_validate()` | 8.3 | Catching broken overrides |
43
+ | Property hooks, asymmetric visibility `public private(set)`, `new Foo()->bar()` without parentheses, `#[\Deprecated]` | 8.4 | Replacing trivial getters/setters |
44
+
45
+ PHP 8.4 deprecates implicitly nullable parameters (`function f(Foo $x = null)`); write `?Foo $x = null`.
46
+
47
+ ## 3. Data and types
48
+
49
+ - Value objects: `final readonly class Money { public function __construct(public int $amountMinor, public Currency $currency) {} }`. Validate in the constructor and throw on invalid input; a constructed object is always valid.
50
+ - Money is integer minor units or a decimal library (`brick/money`, `moneyphp/money`), never `float`.
51
+ - Use a backed enum for any closed set of strings or ints that crosses a boundary (database column, API field): `enum Status: string { case Paid = 'paid'; }`. Parse with `Status::from()` when invalid input is a bug, `Status::tryFrom()` when it is user input you will reject.
52
+ - Use `match` instead of `switch`: it compares strictly, returns a value and throws `UnhandledMatchError` on a missing case. Over an enum, list every case and omit `default` so a new case fails loudly.
53
+ - Always compare with `===` and `!==`. Pass `true` as the strict flag to `in_array()` and `array_search()`. Never compare hashes or tokens with `==` (`"0e123" == "0e456"` is true); use `hash_equals()`.
54
+ - Arrays with a fixed shape are a missing class. Return a DTO, not `['id' => ..., 'name' => ...]`. Where arrays stay, document them for the analyser: `@param list<int>`, `@return array<string, User>`, `@var array{id: int, name: string}`.
55
+ - Prefer immutability: return a new instance (`withX()`) instead of mutating shared objects.
56
+
57
+ ## 4. Errors
58
+
59
+ - Throw exceptions; never return `false` or `null` to mean "failed" in new code. Return `null` only for "not found" and type it `?T`.
60
+ - Define a small hierarchy per module: `final class InvoiceNotFound extends \DomainException`. Extend SPL exceptions (`InvalidArgumentException`, `RuntimeException`, `LogicException`, `DomainException`) so callers can catch broadly.
61
+ - When rethrowing, chain the cause: `throw new PaymentFailed('charge declined', previous: $e);`.
62
+ - Catch only what you can handle. Never write an empty `catch (\Throwable $e) {}`. Catch `\Throwable` only at the top level (HTTP kernel, queue worker, CLI entry point) to log and respond.
63
+ - Many built-ins still signal failure by return value: check `file_get_contents`, `fopen`, `preg_match`, `json_decode`, `strpos` results with `=== false`. For JSON use `json_decode($s, true, 512, JSON_THROW_ON_ERROR)` and `json_encode($v, JSON_THROW_ON_ERROR)`.
64
+ - Never use the `@` error-suppression operator to hide a failure.
65
+
66
+ ## 5. Composer and autoloading
67
+
68
+ - Every class loads through Composer's PSR-4 autoloader; no `require_once` for classes. Tests use `autoload-dev`.
69
+ - After changing `autoload` in `composer.json` run `composer dump-autoload`. In production builds use `composer install --no-dev --optimize-autoloader` (or `--classmap-authoritative`).
70
+ - Commit `composer.lock` for applications; packages usually don't. Run `composer validate --strict` after editing `composer.json`.
71
+ - Add dependencies with `composer require vendor/pkg` (`--dev` for tools), using a caret constraint (`^2.3`). Do not hand-edit versions and skip the lock update.
72
+ - Set `config.platform.php` to the production PHP version so the lock file resolves for the server, not your laptop.
73
+ - Run `composer audit` before release and when adding a dependency.
74
+
75
+ ## 6. Static analysis
76
+
77
+ - PHPStan: aim for the highest level the project can sustain; for new projects start at level 6 or higher and raise it. Run `vendor/bin/phpstan analyse`.
78
+ - Psalm: `vendor/bin/psalm`, with `errorLevel` in `psalm.xml` (1 is strictest).
79
+ - Fix the type, don't silence the error. If legacy code makes a level impossible, generate a baseline (`phpstan analyse --generate-baseline`, `psalm --set-baseline=psalm-baseline.xml`) and never add new code to it.
80
+ - When you must ignore one line, use an identifier-specific ignore with a reason (`// @phpstan-ignore argument.type (reason)`, `/** @psalm-suppress PossiblyNullReference */`), never a blanket ignore.
81
+ - Use generics in docblocks (`@template T`, `Collection<int, User>`) where the language can't express the type.
82
+
83
+ ## 7. Security defaults
84
+
85
+ | Risk | Do | Never |
86
+ |---|---|---|
87
+ | SQL injection | PDO or the framework query builder with bound parameters: `$stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?'); $stmt->execute([$id]);`. Allow-list column and sort names. | Interpolate input into SQL, even "just an int" |
88
+ | XSS | Escape at output in the template engine (Twig, Blade escape by default). In raw PHP: `htmlspecialchars($s, ENT_QUOTES \| ENT_SUBSTITUTE, 'UTF-8')` | `echo $_GET[...]`, `{!! !!}` / `\|raw` on user data |
89
+ | Passwords | `password_hash($p, PASSWORD_DEFAULT)`, `password_verify()`, `password_needs_rehash()` | `md5`, `sha1`, unsalted hashes |
90
+ | Tokens | `random_bytes()`, `random_int()`, `bin2hex(random_bytes(32))` | `rand`, `mt_rand`, `uniqid` for secrets |
91
+ | Deserialisation | `json_decode`; if `unserialize` is unavoidable, `unserialize($s, ['allowed_classes' => false])` | `unserialize()` on any data a user can influence |
92
+ | Commands | Avoid the shell; if required, `escapeshellarg()` each argument or pass an array to `proc_open()` | Build shell strings from input |
93
+ | Files | Resolve with `realpath()` and check the prefix; store uploads outside the web root with generated names | `include`/`require` a path built from input |
94
+ | Config | Secrets from environment or a secrets manager; `display_errors=Off` in production | Commit `.env` or credentials |
95
+
96
+ Also: set PDO `PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION` and `PDO::ATTR_EMULATE_PREPARES => false` unless the project relies on emulation.
97
+
98
+ ## 8. Stop and ask the user
99
+
100
+ - The change needs a higher PHP version than `composer.json` allows, or a new runtime dependency.
101
+ - Adding `strict_types` or tightening types would change behaviour that existing callers depend on and there are no tests.
102
+ - You would need to raise or lower the PHPStan/Psalm level, or regenerate the baseline.
103
+
104
+ ## 9. Before you finish
105
+
106
+ 1. Run the project's linters and analyser on touched files (`vendor/bin/phpstan analyse <paths>`, `vendor/bin/psalm <paths>`, the fixer in check/dry-run mode).
107
+ 2. Run `php -l` on any file you could not analyse.
108
+ 3. Run the test suite (`vendor/bin/phpunit` or `vendor/bin/pest`). For writing tests, use the `php-testing` skill.
109
+ 4. Report what you changed and anything you did not run.
110
+
111
+ ## Never
112
+
113
+ - Leave a file without `declare(strict_types=1);` in a project that uses it.
114
+ - Use `extract()`, `eval()`, variable variables (`$$name`) or `global`.
115
+ - Use `float` for money, `==` for security comparisons, or `unserialize` on untrusted input.
116
+ - Disable a check, lower an analysis level or add to a baseline to make new code pass.
@@ -0,0 +1,16 @@
1
+ {
2
+ "should_trigger": [
3
+ "Write a PHP 8.3 value object for an email address with validation and readonly properties",
4
+ "How should I model order statuses in PHP now that we have enums?",
5
+ "Modernise this old PHP 7 class with typed properties and constructor promotion",
6
+ "Set up PSR-4 autoloading and a sensible folder layout for my new Composer package",
7
+ "What's the idiomatic way to handle errors in modern PHP instead of returning false?"
8
+ ],
9
+ "should_not_trigger": [
10
+ "Add PHPUnit tests with a data provider covering the discount rules",
11
+ "Check this PHP pull request for injection and escaping bugs before merge",
12
+ "composer update can't resolve a conflict between symfony/console and laravel/framework",
13
+ "Build a Laravel Eloquent model and controller for blog posts",
14
+ "Write idiomatic Ruby with proper error handling for this service object"
15
+ ]
16
+ }