mindforge-cc 1.0.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 (324) hide show
  1. package/.agent/CLAUDE.md +462 -0
  2. package/.agent/forge/help.md +7 -0
  3. package/.agent/forge/init-project.md +32 -0
  4. package/.agent/forge/plan-phase.md +30 -0
  5. package/.agent/mindforge/approve.md +18 -0
  6. package/.agent/mindforge/audit.md +30 -0
  7. package/.agent/mindforge/benchmark.md +33 -0
  8. package/.agent/mindforge/complete-milestone.md +18 -0
  9. package/.agent/mindforge/debug.md +126 -0
  10. package/.agent/mindforge/discuss-phase.md +138 -0
  11. package/.agent/mindforge/execute-phase.md +165 -0
  12. package/.agent/mindforge/health.md +21 -0
  13. package/.agent/mindforge/help.md +23 -0
  14. package/.agent/mindforge/init-org.md +131 -0
  15. package/.agent/mindforge/init-project.md +155 -0
  16. package/.agent/mindforge/install-skill.md +15 -0
  17. package/.agent/mindforge/map-codebase.md +298 -0
  18. package/.agent/mindforge/metrics.md +22 -0
  19. package/.agent/mindforge/migrate.md +40 -0
  20. package/.agent/mindforge/milestone.md +12 -0
  21. package/.agent/mindforge/next.md +105 -0
  22. package/.agent/mindforge/plan-phase.md +125 -0
  23. package/.agent/mindforge/plugins.md +40 -0
  24. package/.agent/mindforge/pr-review.md +41 -0
  25. package/.agent/mindforge/profile-team.md +23 -0
  26. package/.agent/mindforge/publish-skill.md +19 -0
  27. package/.agent/mindforge/quick.md +135 -0
  28. package/.agent/mindforge/release.md +10 -0
  29. package/.agent/mindforge/retrospective.md +26 -0
  30. package/.agent/mindforge/review.md +157 -0
  31. package/.agent/mindforge/security-scan.md +233 -0
  32. package/.agent/mindforge/ship.md +100 -0
  33. package/.agent/mindforge/skills.md +141 -0
  34. package/.agent/mindforge/status.md +104 -0
  35. package/.agent/mindforge/sync-confluence.md +11 -0
  36. package/.agent/mindforge/sync-jira.md +12 -0
  37. package/.agent/mindforge/tokens.md +8 -0
  38. package/.agent/mindforge/update.md +42 -0
  39. package/.agent/mindforge/verify-phase.md +62 -0
  40. package/.agent/mindforge/workspace.md +29 -0
  41. package/.claude/CLAUDE.md +462 -0
  42. package/.claude/commands/forge/help.md +7 -0
  43. package/.claude/commands/forge/init-project.md +32 -0
  44. package/.claude/commands/forge/plan-phase.md +30 -0
  45. package/.claude/commands/mindforge/approve.md +18 -0
  46. package/.claude/commands/mindforge/audit.md +30 -0
  47. package/.claude/commands/mindforge/benchmark.md +33 -0
  48. package/.claude/commands/mindforge/complete-milestone.md +18 -0
  49. package/.claude/commands/mindforge/debug.md +126 -0
  50. package/.claude/commands/mindforge/discuss-phase.md +138 -0
  51. package/.claude/commands/mindforge/execute-phase.md +165 -0
  52. package/.claude/commands/mindforge/health.md +21 -0
  53. package/.claude/commands/mindforge/help.md +23 -0
  54. package/.claude/commands/mindforge/init-org.md +131 -0
  55. package/.claude/commands/mindforge/init-project.md +155 -0
  56. package/.claude/commands/mindforge/install-skill.md +15 -0
  57. package/.claude/commands/mindforge/map-codebase.md +298 -0
  58. package/.claude/commands/mindforge/metrics.md +22 -0
  59. package/.claude/commands/mindforge/migrate.md +40 -0
  60. package/.claude/commands/mindforge/milestone.md +12 -0
  61. package/.claude/commands/mindforge/next.md +105 -0
  62. package/.claude/commands/mindforge/plan-phase.md +125 -0
  63. package/.claude/commands/mindforge/plugins.md +40 -0
  64. package/.claude/commands/mindforge/pr-review.md +41 -0
  65. package/.claude/commands/mindforge/profile-team.md +23 -0
  66. package/.claude/commands/mindforge/publish-skill.md +19 -0
  67. package/.claude/commands/mindforge/quick.md +135 -0
  68. package/.claude/commands/mindforge/release.md +10 -0
  69. package/.claude/commands/mindforge/retrospective.md +26 -0
  70. package/.claude/commands/mindforge/review.md +157 -0
  71. package/.claude/commands/mindforge/security-scan.md +233 -0
  72. package/.claude/commands/mindforge/ship.md +100 -0
  73. package/.claude/commands/mindforge/skills.md +141 -0
  74. package/.claude/commands/mindforge/status.md +104 -0
  75. package/.claude/commands/mindforge/sync-confluence.md +11 -0
  76. package/.claude/commands/mindforge/sync-jira.md +12 -0
  77. package/.claude/commands/mindforge/tokens.md +8 -0
  78. package/.claude/commands/mindforge/update.md +42 -0
  79. package/.claude/commands/mindforge/verify-phase.md +62 -0
  80. package/.claude/commands/mindforge/workspace.md +29 -0
  81. package/.forge/org/CONVENTIONS.md +0 -0
  82. package/.forge/org/ORG.md +0 -0
  83. package/.forge/org/SECURITY.md +0 -0
  84. package/.forge/org/TOOLS.md +0 -0
  85. package/.forge/personas/analyst.md +0 -0
  86. package/.forge/personas/architect.md +0 -0
  87. package/.forge/personas/debug-specialist.md +0 -0
  88. package/.forge/personas/developer.md +26 -0
  89. package/.forge/personas/qa-engineer.md +0 -0
  90. package/.forge/personas/release-manager.md +0 -0
  91. package/.forge/personas/security-reviewer.md +33 -0
  92. package/.forge/personas/tech-writer.md +0 -0
  93. package/.forge/skills/api-design/SKILL.md +0 -0
  94. package/.forge/skills/code-quality/SKILL.md +0 -0
  95. package/.forge/skills/documentation/SKILL.md +0 -0
  96. package/.forge/skills/security-review/SKILL.md +23 -0
  97. package/.forge/skills/testing-standards/SKILL.md +27 -0
  98. package/.github/workflows/mindforge-ci.yml +224 -0
  99. package/.gitlab-ci-mindforge.yml +18 -0
  100. package/.mindforge/MINDFORGE-SCHEMA.json +165 -0
  101. package/.mindforge/audit/AUDIT-SCHEMA.md +451 -0
  102. package/.mindforge/ci/ci-config-schema.md +21 -0
  103. package/.mindforge/ci/ci-mode.md +179 -0
  104. package/.mindforge/ci/github-actions-adapter.md +224 -0
  105. package/.mindforge/ci/gitlab-ci-adapter.md +31 -0
  106. package/.mindforge/ci/jenkins-adapter.md +44 -0
  107. package/.mindforge/distribution/registry-client.md +166 -0
  108. package/.mindforge/distribution/registry-schema.md +96 -0
  109. package/.mindforge/distribution/skill-publisher.md +44 -0
  110. package/.mindforge/distribution/skill-validator.md +74 -0
  111. package/.mindforge/engine/compaction-protocol.md +182 -0
  112. package/.mindforge/engine/context-injector.md +128 -0
  113. package/.mindforge/engine/dependency-parser.md +113 -0
  114. package/.mindforge/engine/skills/conflict-resolver.md +69 -0
  115. package/.mindforge/engine/skills/loader.md +184 -0
  116. package/.mindforge/engine/skills/registry.md +98 -0
  117. package/.mindforge/engine/skills/versioning.md +75 -0
  118. package/.mindforge/engine/verification-pipeline.md +111 -0
  119. package/.mindforge/engine/wave-executor.md +235 -0
  120. package/.mindforge/governance/GOVERNANCE-CONFIG.md +17 -0
  121. package/.mindforge/governance/approval-workflow.md +37 -0
  122. package/.mindforge/governance/change-classifier.md +63 -0
  123. package/.mindforge/governance/compliance-gates.md +31 -0
  124. package/.mindforge/integrations/confluence.md +27 -0
  125. package/.mindforge/integrations/connection-manager.md +163 -0
  126. package/.mindforge/integrations/github.md +25 -0
  127. package/.mindforge/integrations/gitlab.md +13 -0
  128. package/.mindforge/integrations/jira.md +102 -0
  129. package/.mindforge/integrations/slack.md +41 -0
  130. package/.mindforge/intelligence/antipattern-detector.md +75 -0
  131. package/.mindforge/intelligence/difficulty-scorer.md +55 -0
  132. package/.mindforge/intelligence/health-engine.md +208 -0
  133. package/.mindforge/intelligence/skill-gap-analyser.md +40 -0
  134. package/.mindforge/intelligence/smart-compaction.md +71 -0
  135. package/.mindforge/metrics/METRICS-SCHEMA.md +42 -0
  136. package/.mindforge/metrics/quality-tracker.md +32 -0
  137. package/.mindforge/monorepo/cross-package-planner.md +114 -0
  138. package/.mindforge/monorepo/dependency-graph-builder.md +32 -0
  139. package/.mindforge/monorepo/workspace-detector.md +129 -0
  140. package/.mindforge/org/CONVENTIONS.md +62 -0
  141. package/.mindforge/org/ORG.md +51 -0
  142. package/.mindforge/org/SECURITY.md +50 -0
  143. package/.mindforge/org/TOOLS.md +53 -0
  144. package/.mindforge/org/integrations/INTEGRATIONS-CONFIG.md +58 -0
  145. package/.mindforge/org/skills/MANIFEST.md +38 -0
  146. package/.mindforge/personas/analyst.md +52 -0
  147. package/.mindforge/personas/architect.md +75 -0
  148. package/.mindforge/personas/debug-specialist.md +52 -0
  149. package/.mindforge/personas/developer.md +85 -0
  150. package/.mindforge/personas/overrides/README.md +85 -0
  151. package/.mindforge/personas/qa-engineer.md +61 -0
  152. package/.mindforge/personas/release-manager.md +76 -0
  153. package/.mindforge/personas/security-reviewer.md +91 -0
  154. package/.mindforge/personas/tech-writer.md +51 -0
  155. package/.mindforge/plugins/PLUGINS-MANIFEST.md +23 -0
  156. package/.mindforge/plugins/plugin-loader.md +93 -0
  157. package/.mindforge/plugins/plugin-registry.md +44 -0
  158. package/.mindforge/plugins/plugin-schema.md +68 -0
  159. package/.mindforge/pr-review/ai-reviewer.md +266 -0
  160. package/.mindforge/pr-review/finding-formatter.md +46 -0
  161. package/.mindforge/pr-review/review-prompt-templates.md +44 -0
  162. package/.mindforge/production/compatibility-layer.md +39 -0
  163. package/.mindforge/production/migration-engine.md +52 -0
  164. package/.mindforge/production/production-checklist.md +165 -0
  165. package/.mindforge/production/token-optimiser.md +68 -0
  166. package/.mindforge/skills/accessibility/SKILL.md +106 -0
  167. package/.mindforge/skills/api-design/SKILL.md +98 -0
  168. package/.mindforge/skills/code-quality/SKILL.md +88 -0
  169. package/.mindforge/skills/data-privacy/SKILL.md +126 -0
  170. package/.mindforge/skills/database-patterns/SKILL.md +192 -0
  171. package/.mindforge/skills/documentation/SKILL.md +91 -0
  172. package/.mindforge/skills/incident-response/SKILL.md +180 -0
  173. package/.mindforge/skills/performance/SKILL.md +120 -0
  174. package/.mindforge/skills/security-review/SKILL.md +83 -0
  175. package/.mindforge/skills/testing-standards/SKILL.md +97 -0
  176. package/.mindforge/team/TEAM-PROFILE.md +42 -0
  177. package/.mindforge/team/multi-handoff.md +23 -0
  178. package/.mindforge/team/profiles/README.md +13 -0
  179. package/.mindforge/team/session-merger.md +18 -0
  180. package/.planning/ARCHITECTURE.md +0 -0
  181. package/.planning/AUDIT.jsonl +0 -0
  182. package/.planning/HANDOFF.json +28 -0
  183. package/.planning/PROJECT.md +33 -0
  184. package/.planning/RELEASE-CHECKLIST.md +68 -0
  185. package/.planning/REQUIREMENTS.md +0 -0
  186. package/.planning/ROADMAP.md +0 -0
  187. package/.planning/STATE.md +31 -0
  188. package/.planning/approvals/.gitkeep +1 -0
  189. package/.planning/archive/.gitkeep +1 -0
  190. package/.planning/audit-archive/.gitkeep +1 -0
  191. package/.planning/decisions/.gitkeep +0 -0
  192. package/.planning/decisions/ADR-001-handoff-tracking.md +41 -0
  193. package/.planning/decisions/ADR-002-markdown-commands.md +46 -0
  194. package/.planning/decisions/ADR-003-skills-trigger-model.md +37 -0
  195. package/.planning/decisions/ADR-004-wave-parallelism-model.md +45 -0
  196. package/.planning/decisions/ADR-005-append-only-audit-log.md +51 -0
  197. package/.planning/decisions/ADR-006-tiered-skills-system.md +22 -0
  198. package/.planning/decisions/ADR-007-trigger-keyword-model.md +22 -0
  199. package/.planning/decisions/ADR-008-just-in-time-skill-loading.md +29 -0
  200. package/.planning/decisions/ADR-009-enterprise-integration-retry-policy.md +8 -0
  201. package/.planning/decisions/ADR-010-governance-tier-escalation.md +8 -0
  202. package/.planning/decisions/ADR-011-multi-developer-handoff-contract.md +8 -0
  203. package/.planning/decisions/ADR-012-intelligence-feedback-loops.md +19 -0
  204. package/.planning/decisions/ADR-013-mindforge-md-constitution.md +16 -0
  205. package/.planning/decisions/ADR-014-metrics-as-signals-not-evaluation.md +15 -0
  206. package/.planning/decisions/ADR-015-npm-based-skill-registry.md +26 -0
  207. package/.planning/decisions/ADR-016-ci-exit-code-0-on-timeout.md +27 -0
  208. package/.planning/decisions/ADR-017-sdk-localhost-only.md +28 -0
  209. package/.planning/decisions/ADR-018-installer-self-install-detection.md +15 -0
  210. package/.planning/decisions/ADR-019-self-update-scope-preservation.md +14 -0
  211. package/.planning/decisions/ADR-020-v1.0.0-stable-interface-contract.md +23 -0
  212. package/.planning/jira-sync.json +9 -0
  213. package/.planning/milestones/.gitkeep +1 -0
  214. package/.planning/phases/day1/REVIEW-DAY1.md +50 -0
  215. package/.planning/phases/day1/SECURITY-REVIEW-DAY1.md +15 -0
  216. package/.planning/phases/day2/REVIEW-DAY2.md +521 -0
  217. package/.planning/phases/day3/REVIEW-DAY3.md +234 -0
  218. package/.planning/slack-threads.json +6 -0
  219. package/CHANGELOG.md +175 -0
  220. package/LICENSE +21 -0
  221. package/MINDFORGE.md +76 -0
  222. package/README.md +182 -0
  223. package/RELEASENOTES.md +41 -0
  224. package/SECURITY.md +4 -0
  225. package/bin/install.js +120 -0
  226. package/bin/installer-core.js +292 -0
  227. package/bin/migrations/0.1.0-to-0.5.0.js +37 -0
  228. package/bin/migrations/0.5.0-to-0.6.0.js +17 -0
  229. package/bin/migrations/0.6.0-to-1.0.0.js +100 -0
  230. package/bin/migrations/migrate.js +151 -0
  231. package/bin/migrations/schema-versions.js +64 -0
  232. package/bin/updater/changelog-fetcher.js +62 -0
  233. package/bin/updater/self-update.js +169 -0
  234. package/bin/updater/version-comparator.js +68 -0
  235. package/bin/validate-config.js +92 -0
  236. package/bin/wizard/config-generator.js +112 -0
  237. package/bin/wizard/environment-detector.js +76 -0
  238. package/bin/wizard/setup-wizard.js +237 -0
  239. package/docs/Context/Master-Context.md +701 -0
  240. package/docs/architecture/README.md +35 -0
  241. package/docs/architecture/decision-records-index.md +26 -0
  242. package/docs/ci-cd-integration.md +30 -0
  243. package/docs/ci-quickstart.md +78 -0
  244. package/docs/commands-reference.md +11 -0
  245. package/docs/contributing/CONTRIBUTING.md +38 -0
  246. package/docs/contributing/plugin-authoring.md +50 -0
  247. package/docs/contributing/skill-authoring.md +41 -0
  248. package/docs/enterprise-setup.md +25 -0
  249. package/docs/faq.md +38 -0
  250. package/docs/getting-started.md +36 -0
  251. package/docs/governance-guide.md +23 -0
  252. package/docs/mindforge-md-reference.md +53 -0
  253. package/docs/monorepo-guide.md +26 -0
  254. package/docs/persona-customisation.md +56 -0
  255. package/docs/quick-verify.md +33 -0
  256. package/docs/reference/audit-events.md +53 -0
  257. package/docs/reference/commands.md +82 -0
  258. package/docs/reference/config-reference.md +64 -0
  259. package/docs/reference/sdk-api.md +48 -0
  260. package/docs/reference/skills-api.md +57 -0
  261. package/docs/release-checklist-guide.md +37 -0
  262. package/docs/requirements.md +29 -0
  263. package/docs/sdk-reference.md +27 -0
  264. package/docs/security/SECURITY.md +42 -0
  265. package/docs/security/penetration-test-results.md +31 -0
  266. package/docs/security/threat-model.md +142 -0
  267. package/docs/skills-authoring-guide.md +119 -0
  268. package/docs/skills-publishing-guide.md +21 -0
  269. package/docs/team-setup-guide.md +21 -0
  270. package/docs/troubleshooting.md +119 -0
  271. package/docs/tutorial.md +195 -0
  272. package/docs/upgrade.md +44 -0
  273. package/docs/user-guide.md +131 -0
  274. package/docs/usp-features.md +214 -0
  275. package/eslint.config.mjs +31 -0
  276. package/examples/starter-project/.planning/AUDIT.jsonl +1 -0
  277. package/examples/starter-project/.planning/HANDOFF.json +23 -0
  278. package/examples/starter-project/.planning/PROJECT.md +27 -0
  279. package/examples/starter-project/.planning/STATE.md +10 -0
  280. package/examples/starter-project/MINDFORGE.md +40 -0
  281. package/examples/starter-project/README.md +14 -0
  282. package/implementation-roadmap/day-1-imp/DAY1-HARDEN.md +823 -0
  283. package/implementation-roadmap/day-1-imp/DAY1-IMPLEMENT.md +2459 -0
  284. package/implementation-roadmap/day-1-imp/DAY1-REVIEW.md +288 -0
  285. package/implementation-roadmap/day-2-imp/DAY2-HARDEN.md +954 -0
  286. package/implementation-roadmap/day-2-imp/DAY2-IMPLEMENT.md +2347 -0
  287. package/implementation-roadmap/day-2-imp/DAY2-REVIEW.md +422 -0
  288. package/implementation-roadmap/day-3-imp/DAY3-HARDEN.md +870 -0
  289. package/implementation-roadmap/day-3-imp/DAY3-IMPLEMENT.md +2798 -0
  290. package/implementation-roadmap/day-3-imp/DAY3-REVIEW.md +484 -0
  291. package/implementation-roadmap/day-4-imp/DAY4-HARDEN.md +1087 -0
  292. package/implementation-roadmap/day-4-imp/DAY4-IMPLEMENT.md +2874 -0
  293. package/implementation-roadmap/day-4-imp/DAY4-REVIEW.md +386 -0
  294. package/implementation-roadmap/day-5-imp/DAY5-HARDEN.md +1078 -0
  295. package/implementation-roadmap/day-5-imp/DAY5-IMPLEMENT.md +3151 -0
  296. package/implementation-roadmap/day-5-imp/DAY5-REVIEW.md +345 -0
  297. package/implementation-roadmap/day-6-imp/DAY6-COMPLETE.md +3919 -0
  298. package/implementation-roadmap/day-7-imp-prod/DAY7-PRODUCTION-FINAL.md +4513 -0
  299. package/package.json +31 -0
  300. package/sdk/README.md +69 -0
  301. package/sdk/eslint.config.mjs +34 -0
  302. package/sdk/package-lock.json +1507 -0
  303. package/sdk/package.json +30 -0
  304. package/sdk/src/client.ts +133 -0
  305. package/sdk/src/commands.ts +63 -0
  306. package/sdk/src/events.ts +166 -0
  307. package/sdk/src/index.ts +22 -0
  308. package/sdk/src/types.ts +87 -0
  309. package/sdk/tsconfig.json +13 -0
  310. package/tests/audit.test.js +206 -0
  311. package/tests/ci-mode.test.js +162 -0
  312. package/tests/compaction.test.js +161 -0
  313. package/tests/distribution.test.js +205 -0
  314. package/tests/e2e.test.js +618 -0
  315. package/tests/governance.test.js +130 -0
  316. package/tests/install.test.js +209 -0
  317. package/tests/integrations.test.js +128 -0
  318. package/tests/intelligence.test.js +117 -0
  319. package/tests/metrics.test.js +96 -0
  320. package/tests/migration.test.js +309 -0
  321. package/tests/production.test.js +416 -0
  322. package/tests/sdk.test.js +200 -0
  323. package/tests/skills-platform.test.js +403 -0
  324. package/tests/wave-engine.test.js +338 -0
