@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,16 @@
1
+ {
2
+ "should_trigger": [
3
+ "Write a Dockerfile for our Express API that doesn't run as root",
4
+ "Our Docker image is 1.8GB, can you get it down with a multi-stage build?",
5
+ "Every docker build reinstalls all the npm packages even when I only change one source file",
6
+ "Set up a compose.yaml so I can run the app with Postgres and Redis locally",
7
+ "We pass the NPM_TOKEN as a build arg, how do we stop it ending up in the image?"
8
+ ],
9
+ "should_not_trigger": [
10
+ "Add liveness and readiness probes to our Kubernetes Deployment",
11
+ "Write a Terraform module for an ECR repository and an ECS service",
12
+ "Review this Dockerfile and the Helm chart for security problems before we ship",
13
+ "Create a GitHub Actions workflow that runs the tests on every pull request",
14
+ "Roll back the payments deployment in the cluster to the previous ReplicaSet"
15
+ ]
16
+ }
@@ -0,0 +1,105 @@
1
+ # Dockerfile templates
2
+
3
+ Starting points. Adjust versions, paths and commands to the project; don't paste blindly.
4
+
5
+ ## Node.js (npm)
6
+
7
+ ```dockerfile
8
+ # syntax=docker/dockerfile:1
9
+ FROM node:22-bookworm-slim AS deps
10
+ WORKDIR /app
11
+ COPY package.json package-lock.json ./
12
+ RUN --mount=type=cache,target=/root/.npm npm ci
13
+
14
+ FROM deps AS build
15
+ COPY . .
16
+ RUN npm run build && npm prune --omit=dev
17
+
18
+ FROM node:22-bookworm-slim
19
+ ENV NODE_ENV=production
20
+ WORKDIR /app
21
+ COPY --from=build --chown=node:node /app/node_modules ./node_modules
22
+ COPY --from=build --chown=node:node /app/dist ./dist
23
+ COPY --chown=node:node package.json ./
24
+ USER node
25
+ EXPOSE 3000
26
+ CMD ["node", "dist/server.js"]
27
+ ```
28
+
29
+ ## Python (pip)
30
+
31
+ ```dockerfile
32
+ # syntax=docker/dockerfile:1
33
+ FROM python:3.12-slim AS build
34
+ WORKDIR /app
35
+ RUN python -m venv /opt/venv
36
+ ENV PATH=/opt/venv/bin:$PATH
37
+ COPY requirements.txt .
38
+ RUN --mount=type=cache,target=/root/.cache/pip pip install -r requirements.txt
39
+
40
+ FROM python:3.12-slim
41
+ ENV PATH=/opt/venv/bin:$PATH PYTHONUNBUFFERED=1 PYTHONDONTWRITEBYTECODE=1
42
+ RUN useradd --create-home --uid 10001 app
43
+ WORKDIR /app
44
+ COPY --from=build /opt/venv /opt/venv
45
+ COPY --chown=app:app . .
46
+ USER app
47
+ EXPOSE 8000
48
+ CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app.wsgi:application"]
49
+ ```
50
+
51
+ ## Go (static binary)
52
+
53
+ ```dockerfile
54
+ # syntax=docker/dockerfile:1
55
+ FROM golang:1.23 AS build
56
+ WORKDIR /src
57
+ COPY go.mod go.sum ./
58
+ RUN --mount=type=cache,target=/go/pkg/mod go mod download
59
+ COPY . .
60
+ RUN --mount=type=cache,target=/go/pkg/mod --mount=type=cache,target=/root/.cache/go-build \
61
+ CGO_ENABLED=0 go build -trimpath -ldflags="-s -w" -o /out/app ./cmd/app
62
+
63
+ FROM gcr.io/distroless/static-debian12:nonroot
64
+ COPY --from=build /out/app /app
65
+ USER nonroot:nonroot
66
+ EXPOSE 8080
67
+ ENTRYPOINT ["/app"]
68
+ ```
69
+
70
+ ## Java (Maven, Spring Boot style fat jar)
71
+
72
+ ```dockerfile
73
+ # syntax=docker/dockerfile:1
74
+ FROM eclipse-temurin:21-jdk AS build
75
+ WORKDIR /src
76
+ COPY pom.xml mvnw ./
77
+ COPY .mvn .mvn
78
+ RUN --mount=type=cache,target=/root/.m2 ./mvnw -q dependency:go-offline
79
+ COPY src src
80
+ RUN --mount=type=cache,target=/root/.m2 ./mvnw -q package -DskipTests
81
+
82
+ FROM eclipse-temurin:21-jre
83
+ RUN useradd --uid 10001 app
84
+ WORKDIR /app
85
+ COPY --from=build /src/target/*.jar app.jar
86
+ USER app
87
+ EXPOSE 8080
88
+ ENTRYPOINT ["java", "-jar", "/app/app.jar"]
89
+ ```
90
+
91
+ ## Build-time secret example
92
+
93
+ ```dockerfile
94
+ RUN --mount=type=secret,id=npmrc,target=/root/.npmrc npm ci
95
+ ```
96
+
97
+ ```sh
98
+ docker build --secret id=npmrc,src=$HOME/.npmrc -t app:dev .
99
+ ```
100
+
101
+ ## Notes
102
+
103
+ - `# syntax=docker/dockerfile:1` opts into the current stable Dockerfile frontend, which `--mount` needs on older engines.
104
+ - Version tags above are examples. Use the versions the project already targets.
105
+ - A distroless or `scratch` image has no shell: `docker exec ... sh` won't work, and a `HEALTHCHECK` needs a binary you add yourself.
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: e2e-testing-playwright
3
+ description: Writes and maintains Playwright Test end-to-end suites for web apps, using role-based locators, web-first assertions that auto-wait, saved storageState for login, page.route network mocks, isolated per-test data, traces for flaky runs and a sharded CI job. Use when adding or fixing browser end-to-end tests with Playwright, setting up playwright.config, or making an existing Playwright suite reliable in CI.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. Needs Node 18+ and the project's package manager; browsers install with npx playwright install.
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: testing
9
+ kete-loom/risk: runs-commands
10
+ kete-loom/requires: "node, npx"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # End-to-end testing with Playwright
15
+
16
+ An end-to-end test drives the real app through a real browser, the way a user would. It is slow and costly to maintain, so write few of them, for the journeys that make money or lose data, and make each one deterministic.
17
+
18
+ ## 0. Before you start
19
+
20
+ 1. Look for an existing setup: `playwright.config.ts`, an `e2e/` or `tests/` folder, `@playwright/test` in `package.json`. Follow its conventions (folder, fixtures, naming, base URL) instead of creating a parallel setup.
21
+ 2. If there is none, run `npm init playwright@latest` (or the project's package manager equivalent) and accept TypeScript. Then read `references/config-and-ci.md` for a config to start from.
22
+ 3. Find out how the app starts locally and what test data it needs. If the app needs a database or third-party sandbox you cannot reach, **stop and ask the user** how they want it provided.
23
+ 4. Run the existing suite once (`npx playwright test`) and record the result before changing anything.
24
+
25
+ ## 1. Choose what to cover
26
+
27
+ - List the critical journeys: sign up, log in, the core create/edit flow, checkout or payment, anything with irreversible effects.
28
+ - One test per journey outcome. Cover the happy path plus the one or two failure paths a user really hits (invalid card, expired session).
29
+ - Push everything else down: validation rules, formatting and edge cases belong in unit or component tests.
30
+
31
+ ## 2. Locators: how a user finds things
32
+
33
+ Use, in order of preference:
34
+
35
+ 1. `page.getByRole('button', { name: 'Save' })`: role plus accessible name.
36
+ 2. `page.getByLabel('Email')`, `getByPlaceholder`, `getByText`, `getByAltText`, `getByTitle`.
37
+ 3. `page.getByTestId('cart-total')`: only when there is no user-facing handle. The attribute defaults to `data-testid` (change it with `use.testIdAttribute`).
38
+
39
+ Never use CSS chains tied to layout (`div > div:nth-child(3)`), generated class names, or XPath. Narrow with `locator.filter({ hasText })` or by chaining from a parent region (`page.getByRole('dialog').getByRole('button', { name: 'Confirm' })`). If a role locator can't find an element, the element is probably inaccessible: report that, don't paper over it with a test id.
40
+
41
+ ## 3. Waiting: never sleep
42
+
43
+ - Actions (`click`, `fill`, `check`) wait for the element to be visible, stable, enabled and able to receive events.
44
+ - Assert with web-first assertions that retry until timeout: `await expect(locator).toBeVisible()`, `toHaveText`, `toHaveValue`, `toHaveURL`, `toHaveCount`.
45
+ - Never write `page.waitForTimeout(...)` or a fixed sleep. Never `expect(await locator.textContent()).toBe(...)`: that reads once and does not retry.
46
+ - For a non-DOM condition, use `await expect.poll(() => fetchStatus()).toBe('done')`.
47
+ - To wait for a specific request, start `page.waitForResponse(...)` before the action that triggers it.
48
+
49
+ ## 4. Isolation and data
50
+
51
+ - Each test gets a fresh browser context: no shared cookies or storage. Keep it that way; never make test B depend on test A.
52
+ - Create the data a test needs in the test (through the app's API with the `request` fixture, or a seed helper), with unique values (`order-${test.info().testId}` or a random suffix), so tests can run in parallel and on retry.
53
+ - Clean up in fixture teardown, or use a disposable database per run. Never point tests at production.
54
+ - Put shared setup in custom fixtures with `test.extend`, not in `beforeAll` blocks that leak state.
55
+
56
+ ## 5. Authentication
57
+
58
+ Log in once and reuse the state. Use a setup project that logs in through the UI, waits for proof of login, and saves `page.context().storageState({ path: 'playwright/.auth/user.json' })`; testing projects set `dependencies: ['setup']` and `use: { storageState: 'playwright/.auth/user.json' }`. Add `playwright/.auth` to `.gitignore`: it holds live cookies. For several roles, save one file per role. Tests of the login form itself start with an empty state: `test.use({ storageState: { cookies: [], origins: [] } })`.
59
+
60
+ ## 6. Network mocking
61
+
62
+ Mock only what you don't own or can't control (payment provider, maps, flaky third parties, rare error responses):
63
+
64
+ ```ts
65
+ await page.route('**/api/rates', route =>
66
+ route.fulfill({ status: 503, json: { error: 'unavailable' } }));
67
+ ```
68
+
69
+ - Use `route.fulfill` for canned responses, `route.abort()` to simulate network failure, `route.continue()` to modify a request in flight.
70
+ - Keep at least one unmocked journey against your own backend, or the suite proves nothing about integration.
71
+ - For larger fixtures, record a HAR with `page.routeFromHAR(path, { update: true })` once and replay it.
72
+
73
+ ## 7. Flaky tests
74
+
75
+ 1. Reproduce: `npx playwright test path/to/spec.ts --repeat-each=20 --workers=4`.
76
+ 2. Read the trace: config `trace: 'on-first-retry'` (or `--trace on`), then `npx playwright show-trace <trace.zip>`. Check the action log, DOM snapshots, network and console at the failing step.
77
+ 3. Fix the cause: a missing web-first assertion, shared data, an animation, a race with a request, an un-awaited promise. Retries hide flakiness; they don't fix it.
78
+ 4. In CI, `--fail-on-flaky-tests` turns "passed on retry" into a failure when the team wants zero tolerance.
79
+
80
+ ## 8. CI
81
+
82
+ Run with retries 2 and 1 worker per shard on CI, upload the HTML report and traces as artifacts, and shard with `--shard=1/4` for large suites. A ready workflow and config are in `references/config-and-ci.md`.
83
+
84
+ ## Rules
85
+
86
+ - Never commit `test.only` (set `forbidOnly: !!process.env.CI`).
87
+ - Never add a sleep, a raw `setTimeout`, or a huge timeout to make a test pass.
88
+ - Never weaken or delete an assertion to get green; find out why it failed.
89
+ - Never put real credentials in test files; read them from environment variables.
90
+ - Visual snapshots (`toHaveScreenshot`) only for stable, important screens, generated on the same OS and browser as CI.
91
+
92
+ ## Report back
93
+
94
+ End with: tests added or changed (file and title), the exact command run, pass/fail/flaky counts, and anything not covered (for example "payment provider mocked, real sandbox not exercised").
@@ -0,0 +1,16 @@
1
+ {
2
+ "should_trigger": [
3
+ "Write a Playwright test for the signup and onboarding flow",
4
+ "Our Playwright tests keep logging in through the UI before every test, make them reuse the session",
5
+ "Set up Playwright in this Next.js repo and add an e2e test for checkout, with a GitHub Actions job",
6
+ "Mock the exchange-rate API in my Playwright spec so I can test the error banner",
7
+ "Replace the waitForTimeout calls in our playwright specs with proper assertions"
8
+ ],
9
+ "should_not_trigger": [
10
+ "Click through the staging site and tell me what's broken before the demo",
11
+ "The nightly end-to-end run failed again, figure out whether it's the app or the tests and stabilise it",
12
+ "Look at the tests in this pull request and tell me which cases are missing",
13
+ "Write unit tests for the price formatting helper with Vitest",
14
+ "Our coverage is 41%, help me add tests where it actually matters"
15
+ ]
16
+ }
@@ -0,0 +1,129 @@
1
+ # Playwright config and CI
2
+
3
+ Read this when creating or reworking `playwright.config.ts` or the CI job. Check option names against playwright.dev/docs/test-configuration for the installed version.
4
+
5
+ ## Starting config
6
+
7
+ ```ts
8
+ import { defineConfig, devices } from '@playwright/test';
9
+
10
+ export default defineConfig({
11
+ testDir: './e2e',
12
+ fullyParallel: true,
13
+ forbidOnly: !!process.env.CI,
14
+ retries: process.env.CI ? 2 : 0,
15
+ workers: process.env.CI ? 1 : undefined,
16
+ reporter: process.env.CI ? [['html', { open: 'never' }], ['github']] : 'html',
17
+ use: {
18
+ baseURL: process.env.BASE_URL ?? 'http://localhost:3000',
19
+ trace: 'on-first-retry',
20
+ screenshot: 'only-on-failure',
21
+ },
22
+ projects: [
23
+ { name: 'setup', testMatch: /.*\.setup\.ts/ },
24
+ {
25
+ name: 'chromium',
26
+ use: { ...devices['Desktop Chrome'], storageState: 'playwright/.auth/user.json' },
27
+ dependencies: ['setup'],
28
+ },
29
+ ],
30
+ webServer: {
31
+ command: 'npm run start',
32
+ url: 'http://localhost:3000',
33
+ reuseExistingServer: !process.env.CI,
34
+ },
35
+ });
36
+ ```
37
+
38
+ Add Firefox, WebKit or mobile projects (`devices['Pixel 7']`, `devices['iPhone 15']`) only when the product supports them; each project multiplies run time.
39
+
40
+ ## Auth setup file
41
+
42
+ ```ts
43
+ // e2e/auth.setup.ts
44
+ import { test as setup, expect } from '@playwright/test';
45
+
46
+ const authFile = 'playwright/.auth/user.json';
47
+
48
+ setup('authenticate', async ({ page }) => {
49
+ await page.goto('/login');
50
+ await page.getByLabel('Email').fill(process.env.E2E_USER!);
51
+ await page.getByLabel('Password').fill(process.env.E2E_PASSWORD!);
52
+ await page.getByRole('button', { name: 'Sign in' }).click();
53
+ await expect(page.getByRole('button', { name: 'Account' })).toBeVisible();
54
+ await page.context().storageState({ path: authFile });
55
+ });
56
+ ```
57
+
58
+ ## Custom fixture
59
+
60
+ ```ts
61
+ // e2e/fixtures.ts
62
+ import { test as base } from '@playwright/test';
63
+
64
+ type Fixtures = { project: { id: string; name: string } };
65
+
66
+ export const test = base.extend<Fixtures>({
67
+ project: async ({ request }, use, testInfo) => {
68
+ const name = `e2e-${testInfo.testId}`;
69
+ const res = await request.post('/api/projects', { data: { name } });
70
+ const project = await res.json();
71
+ await use(project);
72
+ await request.delete(`/api/projects/${project.id}`);
73
+ },
74
+ });
75
+ export { expect } from '@playwright/test';
76
+ ```
77
+
78
+ ## GitHub Actions with sharding
79
+
80
+ ```yaml
81
+ name: e2e
82
+ on: [push, pull_request]
83
+ jobs:
84
+ e2e:
85
+ runs-on: ubuntu-latest
86
+ timeout-minutes: 30
87
+ strategy:
88
+ fail-fast: false
89
+ matrix:
90
+ shard: [1/4, 2/4, 3/4, 4/4]
91
+ steps:
92
+ - uses: actions/checkout@v4
93
+ - uses: actions/setup-node@v4
94
+ with:
95
+ node-version: 20
96
+ cache: npm
97
+ - run: npm ci
98
+ - run: npx playwright install --with-deps
99
+ - run: npx playwright test --shard=${{ matrix.shard }}
100
+ env:
101
+ E2E_USER: ${{ secrets.E2E_USER }}
102
+ E2E_PASSWORD: ${{ secrets.E2E_PASSWORD }}
103
+ - uses: actions/upload-artifact@v4
104
+ if: ${{ !cancelled() }}
105
+ with:
106
+ name: playwright-report-${{ strategy.job-index }}
107
+ path: |
108
+ playwright-report/
109
+ test-results/
110
+ retention-days: 14
111
+ ```
112
+
113
+ To combine shard reports into one, use the `blob` reporter on CI and `npx playwright merge-reports --reporter html ./all-blob-reports` in a follow-up job.
114
+
115
+ ## Useful commands
116
+
117
+ | Goal | Command |
118
+ |---|---|
119
+ | Run one file | `npx playwright test e2e/checkout.spec.ts` |
120
+ | Run by title | `npx playwright test -g "applies coupon"` |
121
+ | Debug step by step | `npx playwright test --debug` |
122
+ | Interactive runner | `npx playwright test --ui` |
123
+ | Re-run last failures | `npx playwright test --last-failed` |
124
+ | Stress a test | `npx playwright test e2e/x.spec.ts --repeat-each=20` |
125
+ | Open a trace | `npx playwright show-trace test-results/.../trace.zip` |
126
+ | Open the report | `npx playwright show-report` |
127
+ | Record a draft test | `npx playwright codegen http://localhost:3000` |
128
+
129
+ Treat `codegen` output as a draft: replace its locators with role-based ones and add assertions.
@@ -0,0 +1,117 @@
1
+ ---
2
+ name: ef-core-patterns
3
+ description: Entity Framework Core data-access rules for .NET - scoped DbContext lifetime, pooling and IDbContextFactory, AsNoTracking for read paths, LINQ that translates to SQL instead of throwing or evaluating on the client, projections, Include versus AsSplitQuery for N+1 and cartesian explosion, ExecuteUpdate and ExecuteDelete for bulk writes, safe dotnet ef migrations and idempotent scripts, and optimistic concurrency with row versions. Use when writing or reviewing EF Core queries or DbContext setup, fixing slow or untranslatable LINQ, adding or deploying an EF Core migration, or handling DbUpdateConcurrencyException.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. Needs the .NET SDK and the dotnet-ef tool for migrations. Written for EF Core 8 and later.
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: coding
9
+ kete-loom/risk: runs-commands
10
+ kete-loom/requires: "dotnet"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # EF Core patterns
15
+
16
+ Use EF Core so every query is one you would have written by hand, and every write is safe under concurrency. For the web host around it follow `aspnet-core-patterns`; for engine-specific SQL tuning follow `postgres-patterns` or `mysql-patterns`.
17
+
18
+ ## 0. Before you change anything
19
+
20
+ 1. Read the `Microsoft.EntityFrameworkCore.*` package versions and the provider (SqlServer, Npgsql, Sqlite, Pomelo MySQL). Behaviour differs by provider.
21
+ 2. Turn on SQL logging locally so you can see what each query does:
22
+ ```csharp
23
+ options.UseNpgsql(cs).LogTo(Console.WriteLine, LogLevel.Information)
24
+ .EnableSensitiveDataLogging(env.IsDevelopment());
25
+ ```
26
+ 3. Run `dotnet test`. If it fails before you start, **stop and tell the user**.
27
+
28
+ ## 1. DbContext lifetime
29
+
30
+ - Web apps: `AddDbContext<AppDbContext>` registers it **scoped**, one per request. For hot paths, `AddDbContextPool<AppDbContext>` reuses instances; pooled contexts must not hold per-request state in fields.
31
+ - Singletons, background services, Blazor Server components and parallel work: inject `IDbContextFactory<AppDbContext>` (`AddDbContextFactory`) and `await using var db = await factory.CreateDbContextAsync(ct);`.
32
+ - A `DbContext` is not thread-safe. Never run two queries on the same context at once (`Task.WhenAll` over one context throws). Use separate contexts.
33
+ - Keep a context short-lived. A long-lived context's change tracker grows and serves stale data.
34
+
35
+ ## 2. Tracking vs no-tracking
36
+
37
+ | Path | Use |
38
+ |---|---|
39
+ | Read-only list or detail | `AsNoTracking()` or a `Select` projection |
40
+ | Read then update the same entities | Tracking (default), then `SaveChangesAsync` |
41
+ | Read-only with repeated references you need deduplicated | `AsNoTrackingWithIdentityResolution()` |
42
+
43
+ - Set `UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking)` on the context only if the whole codebase is read-heavy and every update path re-attaches explicitly. Otherwise opt in per query.
44
+ - Projections (`Select(o => new OrderDto(...))`) are never tracked and fetch only the columns used. Prefer them for APIs.
45
+
46
+ ## 3. Query translation pitfalls
47
+
48
+ 1. Keep the query `IQueryable` until the end. `ToList()`, `AsEnumerable()` or `IEnumerable<T>` parameters in the middle pull every row into memory and filter in C#.
49
+ 2. Methods EF can't translate (your own C# helpers, most string formatting, complex `GroupBy` shapes) throw `InvalidOperationException: ... could not be translated`. Rewrite with translatable operators, move the logic to after a projection that already limits rows, or use `FromSql` with parameters.
50
+ 3. Client evaluation is allowed only in the final `Select`. Don't rely on it for filtering.
51
+ 4. `string.Equals(a, b, StringComparison.OrdinalIgnoreCase)` usually doesn't translate; use the column's collation, `EF.Functions.ILike` (Npgsql) or `EF.Functions.Like`.
52
+ 5. `Contains` over a local list becomes `IN` or a parameterised array; keep lists bounded.
53
+ 6. Raw SQL: `FromSql($"... WHERE id = {id}")` and `ExecuteSql($"...")` parameterise interpolated values. `FromSqlRaw` / `ExecuteSqlRaw` with string concatenation is SQL injection.
54
+ 7. Always `await` the async operators (`ToListAsync`, `FirstOrDefaultAsync`, `SaveChangesAsync`) and pass the `CancellationToken`.
55
+ 8. Paginate with `OrderBy` then `Skip`/`Take` (or keyset `Where(x => x.Id > lastId)` for deep pages). `Skip` without `OrderBy` gives unstable pages.
56
+
57
+ ## 4. N+1, Include and split queries
58
+
59
+ - Lazy loading proxies make N+1s invisible. If the project has `UseLazyLoadingProxies()`, don't add more reliance on it; load explicitly.
60
+ - Load what you need: `Include(o => o.Lines).ThenInclude(l => l.Product)`, or better, a projection that selects just the fields.
61
+ - Several collection `Include`s in one query cause cartesian explosion (rows multiply). EF warns about this. Use `AsSplitQuery()` on that query, or `UseQuerySplittingBehavior(QuerySplittingBehavior.SplitQuery)` globally with `AsSingleQuery()` where you need one round trip.
62
+ - Split queries are not one snapshot: data can change between them. Use a transaction with a suitable isolation level when consistency matters, and always `OrderBy` before `Skip`/`Take` with split queries.
63
+ - Filtered include: `Include(o => o.Lines.Where(l => !l.Cancelled))`.
64
+
65
+ ## 5. Writes
66
+
67
+ - Bulk changes without loading: `ExecuteUpdateAsync(s => s.SetProperty(o => o.Status, OrderStatus.Archived), ct)` and `ExecuteDeleteAsync(ct)`. They bypass the change tracker, interceptors that hook `SaveChanges`, and concurrency checks. Say so when you use them.
68
+ - One `SaveChangesAsync` per unit of work; it runs in a transaction. Use `await using var tx = await db.Database.BeginTransactionAsync(ct);` only when you span several `SaveChanges` or raw SQL.
69
+ - With retrying execution strategies (`EnableRetryOnFailure`), wrap manual transactions in `db.Database.CreateExecutionStrategy().ExecuteAsync(...)`.
70
+
71
+ ## 6. Concurrency tokens
72
+
73
+ ```csharp
74
+ // SQL Server rowversion
75
+ [Timestamp] public byte[] RowVersion { get; set; } = [];
76
+ // Any provider: an app-managed token
77
+ modelBuilder.Entity<Account>().Property(a => a.Version).IsConcurrencyToken();
78
+ // Npgsql: a uint property marked as row version maps to the xmin system column
79
+ public uint Version { get; set; }
80
+ modelBuilder.Entity<Account>().Property(a => a.Version).IsRowVersion();
81
+ ```
82
+
83
+ - Handle `DbUpdateConcurrencyException`: reload the entry (`entry.GetDatabaseValuesAsync()`), then retry, merge or return 409 to the client. Never catch and ignore it.
84
+ - APIs send the token to the client (ETag or a field) and require it on update, so stale writes are rejected.
85
+ - An app-managed token must be changed on every update (for example `Version = Guid.NewGuid()` or an incremented int).
86
+
87
+ ## 7. Migrations
88
+
89
+ 1. Create: `dotnet ef migrations add AddInvoiceTable` (add `--project` / `--startup-project` when the context lives in another project).
90
+ 2. **Read the generated migration.** EF can scaffold a rename as drop plus add; edit it to `RenameColumn` when that happens. Check for data loss before you commit it.
91
+ 3. Never edit a migration that has been applied in a shared environment; add a new one.
92
+ 4. Deploy with an idempotent script or a bundle, reviewed and run by the pipeline:
93
+ ```
94
+ dotnet ef migrations script --idempotent -o migrate.sql
95
+ dotnet ef migrations bundle --self-contained
96
+ ```
97
+ Prefer this over `Database.Migrate()` at app startup in production: startup migration needs schema rights for the app identity and gives no review step. Before EF Core 9, several instances migrating at once could also race; EF Core 9+ takes a database-wide lock but SQL scripts do not.
98
+ Add `dotnet ef migrations has-pending-model-changes` to CI (EF Core 8+) so a model change without a migration fails the build.
99
+ 5. Large tables: add nullable columns, backfill in batches, then make them required in a later migration. Raw SQL for things EF can't express (`migrationBuilder.Sql(...)`, for example concurrent index creation on PostgreSQL with the transaction suppressed).
100
+ 6. Keep the model snapshot in source control and resolve merge conflicts in it by re-adding the migration, not by hand-merging.
101
+
102
+ ## Stop and ask the user
103
+
104
+ - Before a migration that drops or renames a column or table with data.
105
+ - Before turning on global no-tracking, global split queries or lazy loading.
106
+ - Before running migrations against any non-local database.
107
+
108
+ ## Never
109
+
110
+ - Never register `DbContext` as a singleton or share one across threads.
111
+ - Never build SQL with string concatenation in `FromSqlRaw` / `ExecuteSqlRaw`.
112
+ - Never `ToList()` a table to filter it in memory.
113
+ - Never swallow `DbUpdateConcurrencyException`.
114
+
115
+ ## Finish
116
+
117
+ Run `dotnet test` and look at the logged SQL for each query you changed. Report: queries changed with before/after query counts, migrations added and whether they lose data, and concurrency handling added.
@@ -0,0 +1,16 @@
1
+ {
2
+ "should_trigger": [
3
+ "My EF Core LINQ query throws 'could not be translated' when I call my own helper in Where",
4
+ "Loading orders with Include on lines and payments returns millions of rows in EF Core, should I use AsSplitQuery?",
5
+ "Two admins edit the same account and the last save wins, add optimistic concurrency with EF Core",
6
+ "How do I deploy dotnet ef migrations to production without calling Database.Migrate at startup?",
7
+ "Should this read-only EF Core endpoint use AsNoTracking or a projection?"
8
+ ],
9
+ "should_not_trigger": [
10
+ "Our ASP.NET Core middleware order breaks authentication, fix Program.cs",
11
+ "Refactor this C# service to use records and pattern matching",
12
+ "Write a Prisma migration for the new invoices table",
13
+ "This PostgreSQL index isn't being used for the orders query, read the EXPLAIN output",
14
+ "Configure Hibernate second-level cache for our Spring Boot JPA entities"
15
+ ]
16
+ }
@@ -0,0 +1,99 @@
1
+ ---
2
+ name: email-deliverability
3
+ description: Gets email into the inbox instead of spam by setting up SPF, DKIM, DMARC and BIMI DNS records with alignment, splitting transactional and marketing mail onto separate subdomains and streams, choosing a sending provider, processing bounces and complaints, keeping lists clean and warming a new domain or IP. Use when mail lands in spam or bounces, a domain needs authenticating before sending, Gmail, Yahoo or Outlook bulk-sender rules must be met, or a new sending domain is about to go live.
4
+ license: MIT
5
+ compatibility: Any Agent Skills host. DNS checks use dig or nslookup; header checks need a raw message (.eml) or the provider's logs. Changes are made in the user's DNS host and email provider.
6
+ metadata:
7
+ kete-loom/version: "0.1.0"
8
+ kete-loom/category: business
9
+ kete-loom/risk: network
10
+ kete-loom/requires: "dig"
11
+ kete-loom/owner: "Kete-org"
12
+ ---
13
+
14
+ # Email deliverability
15
+
16
+ Make mail provably come from the domain it claims, keep receipts and password resets away from the reputation of newsletters, and stop sending to people who bounce, complain or never engage.
17
+
18
+ ## Ground rules
19
+
20
+ 1. **Authenticate every sending domain** with SPF and DKIM, then DMARC. Gmail requires SPF or DKIM for everyone, and SPF, DKIM and DMARC (`p=none` allowed) for anyone sending more than 5,000 messages a day to personal Gmail accounts. Outlook.com (hotmail.com, live.com, outlook.com) requires SPF and DKIM to pass and DMARC to pass with alignment (`p=none` allowed) for senders of 5,000 or more messages from one `From:` domain, and rejects failures with `550 5.7.515`.
21
+ 2. **Alignment is what DMARC checks**: the `From:` domain must match the DKIM `d=` domain or the SPF (Return-Path) domain. A provider signing with its own domain passes DKIM but fails DMARC. Use custom DKIM and a custom return-path on your domain.
22
+ 3. **Separate streams.** Transactional mail (receipts, resets, alerts) and marketing mail use different subdomains (for example `mail.example.com` and `news.example.com`) and, where the provider supports it, different streams or IP pools. A bad campaign must never delay a password reset.
23
+ 4. **Never buy, rent or scrape lists** for marketing mail. Purchased lists contain spam traps and drive complaints; no technical setup fixes that.
24
+ 5. **Marketing mail needs one-click unsubscribe**: a `List-Unsubscribe` header with an HTTPS URL, `List-Unsubscribe-Post: List-Unsubscribe=One-Click` (RFC 8058), and a visible link in the body. Honour it quickly (Google says within 48 hours; US CAN-SPAM allows at most 10 business days).
25
+ 6. **Watch the complaint rate.** Keep Gmail's user-reported spam rate in Postmaster Tools under 0.1% and never let it reach 0.3%.
26
+ 7. **Change DNS carefully.** Read the existing records before editing. A second SPF record, or a DMARC jump to `p=reject` before every sender is aligned, breaks real mail.
27
+
28
+ ## Diagnose first
29
+
30
+ When the user says "our emails go to spam", collect before changing anything:
31
+
32
+ 1. The exact `From:` address, the provider(s) that send for that domain (app, marketing tool, CRM, helpdesk, Google Workspace or Microsoft 365), and daily volume per stream.
33
+ 2. Current records: `dig +short TXT example.com` (SPF), `dig +short TXT _dmarc.example.com`, `dig +short TXT <selector>._domainkey.example.com`, `dig +short MX example.com`.
34
+ 3. Raw headers of one message that landed in spam. Read `Authentication-Results:` for `spf=`, `dkim=`, `dmarc=` and the domains each checked.
35
+ 4. Data from Google Postmaster Tools and Microsoft SNDS if set up, plus the provider's bounce and complaint numbers.
36
+
37
+ Then decide:
38
+
39
+ | Finding | Fix |
40
+ |---|---|
41
+ | `dmarc=fail` with `dkim=pass` | DKIM signed by the provider's domain; set up custom DKIM on yours |
42
+ | `spf=permerror` | More than 10 DNS lookups or two SPF records; merge and flatten (`references/dns-records.md`) |
43
+ | All auth passes, still spam | Reputation or content: check complaint rate, list source, engagement, sudden volume jumps |
44
+ | Bounces with `5.7.x` codes | Policy rejection: authentication or reputation; read the bounce text, it usually names the rule |
45
+ | Only one mailbox provider affected | Check that provider's postmaster tools and its own requirements |
46
+
47
+ ## Set up a sending domain
48
+
49
+ 1. Choose subdomains per stream. List every service that will send as each one.
50
+ 2. Add the provider's DKIM records (2048-bit keys where offered; Gmail requires at least 1024) and its custom return-path or bounce domain (a CNAME or MX record).
51
+ 3. Publish one SPF record per domain name that sends, including only the services that use it: `v=spf1 include:<provider> ~all`. Record shapes in `references/dns-records.md`.
52
+ 4. Publish DMARC at `p=none` with an aggregate report address: `v=DMARC1; p=none; rua=mailto:dmarc@example.com`. Read the reports for a few weeks (2 to 4 is a common rule of thumb) to find every legitimate sender.
53
+ 5. Move to `p=quarantine`, then `p=reject` once reports show all real mail aligned. **Stop and ask the user** before each step.
54
+ 6. BIMI only after DMARC is at `quarantine` or `reject`; it needs an SVG Tiny PS logo and, for Gmail, a mark certificate (a VMC, or a CMC for a logo that is not trademarked). Other mailbox providers, including Apple Mail, set their own BIMI rules; check the provider's current documentation before buying a certificate. Treat it as a branding extra, not a deliverability fix.
55
+ 7. Set valid forward and reverse DNS (PTR) if you run your own sending IPs; hosted providers do this for you.
56
+
57
+ ## Choose a provider
58
+
59
+ - Transactional: a provider with a dedicated transactional stream, webhooks for bounces and complaints, and per-message logs (for example Postmark, Amazon SES, SendGrid, Mailgun, Resend).
60
+ - Marketing: a tool that handles consent, unsubscribes, suppression lists and one-click headers for you.
61
+ - Shared IPs are right under roughly tens of thousands of messages a month; a dedicated IP needs steady volume to build a reputation. Ask the user for volume before recommending one.
62
+ - Never send bulk mail through a personal Google Workspace or Microsoft 365 mailbox.
63
+
64
+ ## Bounces, complaints and list hygiene
65
+
66
+ 1. Subscribe to the provider's bounce and complaint webhooks (or SES notifications) and write them to a suppression table keyed by address.
67
+ 2. Hard bounce (`5.x.x`, unknown user): suppress immediately and permanently.
68
+ 3. Soft bounce (`4.x.x`, mailbox full, throttled): retry per the provider; suppress after repeated failures across several sends.
69
+ 4. Complaint (feedback loop, "report spam"): suppress from all marketing at once; it counts as an unsubscribe.
70
+ 5. Check suppression before every send, across every tool that mails the same domain.
71
+ 6. Use confirmed opt-in for sign-ups from public forms. Sunset marketing contacts with no opens or clicks for a long stretch (6 to 12 months is a common rule of thumb, not a provider rule) after a re-engagement attempt (opens are unreliable since Apple Mail Privacy Protection, so weight clicks).
72
+
73
+ ## Warm a new domain or IP
74
+
75
+ 1. Start with the most engaged recipients (recent sign-ups, active customers), not the whole list.
76
+ 2. Grow volume gradually, roughly doubling while bounce and complaint rates stay low; hold or drop back if they rise. Two to six weeks is a common rule of thumb, not a mailbox-provider rule; follow the sending provider's warm-up plan if it has one.
77
+ 3. Keep volume and timing steady; avoid one huge blast after weeks of silence.
78
+ 4. Send transactional mail from day one; it is high-engagement and builds reputation.
79
+
80
+ ## Never
81
+
82
+ - Publish two SPF TXT records, or use `+all`.
83
+ - Put a DMARC record at `p=reject` without reading reports first.
84
+ - Hide or break the unsubscribe link, or require login to unsubscribe.
85
+ - Re-import suppressed or bounced addresses into another tool.
86
+ - Rotate domains or IPs to escape a bad reputation ("snowshoeing").
87
+
88
+ ## Report format
89
+
90
+ ```
91
+ Domain(s): ... Streams: transactional / marketing
92
+ Auth status: SPF pass|fail (lookups n/10) DKIM aligned yes|no DMARC p=...
93
+ Main problem: one sentence
94
+ Fixes, in order: 1. ... (DNS record or setting, exact value) 2. ...
95
+ Needs user decision: ...
96
+ Re-test: send to a seed list and read Authentication-Results
97
+ ```
98
+
99
+ Mailbox-provider rules change. Check Google's and Yahoo's sender guidelines and Microsoft's Outlook sender requirements before stating a threshold as current; links are in `references/dns-records.md`.
@@ -0,0 +1,17 @@
1
+ {
2
+ "should_trigger": [
3
+ "Our password reset emails keep landing in Gmail spam, here are the headers showing dmarc=fail",
4
+ "Set up SPF, DKIM and DMARC for our new sending domain before we turn on Amazon SES",
5
+ "SPF check says permerror too many DNS lookups, how do I fix the record?",
6
+ "We send 20k newsletters a day, what do we need for the Gmail and Yahoo bulk sender requirements?",
7
+ "Plan a warm-up schedule for the brand new domain we bought for product emails",
8
+ "How should we handle hard bounces and spam complaints coming back from Postmark webhooks?"
9
+ ],
10
+ "should_not_trigger": [
11
+ "Write a five-step cold email sequence for CFOs at logistics companies",
12
+ "Turn our latest blog post into a weekly newsletter issue and three LinkedIn posts",
13
+ "Build the HTML template for our order confirmation email in React Email",
14
+ "Schedule our product announcement to post on X and LinkedIn via their APIs",
15
+ "Plan the launch campaign and channel budget for our new app"
16
+ ]
17
+ }