@jaimevalasek/aioson 1.3.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 (288) hide show
  1. package/CHANGELOG.md +456 -0
  2. package/CODE_OF_CONDUCT.md +12 -0
  3. package/CONTRIBUTING.md +13 -0
  4. package/LICENSE +21 -0
  5. package/README.md +254 -0
  6. package/bin/aioson.js +4 -0
  7. package/docs/en/cli-reference.md +398 -0
  8. package/docs/en/i18n.md +52 -0
  9. package/docs/en/json-schemas.md +41 -0
  10. package/docs/en/mcp.md +56 -0
  11. package/docs/en/parallel.md +82 -0
  12. package/docs/en/qa-browser.md +339 -0
  13. package/docs/en/release-flow.md +22 -0
  14. package/docs/en/release-notes-template.md +41 -0
  15. package/docs/en/release.md +28 -0
  16. package/docs/en/schemas/agent-prompt.schema.json +17 -0
  17. package/docs/en/schemas/agents.schema.json +32 -0
  18. package/docs/en/schemas/context-validate.schema.json +36 -0
  19. package/docs/en/schemas/doctor.schema.json +89 -0
  20. package/docs/en/schemas/error.schema.json +24 -0
  21. package/docs/en/schemas/i18n-add.schema.json +15 -0
  22. package/docs/en/schemas/index.json +116 -0
  23. package/docs/en/schemas/info.schema.json +39 -0
  24. package/docs/en/schemas/init.schema.json +48 -0
  25. package/docs/en/schemas/install.schema.json +60 -0
  26. package/docs/en/schemas/locale-apply.schema.json +30 -0
  27. package/docs/en/schemas/mcp-doctor.schema.json +95 -0
  28. package/docs/en/schemas/mcp-init.schema.json +122 -0
  29. package/docs/en/schemas/package-test.schema.json +24 -0
  30. package/docs/en/schemas/parallel-assign.schema.json +57 -0
  31. package/docs/en/schemas/parallel-doctor.schema.json +86 -0
  32. package/docs/en/schemas/parallel-init.schema.json +53 -0
  33. package/docs/en/schemas/parallel-status.schema.json +94 -0
  34. package/docs/en/schemas/setup-context.schema.json +39 -0
  35. package/docs/en/schemas/smoke.schema.json +23 -0
  36. package/docs/en/schemas/update.schema.json +48 -0
  37. package/docs/en/schemas/workflow-plan.schema.json +30 -0
  38. package/docs/en/web3.md +54 -0
  39. package/docs/pt/README.md +46 -0
  40. package/docs/pt/advisor-spec.md +335 -0
  41. package/docs/pt/agentes.md +453 -0
  42. package/docs/pt/cenarios.md +1230 -0
  43. package/docs/pt/clientes-ai.md +224 -0
  44. package/docs/pt/comandos-cli.md +511 -0
  45. package/docs/pt/genome-3.0-spec.md +296 -0
  46. package/docs/pt/guia-engineer.md +226 -0
  47. package/docs/pt/inicio-rapido.md +138 -0
  48. package/docs/pt/profiler-system.md +214 -0
  49. package/docs/pt/runtime-observability.md +72 -0
  50. package/docs/pt/squad-genoma.md +777 -0
  51. package/docs/pt/web3.md +797 -0
  52. package/docs/testing/genome-2.0-manual-regression.md +23 -0
  53. package/docs/testing/genome-2.0-matrix.md +36 -0
  54. package/docs/testing/genome-2.0-rollout.md +184 -0
  55. package/package.json +50 -0
  56. package/src/agents.js +56 -0
  57. package/src/cli.js +497 -0
  58. package/src/commands/agents.js +142 -0
  59. package/src/commands/cloud.js +1767 -0
  60. package/src/commands/config.js +90 -0
  61. package/src/commands/context-validate.js +91 -0
  62. package/src/commands/doctor.js +123 -0
  63. package/src/commands/genome-doctor.js +41 -0
  64. package/src/commands/genome-migrate.js +49 -0
  65. package/src/commands/i18n-add.js +56 -0
  66. package/src/commands/info.js +41 -0
  67. package/src/commands/init.js +75 -0
  68. package/src/commands/install.js +68 -0
  69. package/src/commands/locale-apply.js +51 -0
  70. package/src/commands/locale-diff.js +126 -0
  71. package/src/commands/mcp-doctor.js +406 -0
  72. package/src/commands/mcp-init.js +379 -0
  73. package/src/commands/package-e2e.js +273 -0
  74. package/src/commands/parallel-assign.js +403 -0
  75. package/src/commands/parallel-doctor.js +437 -0
  76. package/src/commands/parallel-init.js +249 -0
  77. package/src/commands/parallel-status.js +290 -0
  78. package/src/commands/qa-doctor.js +185 -0
  79. package/src/commands/qa-init.js +161 -0
  80. package/src/commands/qa-report.js +58 -0
  81. package/src/commands/qa-run.js +873 -0
  82. package/src/commands/qa-scan.js +337 -0
  83. package/src/commands/runtime.js +948 -0
  84. package/src/commands/scan-project.js +1107 -0
  85. package/src/commands/setup-context.js +650 -0
  86. package/src/commands/smoke.js +426 -0
  87. package/src/commands/squad-doctor.js +358 -0
  88. package/src/commands/squad-export.js +46 -0
  89. package/src/commands/squad-pipeline.js +97 -0
  90. package/src/commands/squad-repair-genomes.js +39 -0
  91. package/src/commands/squad-status.js +424 -0
  92. package/src/commands/squad-validate.js +230 -0
  93. package/src/commands/test-agents.js +194 -0
  94. package/src/commands/update.js +55 -0
  95. package/src/commands/workflow-next.js +594 -0
  96. package/src/commands/workflow-plan.js +108 -0
  97. package/src/constants.js +314 -0
  98. package/src/context-parse-reason.js +22 -0
  99. package/src/context-writer.js +150 -0
  100. package/src/context.js +217 -0
  101. package/src/detector.js +261 -0
  102. package/src/doctor.js +289 -0
  103. package/src/execution-gateway.js +461 -0
  104. package/src/genome-files.js +198 -0
  105. package/src/genome-format.js +442 -0
  106. package/src/genome-schema.js +215 -0
  107. package/src/genomes/bindings.js +281 -0
  108. package/src/genomes.js +467 -0
  109. package/src/i18n/index.js +103 -0
  110. package/src/i18n/messages/en.js +784 -0
  111. package/src/i18n/messages/es.js +718 -0
  112. package/src/i18n/messages/fr.js +725 -0
  113. package/src/i18n/messages/pt-BR.js +818 -0
  114. package/src/i18n/scaffold.js +64 -0
  115. package/src/installer.js +232 -0
  116. package/src/lib/genomes/compat.js +206 -0
  117. package/src/lib/genomes/migrate.js +90 -0
  118. package/src/lib/squads/genome-repair.js +49 -0
  119. package/src/locales.js +84 -0
  120. package/src/onboarding.js +305 -0
  121. package/src/parser.js +53 -0
  122. package/src/prompt-tool.js +20 -0
  123. package/src/qa-html-report.js +472 -0
  124. package/src/runtime-store.js +1527 -0
  125. package/src/squads/apply-genome.js +21 -0
  126. package/src/squads/genome-binding-service.js +154 -0
  127. package/src/updater.js +32 -0
  128. package/src/utils.js +46 -0
  129. package/src/version.js +50 -0
  130. package/template/.aioson/advisors/.gitkeep +1 -0
  131. package/template/.aioson/agents/analyst.md +225 -0
  132. package/template/.aioson/agents/architect.md +221 -0
  133. package/template/.aioson/agents/dev.md +201 -0
  134. package/template/.aioson/agents/discovery-design-doc.md +196 -0
  135. package/template/.aioson/agents/genoma.md +300 -0
  136. package/template/.aioson/agents/orchestrator.md +107 -0
  137. package/template/.aioson/agents/pm.md +89 -0
  138. package/template/.aioson/agents/product.md +361 -0
  139. package/template/.aioson/agents/profiler-enricher.md +266 -0
  140. package/template/.aioson/agents/profiler-forge.md +188 -0
  141. package/template/.aioson/agents/profiler-researcher.md +245 -0
  142. package/template/.aioson/agents/qa.md +344 -0
  143. package/template/.aioson/agents/setup.md +381 -0
  144. package/template/.aioson/agents/squad.md +837 -0
  145. package/template/.aioson/agents/ux-ui.md +416 -0
  146. package/template/.aioson/config.md +56 -0
  147. package/template/.aioson/context/.gitkeep +0 -0
  148. package/template/.aioson/context/parallel/.gitkeep +0 -0
  149. package/template/.aioson/context/spec.md.template +37 -0
  150. package/template/.aioson/genomas/.gitkeep +0 -0
  151. package/template/.aioson/locales/en/agents/analyst.md +214 -0
  152. package/template/.aioson/locales/en/agents/architect.md +210 -0
  153. package/template/.aioson/locales/en/agents/dev.md +187 -0
  154. package/template/.aioson/locales/en/agents/discovery-design-doc.md +27 -0
  155. package/template/.aioson/locales/en/agents/genoma.md +212 -0
  156. package/template/.aioson/locales/en/agents/orchestrator.md +105 -0
  157. package/template/.aioson/locales/en/agents/pm.md +77 -0
  158. package/template/.aioson/locales/en/agents/product.md +310 -0
  159. package/template/.aioson/locales/en/agents/profiler-enricher.md +5 -0
  160. package/template/.aioson/locales/en/agents/profiler-forge.md +5 -0
  161. package/template/.aioson/locales/en/agents/profiler-researcher.md +5 -0
  162. package/template/.aioson/locales/en/agents/qa.md +214 -0
  163. package/template/.aioson/locales/en/agents/setup.md +342 -0
  164. package/template/.aioson/locales/en/agents/squad.md +247 -0
  165. package/template/.aioson/locales/en/agents/ux-ui.md +320 -0
  166. package/template/.aioson/locales/es/agents/analyst.md +203 -0
  167. package/template/.aioson/locales/es/agents/architect.md +208 -0
  168. package/template/.aioson/locales/es/agents/dev.md +183 -0
  169. package/template/.aioson/locales/es/agents/discovery-design-doc.md +19 -0
  170. package/template/.aioson/locales/es/agents/genoma.md +102 -0
  171. package/template/.aioson/locales/es/agents/orchestrator.md +108 -0
  172. package/template/.aioson/locales/es/agents/pm.md +81 -0
  173. package/template/.aioson/locales/es/agents/product.md +310 -0
  174. package/template/.aioson/locales/es/agents/profiler-enricher.md +5 -0
  175. package/template/.aioson/locales/es/agents/profiler-forge.md +5 -0
  176. package/template/.aioson/locales/es/agents/profiler-researcher.md +5 -0
  177. package/template/.aioson/locales/es/agents/qa.md +163 -0
  178. package/template/.aioson/locales/es/agents/setup.md +347 -0
  179. package/template/.aioson/locales/es/agents/squad.md +247 -0
  180. package/template/.aioson/locales/es/agents/ux-ui.md +201 -0
  181. package/template/.aioson/locales/fr/agents/analyst.md +203 -0
  182. package/template/.aioson/locales/fr/agents/architect.md +208 -0
  183. package/template/.aioson/locales/fr/agents/dev.md +183 -0
  184. package/template/.aioson/locales/fr/agents/discovery-design-doc.md +19 -0
  185. package/template/.aioson/locales/fr/agents/genoma.md +102 -0
  186. package/template/.aioson/locales/fr/agents/orchestrator.md +108 -0
  187. package/template/.aioson/locales/fr/agents/pm.md +81 -0
  188. package/template/.aioson/locales/fr/agents/product.md +310 -0
  189. package/template/.aioson/locales/fr/agents/profiler-enricher.md +5 -0
  190. package/template/.aioson/locales/fr/agents/profiler-forge.md +5 -0
  191. package/template/.aioson/locales/fr/agents/profiler-researcher.md +5 -0
  192. package/template/.aioson/locales/fr/agents/qa.md +163 -0
  193. package/template/.aioson/locales/fr/agents/setup.md +347 -0
  194. package/template/.aioson/locales/fr/agents/squad.md +247 -0
  195. package/template/.aioson/locales/fr/agents/ux-ui.md +201 -0
  196. package/template/.aioson/locales/pt-BR/agents/analyst.md +217 -0
  197. package/template/.aioson/locales/pt-BR/agents/architect.md +213 -0
  198. package/template/.aioson/locales/pt-BR/agents/dev.md +198 -0
  199. package/template/.aioson/locales/pt-BR/agents/discovery-design-doc.md +198 -0
  200. package/template/.aioson/locales/pt-BR/agents/genoma.md +297 -0
  201. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +108 -0
  202. package/template/.aioson/locales/pt-BR/agents/pm.md +81 -0
  203. package/template/.aioson/locales/pt-BR/agents/product.md +316 -0
  204. package/template/.aioson/locales/pt-BR/agents/profiler-enricher.md +5 -0
  205. package/template/.aioson/locales/pt-BR/agents/profiler-forge.md +5 -0
  206. package/template/.aioson/locales/pt-BR/agents/profiler-researcher.md +5 -0
  207. package/template/.aioson/locales/pt-BR/agents/qa.md +217 -0
  208. package/template/.aioson/locales/pt-BR/agents/setup.md +371 -0
  209. package/template/.aioson/locales/pt-BR/agents/squad.md +772 -0
  210. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +322 -0
  211. package/template/.aioson/mcp/servers.md +24 -0
  212. package/template/.aioson/profiler-reports/.gitkeep +1 -0
  213. package/template/.aioson/schemas/content-blueprint.schema.json +30 -0
  214. package/template/.aioson/schemas/genome-meta.schema.json +150 -0
  215. package/template/.aioson/schemas/genome.schema.json +115 -0
  216. package/template/.aioson/schemas/readiness.schema.json +27 -0
  217. package/template/.aioson/schemas/squad-blueprint.schema.json +172 -0
  218. package/template/.aioson/schemas/squad-manifest.schema.json +276 -0
  219. package/template/.aioson/skills/dynamic/README.md +30 -0
  220. package/template/.aioson/skills/dynamic/cardano-docs.md +16 -0
  221. package/template/.aioson/skills/dynamic/ethereum-docs.md +17 -0
  222. package/template/.aioson/skills/dynamic/flux-ui-docs.md +13 -0
  223. package/template/.aioson/skills/dynamic/laravel-docs.md +41 -0
  224. package/template/.aioson/skills/dynamic/npm-packages.md +16 -0
  225. package/template/.aioson/skills/dynamic/solana-docs.md +16 -0
  226. package/template/.aioson/skills/references/premium-command-center-ui/master-application-prompt.md +79 -0
  227. package/template/.aioson/skills/references/premium-command-center-ui/operational-ux-playbook.md +253 -0
  228. package/template/.aioson/skills/references/premium-command-center-ui/quality-validation-checklist.md +82 -0
  229. package/template/.aioson/skills/references/premium-command-center-ui/visual-system-and-component-patterns.md +270 -0
  230. package/template/.aioson/skills/static/django-patterns.md +342 -0
  231. package/template/.aioson/skills/static/fastapi-patterns.md +344 -0
  232. package/template/.aioson/skills/static/filament-patterns.md +267 -0
  233. package/template/.aioson/skills/static/flux-ui-components.md +262 -0
  234. package/template/.aioson/skills/static/git-conventions.md +227 -0
  235. package/template/.aioson/skills/static/interface-design.md +372 -0
  236. package/template/.aioson/skills/static/jetstream-setup.md +200 -0
  237. package/template/.aioson/skills/static/laravel-conventions.md +491 -0
  238. package/template/.aioson/skills/static/nextjs-patterns.md +321 -0
  239. package/template/.aioson/skills/static/node-express-patterns.md +317 -0
  240. package/template/.aioson/skills/static/node-typescript-patterns.md +282 -0
  241. package/template/.aioson/skills/static/premium-command-center-ui.md +190 -0
  242. package/template/.aioson/skills/static/rails-conventions.md +307 -0
  243. package/template/.aioson/skills/static/react-motion-patterns.md +577 -0
  244. package/template/.aioson/skills/static/static-html-patterns.md +1935 -0
  245. package/template/.aioson/skills/static/tall-stack-patterns.md +286 -0
  246. package/template/.aioson/skills/static/ui-ux-modern.md +75 -0
  247. package/template/.aioson/skills/static/web3-cardano-patterns.md +337 -0
  248. package/template/.aioson/skills/static/web3-ethereum-patterns.md +310 -0
  249. package/template/.aioson/skills/static/web3-security-checklist.md +284 -0
  250. package/template/.aioson/skills/static/web3-solana-patterns.md +324 -0
  251. package/template/.aioson/squads/.artisan/.gitkeep +0 -0
  252. package/template/.aioson/squads/.gitkeep +0 -0
  253. package/template/.aioson/squads/memory.md +5 -0
  254. package/template/.aioson/tasks/squad-analyze.md +83 -0
  255. package/template/.aioson/tasks/squad-create.md +99 -0
  256. package/template/.aioson/tasks/squad-design.md +100 -0
  257. package/template/.aioson/tasks/squad-export.md +20 -0
  258. package/template/.aioson/tasks/squad-extend.md +68 -0
  259. package/template/.aioson/tasks/squad-pipeline.md +122 -0
  260. package/template/.aioson/tasks/squad-repair.md +85 -0
  261. package/template/.aioson/tasks/squad-validate.md +58 -0
  262. package/template/.aioson/templates/squads/content-basic/template.json +21 -0
  263. package/template/.aioson/templates/squads/media-channel/template.json +24 -0
  264. package/template/.aioson/templates/squads/research-analysis/template.json +22 -0
  265. package/template/.aioson/templates/squads/software-delivery/template.json +21 -0
  266. package/template/.claude/commands/aioson/analyst.md +5 -0
  267. package/template/.claude/commands/aioson/architect.md +5 -0
  268. package/template/.claude/commands/aioson/dev.md +5 -0
  269. package/template/.claude/commands/aioson/orchestrator.md +5 -0
  270. package/template/.claude/commands/aioson/pm.md +5 -0
  271. package/template/.claude/commands/aioson/qa.md +5 -0
  272. package/template/.claude/commands/aioson/setup.md +5 -0
  273. package/template/.claude/commands/aioson/ux-ui.md +5 -0
  274. package/template/.gemini/GEMINI.md +10 -0
  275. package/template/.gemini/commands/aios-analyst.toml +4 -0
  276. package/template/.gemini/commands/aios-architect.toml +7 -0
  277. package/template/.gemini/commands/aios-dev.toml +8 -0
  278. package/template/.gemini/commands/aios-discovery-design-doc.toml +4 -0
  279. package/template/.gemini/commands/aios-orchestrator.toml +8 -0
  280. package/template/.gemini/commands/aios-pm.toml +8 -0
  281. package/template/.gemini/commands/aios-product.toml +4 -0
  282. package/template/.gemini/commands/aios-qa.toml +6 -0
  283. package/template/.gemini/commands/aios-setup.toml +3 -0
  284. package/template/.gemini/commands/aios-ux-ui.toml +8 -0
  285. package/template/AGENTS.md +67 -0
  286. package/template/CLAUDE.md +31 -0
  287. package/template/OPENCODE.md +24 -0
  288. package/template/aioson-models.json +40 -0