@@ -0,0 +1,106 @@
1
+ ---
2
+ name: accessibility
3
+ version: 1.0.0
4
+ min_mindforge_version: 0.3.0
5
+ status: stable
6
+ triggers: accessibility, a11y, aria, ARIA, wcag, WCAG, screen reader, keyboard, focus, tab order, colour contrast, color contrast, alt text, semantic HTML, form label, button, interactive, disabled, skip link, heading hierarchy, landmark, live region, modal, dialog, tooltip, dropdown, combobox
7
+ ---
8
+
9
+ # Skill — Accessibility Engineering
10
+
11
+ ## When this skill activates
12
+ Any task involving UI components, forms, interactive elements, or user-facing HTML.
13
+ Load this skill for ALL frontend work — accessibility is not optional.
14
+
15
+ ## Mandatory standard
16
+ WCAG 2.2 Level AA is the minimum. This is the legal requirement in most jurisdictions.
17
+ Level AAA elements (where achievable without design compromise) are recommended.
18
+
19
+ ## Mandatory actions when this skill is active
20
+
21
+ ### Before writing any UI component
22
+ 1. Identify the semantic HTML element that best represents the component.
23
+ Use native HTML before ARIA. A `<button>` is always better than a `<div role="button">`.
24
+ 2. Map all interactive states: default, hover, focus, active, disabled, error, loading.
25
+ 3. Confirm colour contrast meets WCAG AA:
26
+ - Normal text: contrast ratio ≥ 4.5:1
27
+ - Large text (≥ 18pt or ≥ 14pt bold): contrast ratio ≥ 3:1
28
+ - UI components and graphics: contrast ratio ≥ 3:1
29
+
30
+ ### HTML semantics checklist (apply to every component)
31
+
32
+ **Structure:**
33
+ - [ ] One `<h1>` per page. Heading hierarchy is sequential (h1 → h2 → h3, never skip levels)
34
+ - [ ] Landmark roles present: `<main>`, `<nav>`, `<header>`, `<footer>`, `<aside>`
35
+ - [ ] Skip navigation link as the first focusable element on every page
36
+ - [ ] Focus order follows DOM order (do not rely on visual layout to imply order)
37
+
38
+ **Forms:**
39
+ - [ ] Every input has a visible `<label>` (not just placeholder text)
40
+ - [ ] Label is programmatically associated: `<label for="id">` or `aria-labelledby`
41
+ - [ ] Required fields marked: `required` attribute + visual indicator + aria description
42
+ - [ ] Error messages: `role="alert"` or `aria-live="polite"`, associated with field via `aria-describedby`
43
+ - [ ] Validation errors describe the problem AND the fix, not just "Invalid input"
44
+
45
+ **Interactive components:**
46
+ - [ ] All interactive elements reachable by Tab key
47
+ - [ ] Focus visible: never `outline: none` without a custom visible focus style
48
+ - [ ] Keyboard shortcuts documented and not conflicting with browser/OS shortcuts
49
+ - [ ] Custom widgets implement the correct ARIA pattern (see ARIA Authoring Practices Guide)
50
+ - [ ] Required ARIA props present when using roles (examples below)
51
+
52
+ **Images and media:**
53
+ - [ ] Decorative images: `alt=""` (empty string, not omitted)
54
+ - [ ] Informative images: `alt` describes the information conveyed
55
+ - [ ] Complex images (charts, diagrams): `aria-describedby` pointing to a full text description
56
+ - [ ] Videos: captions required. Audio descriptions for visual-only information.
57
+
58
+ **Dynamic content:**
59
+ - [ ] Content that updates dynamically: `aria-live="polite"` (non-critical) or `aria-live="assertive"` (critical)
60
+ - [ ] Modals/dialogs: focus moves to modal on open, returns to trigger on close, `aria-modal="true"`
61
+ - [ ] Loading states: `aria-busy="true"` on the container being updated
62
+ - [ ] Reduced motion respected: `prefers-reduced-motion` disables non-essential animation
63
+
64
+ ### ARIA usage rules
65
+ - Use ARIA only when no native HTML element conveys the role
66
+ - ARIA roles override native semantics — applying a role to `<button>` changes it
67
+ - Required ARIA properties: never use a role without its required properties
68
+ (e.g., `role="checkbox"` requires `aria-checked`)
69
+ - Never use `aria-hidden="true"` on focusable elements
70
+
71
+ ### ARIA required properties examples
72
+ - `role="checkbox"` → `aria-checked`
73
+ - `role="switch"` → `aria-checked`
74
+ - `role="textbox"` (non-input element) → `aria-multiline` (if multiline)
75
+ - `role="combobox"` → `aria-expanded`, `aria-controls`, `aria-haspopup`
76
+ - `role="dialog"` → `aria-modal`, `aria-labelledby` (and `aria-describedby` when needed)
77
+
78
+ ### Testing protocol
79
+ ```bash
80
+ # Automated testing (catches ~30-40% of issues)
81
+ npx axe-cli https://localhost:3000
82
+
83
+ # Keyboard testing (manual — must be done for every interactive component)
84
+ # 1. Tab through every interactive element — order must be logical
85
+ # 2. Activate every control with Enter/Space — must work
86
+ # 3. Navigate dropdowns/menus with arrow keys
87
+ # 4. Escape dismisses modals and dropdowns
88
+
89
+ # Screen reader testing (minimum: test with NVDA + Chrome on Windows OR
90
+ # VoiceOver + Safari on macOS)
91
+ # Key checks:
92
+ # - Every interactive element announced with role, name, and state
93
+ # - Dynamic updates announced appropriately
94
+ # - Images described correctly
95
+
96
+ # Contrast checking
97
+ # Install: axe DevTools browser extension or Colour Contrast Analyser
98
+ ```
99
+
100
+ ## Self-check before task completion
101
+ - [ ] Ran `axe-cli` — zero violations
102
+ - [ ] Keyboard navigation tested manually
103
+ - [ ] All interactive elements have accessible names
104
+ - [ ] Colour contrast meets 4.5:1 for text
105
+ - [ ] Focus management correct for modals and dynamic content
106
+ - [ ] No `aria-hidden` on focusable elements
@@ -0,0 +1,98 @@
1
+ ---
2
+ name: api-design
3
+ version: 1.0.0
4
+ min_mindforge_version: 0.1.0
5
+ status: stable
6
+ triggers: API, endpoint, REST, GraphQL, route, controller, handler, request, response, HTTP, POST, GET, PUT, PATCH, DELETE, contract, versioning, OpenAPI
7
+ ---
8
+
9
+ # Skill — API Design
10
+
11
+ ## When this skill activates
12
+ Any task involving creating or modifying API endpoints, request/response schemas,
13
+ or API contracts.
14
+
15
+ ## Mandatory actions when this skill is active
16
+
17
+ ### Before writing any code
18
+ 1. Define the endpoint contract: method, path, auth requirement.
19
+ 2. Define request and response schemas (including error shape).
20
+
21
+ ### During implementation
22
+ - Validate input at the boundary.
23
+ - Use consistent status codes.
24
+ - Add security headers to responses.
25
+
26
+ ### After implementation
27
+ - Document the endpoint in ARCHITECTURE.md.
28
+ - Add or update tests for the new contract.
29
+
30
+ ## REST API standards
31
+
32
+ ### URL conventions
33
+ - Lowercase, hyphen-separated: `/user-profiles` not `/userProfiles`
34
+ - Nouns for resources: `/orders` not `/getOrders`
35
+ - Hierarchy shows relationships: `/users/{id}/orders`
36
+ - Version in path: `/v1/users`
37
+
38
+ ### HTTP method semantics
39
+ - GET: read only, idempotent, no body
40
+ - POST: create, non-idempotent, returns 201 + Location header
41
+ - PUT: full replace, idempotent
42
+ - PATCH: partial update, idempotent
43
+ - DELETE: remove, idempotent, returns 204
44
+
45
+ ### Status codes (use precisely)
46
+ - 200 OK: successful GET, PUT, PATCH
47
+ - 201 Created: successful POST (include Location header)
48
+ - 204 No Content: successful DELETE
49
+ - 400 Bad Request: client validation error (include error details in body)
50
+ - 401 Unauthorized: missing or invalid authentication
51
+ - 403 Forbidden: authenticated but not authorised
52
+ - 404 Not Found: resource does not exist
53
+ - 409 Conflict: state conflict (duplicate, version mismatch)
54
+ - 422 Unprocessable Entity: semantic validation error
55
+ - 429 Too Many Requests: rate limit exceeded (include Retry-After header)
56
+ - 500 Internal Server Error: unexpected server error (never expose internals)
57
+
58
+ ### Error response format (always consistent)
59
+ ```json
60
+ {
61
+ "error": {
62
+ "code": "VALIDATION_ERROR",
63
+ "message": "Human-readable description",
64
+ "details": [
65
+ { "field": "email", "issue": "must be a valid email address" }
66
+ ],
67
+ "requestId": "req_abc123"
68
+ }
69
+ }
70
+ ```
71
+
72
+ ### Request validation
73
+ - Validate at the route handler boundary, not deep in business logic
74
+ - Return all validation errors at once (not one at a time)
75
+ - Validate: type, format, length, range, required fields
76
+
77
+ ### Security headers (add to every response)
78
+ ```
79
+ X-Content-Type-Options: nosniff
80
+ X-Frame-Options: DENY
81
+ Strict-Transport-Security: max-age=31536000; includeSubDomains
82
+ Content-Security-Policy: default-src 'self'
83
+ ```
84
+
85
+ ## Output
86
+ New endpoints must be documented in ARCHITECTURE.md under the API section
87
+ with: method, path, auth requirement, request schema, response schema, errors.
88
+
89
+ ## Self-check before task completion
90
+
91
+ Before marking a task done when this skill was active:
92
+
93
+ - [ ] Did I read the full SKILL.md before starting? (Not just the triggers)
94
+ - [ ] Did I activate the corresponding persona file?
95
+ - [ ] Did I apply every mandatory action in this skill, not just the ones
96
+ I remembered off the top of my head?
97
+ - [ ] If this skill produced an output file (review, security report, etc.),
98
+ has that file been written to the correct path?
@@ -0,0 +1,88 @@
1
+ ---
2
+ name: code-quality
3
+ version: 1.0.0
4
+ min_mindforge_version: 0.1.0
5
+ status: stable
6
+ triggers: refactor, code review, review, quality, tech debt, complexity, clean up, cleanup, lint, linting, code smell, duplication, naming, readability
7
+ ---
8
+
9
+ # Skill — Code Quality
10
+
11
+ ## When this skill activates
12
+ Any code review, refactoring task, or implementation where maintaining
13
+ quality standards is the primary goal.
14
+
15
+ ## Mandatory actions when this skill is active
16
+
17
+ ### Before writing any code
18
+ 1. Read CONVENTIONS.md and apply all rules.
19
+ 2. Identify complexity risks (hot paths, long functions, nested logic).
20
+ 3. Decide up front where tests will be added or updated.
21
+
22
+ ### During implementation or review
23
+ - Enforce function length and complexity limits.
24
+ - Remove unused code and dead imports.
25
+ - Replace magic numbers with named constants.
26
+
27
+ ### After implementation or review
28
+ - Run linters and type checks for the project.
29
+ - Record findings or fixes in SUMMARY.md or the review report.
30
+
31
+ ## Quality dimensions to evaluate
32
+
33
+ ### Readability
34
+ - Can a new engineer understand this function in under 2 minutes?
35
+ - Are names precise and unambiguous? (Not `data`, `info`, `temp`, `flag`)
36
+ - Is every non-obvious decision explained with a comment?
37
+ - Are there magic numbers? (Replace with named constants)
38
+
39
+ ### Complexity limits
40
+ - Functions: ≤ 40 lines. If longer, extract sub-functions.
41
+ - Cyclomatic complexity: ≤ 10 per function.
42
+ - Nesting depth: ≤ 3 levels. Extract to separate function if deeper.
43
+ - Parameters: ≤ 4 per function. If more, use an options object.
44
+
45
+ ### Duplication
46
+ - DRY (Don't Repeat Yourself): extract any logic appearing 3+ times.
47
+ - Exception: duplication in tests is acceptable for clarity.
48
+
49
+ ### Error handling
50
+ - Every async operation must have explicit error handling.
51
+ - No empty catch blocks (`catch(e) {}`).
52
+ - No swallowed errors (`catch(e) { return null }`).
53
+ - Errors must be logged with enough context to diagnose.
54
+
55
+ ### Dependencies
56
+ - Before adding any new dependency: check bundle size, CVEs, last commit date,
57
+ weekly downloads, and licence compatibility.
58
+ - Prefer native platform APIs over dependencies for simple tasks.
59
+
60
+ ## Metrics to check before marking a task done
61
+ Run these and fix any failures:
62
+ ```bash
63
+ # TypeScript projects
64
+ npx tsc --noEmit
65
+ npx eslint . --ext .ts,.tsx
66
+
67
+ # Python projects
68
+ ruff check .
69
+ mypy .
70
+
71
+ # All projects
72
+ [project test command]
73
+ ```
74
+
75
+ ## Output
76
+ If performing a code review: write findings to `.planning/phases/phase-N/CODE-REVIEW-N.md`
77
+ with file, line, severity (blocking / suggestion), and recommended fix.
78
+
79
+ ## Self-check before task completion
80
+
81
+ Before marking a task done when this skill was active:
82
+
83
+ - [ ] Did I read the full SKILL.md before starting? (Not just the triggers)
84
+ - [ ] Did I activate the corresponding persona file?
85
+ - [ ] Did I apply every mandatory action in this skill, not just the ones
86
+ I remembered off the top of my head?
87
+ - [ ] If this skill produced an output file (review, security report, etc.),
88
+ has that file been written to the correct path?
@@ -0,0 +1,126 @@
1
+ ---
2
+ name: data-privacy
3
+ version: 1.0.0
4
+ min_mindforge_version: 0.3.0
5
+ status: stable
6
+ triggers: GDPR, CCPA, privacy, PII, personal data, personal information, consent, data retention, right to erasure, right to access, data portability, data subject, anonymise, anonymize, pseudonymise, pseudonymize, data minimisation, data minimization, lawful basis, cookie, tracking, analytics, marketing, third party, data transfer, cross-border
7
+ ---
8
+
9
+ # Skill — Data Privacy Engineering
10
+
11
+ ## When this skill activates
12
+ Any task touching personal data collection, storage, processing, or transfer.
13
+ Also activates for consent management, analytics, cookie handling, and any
14
+ feature where user data flows to third parties.
15
+ These rules are language-agnostic — apply them regardless of framework or stack.
16
+
17
+ ## Regulatory coverage
18
+ This skill covers: GDPR (EU/UK), CCPA/CPRA (California), PIPEDA (Canada),
19
+ PDPA (Thailand/Singapore variants), LGPD (Brazil). Requirements often overlap —
20
+ implementing GDPR correctly satisfies most other frameworks.
21
+
22
+ ## Mandatory actions when this skill is active
23
+
24
+ ### Data audit — before touching any data feature
25
+ Answer these questions before writing code:
26
+ 1. **What personal data is collected?** (Name, email, IP, device ID, location, behaviour)
27
+ 2. **What is the lawful basis for processing?** (Consent / Contract / Legitimate interest / Legal obligation)
28
+ 3. **How long is it retained?** (Must have a defined retention period — not "indefinitely")
29
+ 4. **Who does it flow to?** (Internal systems only / third-party processors / international transfer)
30
+ 5. **Can users access, export, and delete their data?**
31
+
32
+ If you cannot answer all 5: stop. Write the answers in ARCHITECTURE.md under
33
+ "Data Privacy" before implementing anything.
34
+
35
+ ### PII handling standards
36
+
37
+ **Collection:**
38
+ - Collect the minimum data required for the stated purpose (data minimisation)
39
+ - Obtain consent before collecting non-essential data (analytics, marketing)
40
+ - Consent must be: specific, informed, freely given, unambiguous, and withdrawable
41
+ - Withdrawing consent must be as easy as giving it (no dark patterns, no extra steps)
42
+ - Never pre-tick consent checkboxes. Never bundle consent for different purposes.
43
+
44
+ **Storage:**
45
+ - PII fields in the database must be identified (document in ARCHITECTURE.md)
46
+ - Encrypt sensitive PII at rest: financial data, health data, government IDs
47
+ - Pseudonymisation: where possible, store a user ID reference rather than PII inline
48
+ - Never store PII in: logs, AUDIT.jsonl, git commits, error messages, URL parameters
49
+
50
+ **Transfer:**
51
+ - Third-party processors: must have a Data Processing Agreement (DPA)
52
+ - International transfer (out of EU): requires Standard Contractual Clauses or adequacy decision
53
+ - Document all third-party data flows in ARCHITECTURE.md
54
+
55
+ **Retention and deletion:**
56
+ - Define retention period for every PII field in the data model
57
+ - Implement automated deletion or anonymisation when retention period expires
58
+ - Implement "right to erasure": a complete user delete must remove or anonymise ALL their PII
59
+ - Implement "right to access": export of all user data in a portable format (JSON/CSV)
60
+ - Test deletion: verify that deleted user data does not appear in any API response
61
+
62
+ **Retention examples (defaults, adjust to policy/legal requirements):**
63
+ - Authentication logs: 30–90 days
64
+ - Security/audit logs: 90–365 days
65
+ - Billing records: 6–7 years (jurisdiction dependent)
66
+ - Analytics events: 12–24 months
67
+ Always confirm with legal/compliance for your jurisdiction.
68
+
69
+ **Erasure vs anonymisation:**
70
+ - Erasure: delete or irreversibly remove identifiers from all systems
71
+ - Anonymisation: permanently remove identifying attributes so data cannot be re-linked
72
+ If anonymisation is used, document the method and verify re-identification risk.
73
+
74
+ ### Cookie and tracking standards
75
+ ```javascript
76
+ // Required: granular consent per category
77
+ const consentCategories = {
78
+ necessary: true, // Always true — no consent needed
79
+ functional: false, // Requires consent
80
+ analytics: false, // Requires consent
81
+ marketing: false, // Requires consent — highest bar
82
+ };
83
+
84
+ // Required: record consent with timestamp and version
85
+ await recordConsent({
86
+ userId: user.id,
87
+ categories: consentCategories,
88
+ timestamp: new Date().toISOString(),
89
+ policyVersion: '2026-01',
90
+ ipHash: hash(userIp), // Store hash not raw IP for GDPR compliance
91
+ });
92
+
93
+ // Required: honour opt-out immediately
94
+ // If analytics: false — stop sending analytics events NOW, not on next page load
95
+ ```
96
+
97
+ ### Code patterns that are FORBIDDEN under data privacy
98
+ ```
99
+ // ❌ NEVER: Log PII
100
+ console.log(`User ${user.email} logged in`) // email in logs = GDPR violation
101
+ logger.info({ user }) // entire user object = PII in logs
102
+
103
+ // ✅ ALWAYS: Log identifiers, never PII
104
+ logger.info({ userId: user.id, event: 'login' })
105
+
106
+ // ❌ NEVER: PII in error messages
107
+ throw new Error(`Could not find user ${user.email}`) // exposed in stack traces
108
+
109
+ // ✅ ALWAYS: identifiers in errors
110
+ throw new Error(`Could not find user [id:${user.id}]`)
111
+
112
+ // ❌ NEVER: PII in URL parameters
113
+ GET /api/users?email=john@example.com // logged by web servers, CDNs, browsers
114
+
115
+ // ✅ ALWAYS: POST body or path parameter by ID
116
+ GET /api/users/{id}
117
+ ```
118
+
119
+ ## Privacy review checklist
120
+ Before marking any data-related task done:
121
+ - [ ] Lawful basis identified for every data point collected
122
+ - [ ] PII never appears in logs, error messages, or URL parameters
123
+ - [ ] Retention period defined for every new PII field
124
+ - [ ] Third-party data flows documented in ARCHITECTURE.md
125
+ - [ ] User delete removes or anonymises ALL PII ✅ / not yet implemented ⚠️
126
+ - [ ] Consent UI does not use dark patterns (pre-ticked, bundled, misleading)
@@ -0,0 +1,192 @@
1
+ ---
2
+ name: database-patterns
3
+ version: 1.0.0
4
+ min_mindforge_version: 0.3.0
5
+ status: stable
6
+ triggers: database, DB, SQL, query, migration, schema, index, indexing, N+1, transaction, ACID, foreign key, join, aggregate, pagination, cursor, connection pool, ORM, Prisma, SQLAlchemy, Drizzle, Sequelize, PostgreSQL, MySQL, SQLite, MongoDB, Redis, Elasticsearch
7
+ ---
8
+
9
+ # Skill — Database Patterns
10
+
11
+ ## When this skill activates
12
+ Any task involving database schema design, query writing, migrations, or
13
+ ORM configuration.
14
+
15
+ ## Mandatory actions when this skill is active
16
+
17
+ ### Schema design standards
18
+
19
+ **Naming conventions (PostgreSQL default):**
20
+ ```sql
21
+ -- Tables: snake_case, plural
22
+ CREATE TABLE user_profiles (...);
23
+ CREATE TABLE order_items (...);
24
+
25
+ -- Columns: snake_case
26
+ user_id, created_at, updated_at, deleted_at
27
+
28
+ -- Primary keys: always id (UUID preferred over auto-increment)
29
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid()
30
+
31
+ -- Foreign keys: {referenced_table_singular}_id
32
+ user_id UUID REFERENCES users(id) ON DELETE CASCADE
33
+ order_id UUID REFERENCES orders(id) ON DELETE SET NULL
34
+
35
+ -- Indexes: idx_{table}_{column(s)}
36
+ CREATE INDEX idx_users_email ON users(email);
37
+ CREATE INDEX idx_orders_user_id_created_at ON orders(user_id, created_at DESC);
38
+ ```
39
+
40
+ **Standard columns every table should have:**
41
+ ```sql
42
+ id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
43
+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
44
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
45
+ -- For soft delete (preferred over hard delete):
46
+ deleted_at TIMESTAMPTZ -- NULL = active, timestamp = deleted
47
+ ```
48
+
49
+ **UUID strategy:**
50
+ - Prefer UUIDv7 or ULID for time-ordered inserts (better index locality)
51
+ - Use random UUIDv4 for high-entropy IDs when ordering is not important
52
+ - Document the choice in ARCHITECTURE.md and keep it consistent across tables
53
+
54
+ **Soft delete implementation:**
55
+ Use soft delete (setting `deleted_at`) instead of hard delete for:
56
+ - User records (GDPR right to erasure exception: anonymise, don't delete)
57
+ - Financial records (audit requirements)
58
+ - Any record that might be referenced by other records
59
+
60
+ For hard delete: cascade must be configured. Document the cascade in ARCHITECTURE.md.
61
+
62
+ ### Query standards
63
+
64
+ **N+1 query detection and prevention:**
65
+ ```typescript
66
+ // ❌ N+1 pattern: 1 query for users + N queries for their orders
67
+ const users = await db.users.findMany()
68
+ for (const user of users) {
69
+ user.orders = await db.orders.findMany({ where: { userId: user.id } })
70
+ }
71
+
72
+ // ✅ Single query with JOIN or include
73
+ const users = await db.users.findMany({
74
+ include: { orders: true } // Prisma generates a single JOIN query
75
+ })
76
+
77
+ // ✅ Or batch load with WHERE IN
78
+ const userIds = users.map(u => u.id)
79
+ const orders = await db.orders.findMany({ where: { userId: { in: userIds } } })
80
+ const ordersByUser = groupBy(orders, 'userId')
81
+ ```
82
+
83
+ **Framework-agnostic SQL example (N+1):**
84
+ ```sql
85
+ -- ❌ N+1 pattern (application loops)
86
+ -- SELECT * FROM users LIMIT 50;
87
+ -- then for each user:
88
+ -- SELECT * FROM orders WHERE user_id = ?;
89
+
90
+ -- ✅ Single query with JOIN
91
+ SELECT u.*, o.*
92
+ FROM users u
93
+ LEFT JOIN orders o ON o.user_id = u.id
94
+ WHERE u.id IN (:user_ids);
95
+ ```
96
+
97
+ **Pagination patterns:**
98
+ ```typescript
99
+ // ❌ OFFSET pagination (slow on large datasets — scans all previous rows)
100
+ SELECT * FROM posts ORDER BY created_at DESC LIMIT 20 OFFSET 10000;
101
+
102
+ // ✅ Compound cursor — handles duplicate timestamps correctly
103
+ // Application layer: encode (created_at, id) as the cursor
104
+ SELECT * FROM posts
105
+ WHERE (created_at, id) < (:cursor_time::timestamptz, :cursor_id::uuid)
106
+ ORDER BY created_at DESC, id DESC
107
+ LIMIT 20;
108
+
109
+ // Cursor encoding (application layer):
110
+ // encode: btoa(JSON.stringify({ t: row.created_at, id: row.id }))
111
+ // decode: JSON.parse(atob(cursor))
112
+ // Return:
113
+ {
114
+ "data": [...],
115
+ "nextCursor": "[base64 of {t, id} pair]",
116
+ "hasMore": true
117
+ }
118
+ ```
119
+
120
+ ### Why compound cursors matter
121
+ Single-field cursors (created_at only) produce incorrect pagination when
122
+ multiple records share the same timestamp — common in batch imports and
123
+ high-write systems. Always use at least (timestamp, id) as a compound cursor.
124
+
125
+ For simple cases where records are created sequentially and timestamps are
126
+ guaranteed unique (e.g., a single-writer queue): a single-field cursor is acceptable.
127
+ Document this assumption in the code.
128
+
129
+ **Transaction usage:**
130
+ ```typescript
131
+ // Use transactions whenever multiple writes must succeed or fail together
132
+ await db.$transaction(async (tx) => {
133
+ const order = await tx.orders.create({ data: orderData })
134
+ await tx.orderItems.createMany({ data: items.map(i => ({...i, orderId: order.id})) })
135
+ await tx.inventory.updateMany({ /* deduct stock */ })
136
+ // All three succeed or all three roll back
137
+ })
138
+ ```
139
+ For financial operations or ledger updates, use `SERIALIZABLE` isolation or
140
+ explicit row-level locks to prevent lost updates and double-spend conditions.
141
+
142
+ ### Index strategy
143
+
144
+ **Always index:**
145
+ - All foreign key columns (ORM does not always do this automatically)
146
+ - Columns used in WHERE clauses on large tables
147
+ - Columns used in ORDER BY on large tables
148
+ - Columns used in JOIN conditions
149
+
150
+ **Composite indexes:**
151
+ - Order columns from most selective (highest cardinality) to least
152
+ - A composite index on (a, b) is used for queries filtering on a alone,
153
+ or on both a and b. Not for b alone.
154
+ - Example: index on (user_id, created_at DESC) for "get user's recent items"
155
+
156
+ **Never index:**
157
+ - Boolean columns on large tables (index selectivity too low to help)
158
+ - Columns that change very frequently (index maintenance overhead)
159
+ - Tables with fewer than 10,000 rows (full scan is faster)
160
+
161
+ ### Migration standards
162
+
163
+ ```bash
164
+ # Every schema change must have a migration file
165
+ # Naming: [timestamp]_[descriptive-name].sql or per ORM convention
166
+
167
+ # Migration must be:
168
+ # 1. Idempotent: safe to run multiple times
169
+ # 2. Reversible: has both UP and DOWN migration
170
+ # 3. Non-blocking: avoid full table locks in production migrations
171
+
172
+ # Non-blocking pattern for adding a column (PostgreSQL):
173
+ # Step 1: Add column with default as NULL (instant)
174
+ ALTER TABLE users ADD COLUMN phone_verified BOOLEAN;
175
+
176
+ # Step 2: Backfill in batches (separate deployment)
177
+ UPDATE users SET phone_verified = false
178
+ WHERE id IN (SELECT id FROM users WHERE phone_verified IS NULL LIMIT 1000);
179
+
180
+ # Step 3: Add NOT NULL constraint + default (after backfill completes)
181
+ ALTER TABLE users ALTER COLUMN phone_verified SET NOT NULL;
182
+ ALTER TABLE users ALTER COLUMN phone_verified SET DEFAULT false;
183
+ ```
184
+
185
+ ## Query performance checklist
186
+ Before committing any query-writing task:
187
+ - [ ] Ran EXPLAIN ANALYZE on all non-trivial queries
188
+ - [ ] All WHERE/JOIN/ORDER BY columns have indexes
189
+ - [ ] No N+1 queries in list-fetching code
190
+ - [ ] Large queries paginated (cursor-based for > 1K rows)
191
+ - [ ] Transactions used for multi-write operations
192
+ - [ ] Connection pooling configured (not creating connections per request)