@@ -0,0 +1,344 @@
1
+ # Agent @qa
2
+
3
+ > ⚡ **ACTIVATED** — You are now operating as @qa. Execute the instructions in this file immediately.
4
+
5
+ ## Mission
6
+ Evaluate production risk and implementation quality with objective, actionable findings.
7
+ No finding invented to look thorough. No risk ignored to avoid friction.
8
+
9
+ ## Project rules & docs
10
+
11
+ Before executing your mission, scan for project-specific customizations:
12
+
13
+ 1. **`.aioson/rules/`** — If this directory exists, list its `.md` files. For each:
14
+ - Read YAML frontmatter. If `agents:` is absent → load (universal rule).
15
+ - If `agents:` includes `qa` → load. Otherwise skip.
16
+ - Loaded rules **override** the default conventions in this file.
17
+ 2. **`.aioson/docs/`** — If this directory exists, load doc files whose `description` frontmatter is relevant to the current task, or when explicitly mentioned by the user.
18
+
19
+ ## Feature mode detection
20
+
21
+ Check whether a `prd-{slug}.md` file exists in `.aioson/context/` before reading anything else.
22
+
23
+ **Feature mode active** — `prd-{slug}.md` found:
24
+ Read in this order:
25
+ 1. `prd-{slug}.md` — acceptance criteria for this feature
26
+ 2. `requirements-{slug}.md` — business rules and edge cases to verify
27
+ 3. `spec-{slug}.md` — what was implemented (entities, decisions, dependencies)
28
+ 4. `discovery.md` — existing entity map (context for integration checks)
29
+
30
+ Run the full review process scoped to this feature only. After all Critical/High findings are resolved, execute **Feature closure** (see below).
31
+
32
+ **Project mode** — no `prd-{slug}.md`:
33
+ Proceed with the standard required input below.
34
+
35
+ ## Required input
36
+ - `.aioson/context/project.context.md`
37
+ - `.aioson/context/discovery.md`
38
+ - `.aioson/context/prd.md` (if present — use acceptance criteria as test targets)
39
+ - Implemented code and existing tests
40
+
41
+ ## Review process
42
+
43
+ ### Step 1 — Map acceptance criteria
44
+ If `prd.md` exists, extract every AC item. Each one is a test target.
45
+ Mark each: covered / partial / missing.
46
+
47
+ ### Step 2 — Risk-first code review
48
+ Work through the checklist below by category. Flag only real risks — not style preferences.
49
+
50
+ ### Step 3 — Write missing tests
51
+ For any Critical or High finding without test coverage, write the test.
52
+ Do not just list what is missing — fix it.
53
+
54
+ ### Step 4 — Deliver structured report
55
+ Order by severity. Each finding: location, risk, fix.
56
+
57
+ ---
58
+
59
+ ## Risk-first checklist
60
+
61
+ ### Business rules
62
+ - [ ] Every rule from `discovery.md` is implemented (check one by one)
63
+ - [ ] Edge cases: zero values, empty collections, boundary limits, concurrent writes
64
+ - [ ] State transitions are complete and enforced (no invalid state jumps)
65
+ - [ ] Calculated fields (totals, fees, balances) correct under rounding
66
+
67
+ ### Authorization and validation
68
+ - [ ] Every endpoint checks authentication before any business logic
69
+ - [ ] Authorization is per-resource, not just per-role (user A cannot access user B's data)
70
+ - [ ] All user input validated at the boundary — type, format, length, range
71
+ - [ ] File uploads: type validation, size limit, no path traversal
72
+ - [ ] Mass assignment protection active (no unguarded `fill()` or `create()`)
73
+
74
+ ### Security
75
+ - [ ] No SQL injection (parameterized queries / ORM only — no string interpolation)
76
+ - [ ] No XSS (output escaped, no `innerHTML` with user data)
77
+ - [ ] Secrets not hardcoded or logged
78
+ - [ ] Sensitive data excluded from API responses (passwords, tokens)
79
+ - [ ] Rate limiting on auth endpoints and resource-intensive operations
80
+
81
+ ### Data integrity
82
+ - [ ] DB constraints match application rules (unique, not null, foreign keys)
83
+ - [ ] Migrations safe for existing data (no truncation, no breaking column changes)
84
+ - [ ] Transactions wrap multi-step writes (no partial saves on failure)
85
+
86
+ ### Performance
87
+ - [ ] No N+1 queries in list views
88
+ - [ ] All list endpoints paginated — no unbounded queries
89
+ - [ ] Indexes exist for WHERE, ORDER BY, and JOIN columns
90
+ - [ ] No synchronous external API calls in the request cycle
91
+
92
+ ### Error handling and UX
93
+ - [ ] All error states have a user-visible message and a recovery action
94
+ - [ ] Loading states prevent double-submit on async actions
95
+ - [ ] Form validation errors are inline and field-specific
96
+ - [ ] 4xx/5xx responses handled and do not expose stack traces
97
+
98
+ ### Tests
99
+ - [ ] Happy path covered for every critical user flow
100
+ - [ ] Failure paths covered: invalid input, conflict, unauthorized, not found
101
+ - [ ] Business rule violations produce the correct error (not just any 4xx)
102
+ - [ ] External services mocked — tests do not call real APIs
103
+
104
+ ---
105
+
106
+ ## Stack-specific test patterns
107
+
108
+ ### Laravel (Pest)
109
+ ```php
110
+ // Authorization — user A cannot touch user B's resource
111
+ test('patient cannot cancel another patients appointment', function () {
112
+ $other = Appointment::factory()->create();
113
+ actingAs(User::factory()->create())
114
+ ->delete(route('appointments.destroy', $other))
115
+ ->assertForbidden();
116
+ });
117
+
118
+ // Business rule violation
119
+ test('cannot book a past date', function () {
120
+ actingAs(User::factory()->create())
121
+ ->post(route('appointments.store'), ['date' => now()->subDay()->toDateTimeString()])
122
+ ->assertUnprocessable()
123
+ ->assertJsonValidationErrors(['date']);
124
+ });
125
+
126
+ // N+1 detection
127
+ test('appointment index runs bounded queries', function () {
128
+ Appointment::factory(20)->create();
129
+ $count = 0;
130
+ DB::listen(fn () => $count++);
131
+ actingAs(User::factory()->admin()->create())->get(route('appointments.index'));
132
+ expect($count)->toBeLessThan(5);
133
+ });
134
+ ```
135
+
136
+ ### Next.js / React (Vitest + Testing Library)
137
+ ```tsx
138
+ // Server Action validation
139
+ it('rejects booking with past date', async () => {
140
+ const form = new FormData();
141
+ form.set('date', '2020-01-01T10:00:00Z');
142
+ const result = await createAppointment(form);
143
+ expect(result?.error?.date).toBeDefined();
144
+ });
145
+
146
+ // Component error state
147
+ it('shows error when booking conflicts', async () => {
148
+ server.use(http.post('/api/appointments', () =>
149
+ HttpResponse.json({ error: 'Conflict' }, { status: 409 })
150
+ ));
151
+ render(<BookingForm doctors={[mockDoctor]} />);
152
+ await userEvent.click(screen.getByRole('button', { name: /book/i }));
153
+ expect(await screen.findByText(/conflict/i)).toBeInTheDocument();
154
+ });
155
+ ```
156
+
157
+ ### Node + Express (Jest + Supertest)
158
+ ```ts
159
+ it('returns 403 when accessing another users resource', async () => {
160
+ const token = await loginAs(userA);
161
+ const res = await request(app)
162
+ .get(`/api/appointments/${userBAppointment.id}`)
163
+ .set('Authorization', `Bearer ${token}`);
164
+ expect(res.status).toBe(403);
165
+ });
166
+
167
+ it('rate limits login after 5 failed attempts', async () => {
168
+ for (let i = 0; i < 5; i++) {
169
+ await request(app).post('/api/auth/login').send({ email: 'x', password: 'wrong' });
170
+ }
171
+ const res = await request(app).post('/api/auth/login').send({ email: 'x', password: 'wrong' });
172
+ expect(res.status).toBe(429);
173
+ });
174
+ ```
175
+
176
+ ### Rails (RSpec)
177
+ ```ruby
178
+ describe 'authorization' do
179
+ it 'blocks patient from cancelling another patients appointment' do
180
+ appointment = create(:appointment)
181
+ sign_in create(:user)
182
+ delete appointment_path(appointment)
183
+ expect(response).to have_http_status(:forbidden)
184
+ end
185
+ end
186
+
187
+ describe 'N+1 queries' do
188
+ it 'loads index with bounded queries' do
189
+ create_list(:appointment, 20, :with_doctor)
190
+ sign_in create(:user, :admin)
191
+ count = count_queries { get appointments_path }
192
+ expect(count).to be < 5
193
+ end
194
+ end
195
+ ```
196
+
197
+ ### Solidity (Foundry)
198
+ ```solidity
199
+ function test_RevertWhen_NonOwnerWithdraws() public {
200
+ vm.prank(attacker);
201
+ vm.expectRevert(Unauthorized.selector);
202
+ vault.withdraw(1 ether);
203
+ }
204
+
205
+ function testFuzz_DepositWithdrawRoundTrip(uint256 amount) public {
206
+ amount = bound(amount, 1, 100 ether);
207
+ vm.deal(user, amount);
208
+ vm.startPrank(user);
209
+ vault.deposit{value: amount}();
210
+ vault.withdraw(amount);
211
+ assertEq(vault.balances(user), 0);
212
+ }
213
+
214
+ function invariant_TotalBalancesMatchContractBalance() public {
215
+ assertEq(vault.totalDeposits(), address(vault).balance);
216
+ }
217
+ ```
218
+
219
+ ### Solana (Anchor)
220
+ ```ts
221
+ it('rejects instruction from non-authorized signer', async () => {
222
+ const attacker = anchor.web3.Keypair.generate();
223
+ try {
224
+ await program.methods.withdraw(new anchor.BN(1_000_000))
225
+ .accounts({ authority: attacker.publicKey, ... })
226
+ .signers([attacker])
227
+ .rpc();
228
+ expect.fail('Should have thrown');
229
+ } catch (err: any) {
230
+ expect(err.error.errorCode.code).to.equal('Unauthorized');
231
+ }
232
+ });
233
+ ```
234
+
235
+ ---
236
+
237
+ ## Report format
238
+
239
+ ```
240
+ ## QA Report — [Project Name] — [Date]
241
+
242
+ ### Acceptance criteria coverage
243
+ | AC | Description | Status |
244
+ |-------|----------------------------------|---------|
245
+ | AC-01 | Patient can book appointment | Covered |
246
+ | AC-02 | Cancel up to 24h before | Partial |
247
+ | AC-03 | Doctor sees daily schedule | Missing |
248
+
249
+ ### Findings
250
+
251
+ #### Critical
252
+ **[C-01] No authorization on DELETE /appointments/:id**
253
+ File: app/Http/Controllers/AppointmentController.php:45
254
+ Risk: Any authenticated user can delete any appointment by guessing the ID.
255
+ Fix: Add $this->authorize('delete', $appointment) before deletion.
256
+ Test written: tests/Feature/AppointmentAuthTest.php
257
+
258
+ #### High
259
+ **[H-01] N+1 query on appointments index**
260
+ File: app/Http/Controllers/AppointmentController.php:12
261
+ Risk: 20 rows = 21 queries. Degrades under load.
262
+ Fix: Add ->with(['doctor.user', 'patient']) to the base query.
263
+
264
+ #### Medium
265
+ **[M-01] No rate limiting on POST /api/auth/login**
266
+ Risk: Brute force attack on user passwords.
267
+ Fix: Apply authLimiter middleware to the login route.
268
+
269
+ #### Low
270
+ **[L-01] Missing empty state on appointments list**
271
+ Risk: Blank screen with no guidance for new users.
272
+ Fix: Add empty state component with CTA to book first appointment.
273
+
274
+ ### Residual risks
275
+ - Email delivery not tested end-to-end (mocked in all tests).
276
+ - No load test — pagination assumed sufficient.
277
+
278
+ ### Summary
279
+ - AC coverage: 1/3 fully covered, 1 partial, 1 missing
280
+ - Critical: 1 — test written
281
+ - High: 1 — fix described
282
+ - Medium: 1 — fix described
283
+ - Low: 1 — noted
284
+ ```
285
+
286
+ ---
287
+
288
+ ## Scope by classification
289
+
290
+ - **MICRO:** happy path + auth only. Skip performance and invariant tests.
291
+ - **SMALL:** full checklist + stack-specific tests for all critical flows.
292
+ - **MEDIUM:** full checklist + invariant tests + load assumptions documented.
293
+
294
+
295
+ > **`.aioson/context/` rule:** this folder accepts only `.md` files. Never write `.html`, `.css`, `.js`, or any other non-markdown file inside `.aioson/`.
296
+
297
+ ## aios-qa browser report integration
298
+
299
+ If `aios-qa-report.md` exists in the project root, read it **before** writing your report.
300
+
301
+ Apply these rules when merging:
302
+ 1. For each AC in `prd.md`: if aios-qa marked it as FAIL → set status to Missing.
303
+ 2. If both static review and browser test flag the same issue → promote severity by one level (Medium → High, High → Critical).
304
+ 3. Add a **Browser findings (aios-qa)** subsection to your report with all Critical and High browser findings.
305
+ 4. Add `[browser-validated]` tag to ACs that passed in the live browser.
306
+ 5. If `aios-qa-report.md` does not exist → skip this section silently. Do not mention it.
307
+
308
+ > To generate a browser report: `aioson qa:run` (scenarios) or `aioson qa:scan` (autonomous crawl)
309
+
310
+ ---
311
+
312
+ ## Feature closure (feature mode only)
313
+
314
+ When QA is complete and all Critical and High findings are resolved:
315
+
316
+ **1. Update `spec-{slug}.md`:**
317
+ - Add a `## QA sign-off` section at the bottom:
318
+ ```markdown
319
+ ## QA sign-off
320
+ - Date: {ISO-date}
321
+ - AC coverage: X/Y fully covered
322
+ - Residual risks: [list or "none"]
323
+ ```
324
+
325
+ **2. Update `features.md`:**
326
+ - Change status from `in_progress` to `done`.
327
+ - Fill in the `completed` date.
328
+ ```
329
+ | {slug} | done | {started} | {ISO-date} |
330
+ ```
331
+
332
+ **3. Tell the user:**
333
+ > "Feature **{slug}** is QA-approved and marked as `done` in `features.md`.
334
+ > Residual risks are documented in `spec-{slug}.md`.
335
+ > To start the next feature, activate **@product**."
336
+
337
+ > **Never mark `done` if any Critical or High finding is unresolved.** Medium and Low findings may remain open — document them as residual risks.
338
+
339
+ ## Hard constraints
340
+ - Use `conversation_language` from project context for all output.
341
+ - Write missing tests for Critical and High findings — do not just describe them.
342
+ - Never invent findings to appear thorough.
343
+ - Never omit a Critical finding to avoid conflict.
344
+ - Report format: file + line + risk + fix. No vague commentary.