@jaimevalasek/aioson 1.7.2 → 1.8.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 (362) hide show
  1. package/CHANGELOG.md +35 -0
  2. package/README.md +153 -10
  3. package/docs/en/cli-reference.md +56 -1
  4. package/docs/en/i18n.md +18 -18
  5. package/docs/en/schemas/index.json +10 -0
  6. package/docs/en/schemas/parallel-assign.schema.json +9 -0
  7. package/docs/en/schemas/parallel-doctor.schema.json +36 -0
  8. package/docs/en/schemas/parallel-guard.schema.json +63 -0
  9. package/docs/en/schemas/parallel-merge.schema.json +84 -0
  10. package/docs/en/schemas/parallel-status.schema.json +91 -1
  11. package/docs/integrations/apps-publish-marketplace.md +94 -0
  12. package/docs/pt/README.md +9 -0
  13. package/docs/pt/agentes.md +324 -3
  14. package/docs/pt/clientes-ai.md +7 -3
  15. package/docs/pt/comandos-cli.md +160 -13
  16. package/docs/pt/compress-agents.md +304 -0
  17. package/docs/pt/design-docs-governance.md +59 -0
  18. package/docs/pt/feature-archive.md +191 -0
  19. package/docs/pt/genome-3.0-spec.md +115 -4
  20. package/docs/pt/genome-distribution.md +232 -0
  21. package/docs/pt/inicio-rapido.md +1 -0
  22. package/docs/pt/motor-hardening.md +492 -0
  23. package/docs/pt/runner-system.md +113 -0
  24. package/package.json +2 -1
  25. package/src/agent-manifests.js +66 -0
  26. package/src/agents.js +27 -7
  27. package/src/autonomy-policy.js +139 -0
  28. package/src/brain-query.js +161 -0
  29. package/src/cli.js +1377 -1099
  30. package/src/commands/agents.js +102 -7
  31. package/src/commands/artifact-validate.js +33 -4
  32. package/src/commands/auth.js +272 -0
  33. package/src/commands/brain-query.js +44 -0
  34. package/src/commands/briefing.js +344 -0
  35. package/src/commands/commit-prepare.js +547 -0
  36. package/src/commands/compress-agents.js +416 -0
  37. package/src/commands/context-health.js +4 -2
  38. package/src/commands/context-trim.js +17 -11
  39. package/src/commands/design-hybrid-options.js +3 -3
  40. package/src/commands/devlog-process.js +6 -4
  41. package/src/commands/dossier.js +423 -0
  42. package/src/commands/feature-archive.js +513 -0
  43. package/src/commands/feature-close.js +123 -18
  44. package/src/commands/gate-approve.js +198 -0
  45. package/src/commands/gate-check.js +24 -5
  46. package/src/commands/genome-doctor.js +166 -9
  47. package/src/commands/git-guard.js +170 -0
  48. package/src/commands/harness.js +121 -0
  49. package/src/commands/implementation-plan.js +47 -20
  50. package/src/commands/init.js +6 -2
  51. package/src/commands/install.js +6 -2
  52. package/src/commands/live.js +497 -56
  53. package/src/commands/locale-apply.js +9 -6
  54. package/src/commands/locale-diff.js +11 -112
  55. package/src/commands/mcp-doctor.js +2 -1
  56. package/src/commands/mcp-init.js +4 -10
  57. package/src/commands/memory.js +234 -0
  58. package/src/commands/parallel-assign.js +107 -27
  59. package/src/commands/parallel-doctor.js +416 -3
  60. package/src/commands/parallel-guard.js +241 -0
  61. package/src/commands/parallel-init.js +66 -4
  62. package/src/commands/parallel-merge.js +299 -0
  63. package/src/commands/parallel-status.js +147 -3
  64. package/src/commands/preflight.js +63 -4
  65. package/src/commands/qa-init.js +10 -5
  66. package/src/commands/revision.js +235 -0
  67. package/src/commands/scaffold-complete.js +188 -0
  68. package/src/commands/security-audit.js +275 -0
  69. package/src/commands/security-scan.js +376 -0
  70. package/src/commands/self-implement-loop.js +46 -2
  71. package/src/commands/setup-context.js +11 -10
  72. package/src/commands/squad-agent-create.js +51 -9
  73. package/src/commands/squad-investigate.js +53 -0
  74. package/src/commands/squad-plan.js +33 -1
  75. package/src/commands/squad-scaffold.js +4 -3
  76. package/src/commands/squad-score.js +71 -14
  77. package/src/commands/squad-status.js +22 -1
  78. package/src/commands/squad-validate.js +93 -2
  79. package/src/commands/store-genome.js +304 -0
  80. package/src/commands/store-skill.js +247 -0
  81. package/src/commands/store-squad.js +431 -0
  82. package/src/commands/store-system.js +392 -0
  83. package/src/commands/tool-capabilities.js +63 -0
  84. package/src/commands/update.js +3 -3
  85. package/src/commands/verify-gate.js +40 -0
  86. package/src/commands/workflow-execute.js +644 -155
  87. package/src/commands/workflow-harden.js +231 -0
  88. package/src/commands/workflow-heal.js +136 -0
  89. package/src/commands/workflow-next.js +460 -22
  90. package/src/commands/workflow-status.js +328 -138
  91. package/src/commands/workspace.js +144 -0
  92. package/src/constants.js +42 -75
  93. package/src/context-memory.js +133 -4
  94. package/src/context-writer.js +2 -1
  95. package/src/context.js +32 -2
  96. package/src/doctor.js +46 -6
  97. package/src/dossier/codemap-store.js +267 -0
  98. package/src/dossier/dossier-bootstrap.js +222 -0
  99. package/src/dossier/dossier-compact.js +159 -0
  100. package/src/dossier/lock.js +128 -0
  101. package/src/dossier/revision-store.js +313 -0
  102. package/src/dossier/schema.js +155 -0
  103. package/src/dossier/store.js +400 -0
  104. package/src/execution-gateway.js +3 -0
  105. package/src/friction-scanner.js +202 -0
  106. package/src/genome-schema.js +24 -1
  107. package/src/genomes.js +33 -0
  108. package/src/handoff-contract.js +363 -0
  109. package/src/handoff-validator.js +45 -0
  110. package/src/harness/circuit-breaker.js +135 -0
  111. package/src/i18n/messages/en.js +317 -22
  112. package/src/i18n/messages/es.js +259 -18
  113. package/src/i18n/messages/fr.js +260 -18
  114. package/src/i18n/messages/pt-BR.js +313 -22
  115. package/src/install-profile.js +0 -16
  116. package/src/installer.js +70 -6
  117. package/src/lib/git-commit-guard.js +691 -0
  118. package/src/lib/security/artifact-reader.js +167 -0
  119. package/src/lib/security/exit-codes.js +51 -0
  120. package/src/lib/security/findings-writer.js +176 -0
  121. package/src/lib/security/runtime-events.js +77 -0
  122. package/src/lib/security/secrets-regex.js +115 -0
  123. package/src/lib/store/security-scan.js +173 -0
  124. package/src/lib/terminal-checkbox.js +130 -0
  125. package/src/lib/tmux-launcher.js +163 -0
  126. package/src/lib/tool-capabilities.js +102 -0
  127. package/src/locales.js +12 -8
  128. package/src/parallel-workspace.js +756 -0
  129. package/src/parser.js +8 -1
  130. package/src/path-guard.js +47 -0
  131. package/src/preflight-engine.js +237 -26
  132. package/src/self-healing.js +142 -0
  133. package/src/session-handoff.js +111 -1
  134. package/src/squad/squad-scaffold.js +183 -19
  135. package/src/test-briefing.js +226 -0
  136. package/src/updater.js +1 -1
  137. package/src/utils.js +3 -0
  138. package/src/workflow-gates.js +185 -0
  139. package/template/.aioson/agents/analyst.md +76 -130
  140. package/template/.aioson/agents/architect.md +53 -86
  141. package/template/.aioson/agents/committer.md +161 -0
  142. package/template/.aioson/agents/cypher.md +252 -0
  143. package/template/.aioson/agents/dev.md +112 -628
  144. package/template/.aioson/agents/deyvin.md +33 -236
  145. package/template/.aioson/agents/discover.md +235 -0
  146. package/template/.aioson/agents/discovery-design-doc.md +17 -252
  147. package/template/.aioson/agents/genome.md +76 -26
  148. package/template/.aioson/agents/manifests/analyst.manifest.json +26 -0
  149. package/template/.aioson/agents/manifests/architect.manifest.json +23 -0
  150. package/template/.aioson/agents/manifests/committer.manifest.json +23 -0
  151. package/template/.aioson/agents/manifests/dev.manifest.json +37 -0
  152. package/template/.aioson/agents/manifests/orchestrator.manifest.json +30 -0
  153. package/template/.aioson/agents/manifests/pentester.manifest.json +39 -0
  154. package/template/.aioson/agents/manifests/pm.manifest.json +26 -0
  155. package/template/.aioson/agents/manifests/product.manifest.json +23 -0
  156. package/template/.aioson/agents/manifests/qa.manifest.json +25 -0
  157. package/template/.aioson/agents/manifests/setup.manifest.json +20 -0
  158. package/template/.aioson/agents/manifests/ux-ui.manifest.json +24 -0
  159. package/template/.aioson/agents/neo.md +5 -7
  160. package/template/.aioson/agents/orache.md +2 -6
  161. package/template/.aioson/agents/orchestrator.md +81 -182
  162. package/template/.aioson/agents/pentester.md +235 -0
  163. package/template/.aioson/agents/pm.md +40 -104
  164. package/template/.aioson/agents/product.md +99 -344
  165. package/template/.aioson/agents/profiler-enricher.md +57 -6
  166. package/template/.aioson/agents/profiler-forge.md +17 -7
  167. package/template/.aioson/agents/profiler-researcher.md +29 -6
  168. package/template/.aioson/agents/qa.md +168 -514
  169. package/template/.aioson/agents/setup.md +52 -278
  170. package/template/.aioson/agents/sheldon.md +122 -754
  171. package/template/.aioson/agents/site-forge.md +111 -1583
  172. package/template/.aioson/agents/squad.md +139 -2010
  173. package/template/.aioson/agents/tester.md +10 -0
  174. package/template/.aioson/agents/ux-ui.md +104 -812
  175. package/template/.aioson/agents/validator.md +69 -0
  176. package/template/.aioson/brains/scripts/query.js +5 -1
  177. package/template/.aioson/config/autonomy-protocol.json +43 -0
  178. package/template/.aioson/config.md +43 -15
  179. package/template/.aioson/constitution.md +36 -33
  180. package/template/.aioson/context/design-doc.md +136 -0
  181. package/template/.aioson/context/project-map.md +57 -0
  182. package/template/.aioson/design-docs/code-reuse.md +48 -0
  183. package/template/.aioson/design-docs/componentization.md +47 -0
  184. package/template/.aioson/design-docs/file-size.md +52 -0
  185. package/template/.aioson/design-docs/folder-structure.md +51 -0
  186. package/template/.aioson/design-docs/naming.md +54 -0
  187. package/template/.aioson/docs/LAYERS.md +12 -2
  188. package/template/.aioson/docs/dev/execution-discipline.md +106 -0
  189. package/template/.aioson/docs/dev/stack-conventions.md +83 -0
  190. package/template/.aioson/docs/deyvin/continuity-recovery.md +57 -0
  191. package/template/.aioson/docs/deyvin/debugging-escalation.md +30 -0
  192. package/template/.aioson/docs/deyvin/pair-execution.md +44 -0
  193. package/template/.aioson/docs/deyvin/runtime-handoffs.md +36 -0
  194. package/template/.aioson/docs/product/conversation-playbook.md +116 -0
  195. package/template/.aioson/docs/product/prd-contract.md +107 -0
  196. package/template/.aioson/docs/product/quality-lens.md +57 -0
  197. package/template/.aioson/docs/product/research-loop.md +65 -0
  198. package/template/.aioson/docs/sheldon/enrichment-paths.md +134 -0
  199. package/template/.aioson/docs/sheldon/quality-lens.md +57 -0
  200. package/template/.aioson/docs/sheldon/research-loop.md +56 -0
  201. package/template/.aioson/docs/sheldon/web-intelligence.md +75 -0
  202. package/template/.aioson/docs/site-forge-build.md +195 -0
  203. package/template/.aioson/docs/site-forge-extraction.md +135 -0
  204. package/template/.aioson/docs/site-forge-qa.md +155 -0
  205. package/template/.aioson/docs/site-forge-recon.md +434 -0
  206. package/template/.aioson/docs/site-forge-transform.md +249 -0
  207. package/template/.aioson/docs/squad/content-output.md +91 -0
  208. package/template/.aioson/docs/squad/creation-flow.md +135 -0
  209. package/template/.aioson/docs/squad/domain-classification.md +117 -0
  210. package/template/.aioson/docs/squad/genome-bindings.md +47 -0
  211. package/template/.aioson/docs/squad/package-contract.md +234 -0
  212. package/template/.aioson/docs/squad/quality-lens.md +56 -0
  213. package/template/.aioson/docs/squad/research-loop.md +59 -0
  214. package/template/.aioson/docs/squad/session-operations.md +117 -0
  215. package/template/.aioson/docs/squad/workflow-quality.md +165 -0
  216. package/template/.aioson/docs/ux-ui/accessibility-audit.md +55 -0
  217. package/template/.aioson/docs/ux-ui/audit-mode.md +86 -0
  218. package/template/.aioson/docs/ux-ui/component-map.md +35 -0
  219. package/template/.aioson/docs/ux-ui/design-execution.md +111 -0
  220. package/template/.aioson/docs/ux-ui/design-gate.md +27 -0
  221. package/template/.aioson/docs/ux-ui/research-mode.md +39 -0
  222. package/template/.aioson/docs/ux-ui/site-delivery.md +156 -0
  223. package/template/.aioson/docs/ux-ui/token-contract.md +57 -0
  224. package/template/.aioson/genomes/copywriting.meta.json +48 -0
  225. package/template/.aioson/git-guard.json +11 -0
  226. package/template/.aioson/mcp/servers.md +0 -1
  227. package/template/.aioson/rules/agent-language-policy.md +93 -0
  228. package/template/.aioson/rules/aioson-context-boundary.md +63 -0
  229. package/template/.aioson/rules/canonical-path-contract.md +47 -0
  230. package/template/.aioson/rules/data-format-convention.md +24 -86
  231. package/template/.aioson/rules/disk-first-artifacts.md +44 -0
  232. package/template/.aioson/rules/output-brevity.md +44 -0
  233. package/template/.aioson/rules/prd-section-ownership.md +49 -0
  234. package/template/.aioson/rules/security-baseline.md +139 -0
  235. package/template/.aioson/rules/spec-level-ownership.md +61 -0
  236. package/template/.aioson/rules/squad-driver-pattern.md +81 -0
  237. package/template/.aioson/schemas/squad-blueprint.schema.json +24 -0
  238. package/template/.aioson/schemas/squad-manifest.schema.json +44 -0
  239. package/template/.aioson/skills/process/aioson-spec-driven/references/pm.md +30 -0
  240. package/template/.aioson/skills/process/secure-tdd/SKILL.md +97 -0
  241. package/template/.aioson/skills/process/secure-tdd/references/nextjs.md +81 -0
  242. package/template/.aioson/skills/process/secure-tdd/references/node-express.md +91 -0
  243. package/template/.aioson/skills/process/secure-tdd/references/planned-stacks.md +33 -0
  244. package/template/.aioson/skills/static/harness-validate/SKILL.md +46 -0
  245. package/template/.aioson/skills/static/web-research-cache.md +3 -0
  246. package/template/.aioson/tasks/squad-create.md +35 -8
  247. package/template/.aioson/tasks/squad-design.md +50 -2
  248. package/template/.aioson/tasks/squad-investigate.md +14 -1
  249. package/template/.claude/commands/aioson/agent/committer.md +5 -0
  250. package/template/.claude/commands/aioson/agent/copywriter.md +5 -0
  251. package/template/.claude/commands/aioson/agent/cypher.md +5 -0
  252. package/template/.claude/commands/aioson/agent/pair.md +5 -0
  253. package/template/.claude/commands/aioson/agent/validator.md +5 -0
  254. package/template/.gemini/commands/aios-analyst.toml +6 -3
  255. package/template/.gemini/commands/aios-architect.toml +7 -6
  256. package/template/.gemini/commands/aios-committer.toml +7 -0
  257. package/template/.gemini/commands/aios-copywriter.toml +7 -0
  258. package/template/.gemini/commands/aios-cypher.toml +7 -0
  259. package/template/.gemini/commands/aios-dev.toml +8 -7
  260. package/template/.gemini/commands/aios-deyvin.toml +6 -5
  261. package/template/.gemini/commands/aios-discovery-design-doc.toml +6 -3
  262. package/template/.gemini/commands/aios-genome.toml +7 -0
  263. package/template/.gemini/commands/aios-neo.toml +5 -3
  264. package/template/.gemini/commands/aios-orache.toml +7 -0
  265. package/template/.gemini/commands/aios-orchestrator.toml +8 -7
  266. package/template/.gemini/commands/aios-pair.toml +6 -5
  267. package/template/.gemini/commands/aios-pm.toml +8 -7
  268. package/template/.gemini/commands/aios-product.toml +5 -3
  269. package/template/.gemini/commands/aios-qa.toml +6 -5
  270. package/template/.gemini/commands/aios-setup.toml +5 -2
  271. package/template/.gemini/commands/aios-sheldon.toml +7 -0
  272. package/template/.gemini/commands/aios-site-forge.toml +7 -0
  273. package/template/.gemini/commands/aios-squad.toml +7 -0
  274. package/template/.gemini/commands/aios-tester.toml +6 -5
  275. package/template/.gemini/commands/aios-ux-ui.toml +8 -7
  276. package/template/.gemini/commands/aios-validator.toml +7 -0
  277. package/template/AGENTS.md +12 -1
  278. package/template/CLAUDE.md +5 -1
  279. package/template/.aioson/locales/en/agents/analyst.md +0 -244
  280. package/template/.aioson/locales/en/agents/architect.md +0 -245
  281. package/template/.aioson/locales/en/agents/dev.md +0 -397
  282. package/template/.aioson/locales/en/agents/deyvin.md +0 -137
  283. package/template/.aioson/locales/en/agents/discovery-design-doc.md +0 -27
  284. package/template/.aioson/locales/en/agents/genome.md +0 -212
  285. package/template/.aioson/locales/en/agents/neo.md +0 -8
  286. package/template/.aioson/locales/en/agents/orache.md +0 -6
  287. package/template/.aioson/locales/en/agents/orchestrator.md +0 -189
  288. package/template/.aioson/locales/en/agents/pair.md +0 -5
  289. package/template/.aioson/locales/en/agents/pm.md +0 -84
  290. package/template/.aioson/locales/en/agents/product.md +0 -378
  291. package/template/.aioson/locales/en/agents/profiler-enricher.md +0 -5
  292. package/template/.aioson/locales/en/agents/profiler-forge.md +0 -5
  293. package/template/.aioson/locales/en/agents/profiler-researcher.md +0 -5
  294. package/template/.aioson/locales/en/agents/qa.md +0 -270
  295. package/template/.aioson/locales/en/agents/setup.md +0 -421
  296. package/template/.aioson/locales/en/agents/sheldon.md +0 -455
  297. package/template/.aioson/locales/en/agents/squad.md +0 -449
  298. package/template/.aioson/locales/en/agents/tester.md +0 -6
  299. package/template/.aioson/locales/en/agents/ux-ui.md +0 -668
  300. package/template/.aioson/locales/es/agents/analyst.md +0 -225
  301. package/template/.aioson/locales/es/agents/architect.md +0 -245
  302. package/template/.aioson/locales/es/agents/dev.md +0 -370
  303. package/template/.aioson/locales/es/agents/deyvin.md +0 -99
  304. package/template/.aioson/locales/es/agents/discovery-design-doc.md +0 -21
  305. package/template/.aioson/locales/es/agents/genome.md +0 -104
  306. package/template/.aioson/locales/es/agents/neo.md +0 -50
  307. package/template/.aioson/locales/es/agents/orache.md +0 -105
  308. package/template/.aioson/locales/es/agents/orchestrator.md +0 -194
  309. package/template/.aioson/locales/es/agents/pair.md +0 -7
  310. package/template/.aioson/locales/es/agents/pm.md +0 -90
  311. package/template/.aioson/locales/es/agents/product.md +0 -372
  312. package/template/.aioson/locales/es/agents/profiler-enricher.md +0 -7
  313. package/template/.aioson/locales/es/agents/profiler-forge.md +0 -7
  314. package/template/.aioson/locales/es/agents/profiler-researcher.md +0 -7
  315. package/template/.aioson/locales/es/agents/qa.md +0 -198
  316. package/template/.aioson/locales/es/agents/setup.md +0 -405
  317. package/template/.aioson/locales/es/agents/sheldon.md +0 -309
  318. package/template/.aioson/locales/es/agents/squad.md +0 -532
  319. package/template/.aioson/locales/es/agents/tester.md +0 -9
  320. package/template/.aioson/locales/es/agents/ux-ui.md +0 -212
  321. package/template/.aioson/locales/fr/agents/analyst.md +0 -225
  322. package/template/.aioson/locales/fr/agents/architect.md +0 -245
  323. package/template/.aioson/locales/fr/agents/dev.md +0 -370
  324. package/template/.aioson/locales/fr/agents/deyvin.md +0 -99
  325. package/template/.aioson/locales/fr/agents/discovery-design-doc.md +0 -21
  326. package/template/.aioson/locales/fr/agents/genome.md +0 -104
  327. package/template/.aioson/locales/fr/agents/neo.md +0 -50
  328. package/template/.aioson/locales/fr/agents/orache.md +0 -106
  329. package/template/.aioson/locales/fr/agents/orchestrator.md +0 -194
  330. package/template/.aioson/locales/fr/agents/pair.md +0 -7
  331. package/template/.aioson/locales/fr/agents/pm.md +0 -90
  332. package/template/.aioson/locales/fr/agents/product.md +0 -372
  333. package/template/.aioson/locales/fr/agents/profiler-enricher.md +0 -7
  334. package/template/.aioson/locales/fr/agents/profiler-forge.md +0 -7
  335. package/template/.aioson/locales/fr/agents/profiler-researcher.md +0 -7
  336. package/template/.aioson/locales/fr/agents/qa.md +0 -198
  337. package/template/.aioson/locales/fr/agents/setup.md +0 -405
  338. package/template/.aioson/locales/fr/agents/sheldon.md +0 -309
  339. package/template/.aioson/locales/fr/agents/squad.md +0 -532
  340. package/template/.aioson/locales/fr/agents/tester.md +0 -9
  341. package/template/.aioson/locales/fr/agents/ux-ui.md +0 -212
  342. package/template/.aioson/locales/pt-BR/agents/analyst.md +0 -319
  343. package/template/.aioson/locales/pt-BR/agents/architect.md +0 -284
  344. package/template/.aioson/locales/pt-BR/agents/dev.md +0 -483
  345. package/template/.aioson/locales/pt-BR/agents/deyvin.md +0 -184
  346. package/template/.aioson/locales/pt-BR/agents/discovery-design-doc.md +0 -198
  347. package/template/.aioson/locales/pt-BR/agents/genome.md +0 -297
  348. package/template/.aioson/locales/pt-BR/agents/neo.md +0 -208
  349. package/template/.aioson/locales/pt-BR/agents/orache.md +0 -137
  350. package/template/.aioson/locales/pt-BR/agents/orchestrator.md +0 -324
  351. package/template/.aioson/locales/pt-BR/agents/pair.md +0 -5
  352. package/template/.aioson/locales/pt-BR/agents/pm.md +0 -182
  353. package/template/.aioson/locales/pt-BR/agents/product.md +0 -466
  354. package/template/.aioson/locales/pt-BR/agents/profiler-enricher.md +0 -5
  355. package/template/.aioson/locales/pt-BR/agents/profiler-forge.md +0 -5
  356. package/template/.aioson/locales/pt-BR/agents/profiler-researcher.md +0 -5
  357. package/template/.aioson/locales/pt-BR/agents/qa.md +0 -300
  358. package/template/.aioson/locales/pt-BR/agents/setup.md +0 -533
  359. package/template/.aioson/locales/pt-BR/agents/sheldon.md +0 -323
  360. package/template/.aioson/locales/pt-BR/agents/squad.md +0 -1330
  361. package/template/.aioson/locales/pt-BR/agents/tester.md +0 -449
  362. package/template/.aioson/locales/pt-BR/agents/ux-ui.md +0 -669
@@ -0,0 +1,167 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+
6
+ const ARTIFACT_NAMES = Object.freeze([
7
+ { key: 'prd', name: (slug) => `prd-${slug}.md` },
8
+ { key: 'requirements', name: (slug) => `requirements-${slug}.md` },
9
+ { key: 'architecture', name: () => 'architecture.md' },
10
+ { key: 'implementation_plan', name: (slug) => `implementation-plan-${slug}.md` },
11
+ { key: 'spec', name: (slug) => `spec-${slug}.md` },
12
+ { key: 'conformance', name: (slug) => `conformance-${slug}.yaml` }
13
+ ]);
14
+
15
+ async function readSlugArtifacts(targetDir, slug) {
16
+ const baseDir = path.join(targetDir, '.aioson', 'context');
17
+ const result = { slug, baseDir, artifacts: {} };
18
+ for (const def of ARTIFACT_NAMES) {
19
+ const filePath = path.join(baseDir, def.name(slug));
20
+ try {
21
+ const content = await fs.readFile(filePath, 'utf8');
22
+ result.artifacts[def.key] = { path: filePath, content, present: true };
23
+ } catch (err) {
24
+ if (err && err.code === 'ENOENT') {
25
+ result.artifacts[def.key] = { path: filePath, content: null, present: false };
26
+ } else {
27
+ throw err;
28
+ }
29
+ }
30
+ }
31
+ return result;
32
+ }
33
+
34
+ function extractClassification(content) {
35
+ if (!content) return null;
36
+ const match = content.match(/^classification:\s*["']?([A-Z]+)["']?/m);
37
+ return match ? match[1].toUpperCase() : null;
38
+ }
39
+
40
+ function hasSection(content, headerRegex) {
41
+ if (!content) return false;
42
+ return headerRegex.test(content);
43
+ }
44
+
45
+ const TABLE_ROW_TO_SURFACE = Object.freeze({
46
+ 'authenticated endpoints': 'auth',
47
+ 'owned resources': 'ownership',
48
+ 'financial state changes': 'money',
49
+ uploads: 'uploads',
50
+ 'external urls': 'external_urls',
51
+ 'secrets or credentials': 'secrets',
52
+ 'storage boundaries': 'storage',
53
+ 'pentester trigger': 'pentester_trigger'
54
+ });
55
+
56
+ const NON_APPLICABLE_SURFACE_PATTERNS = [
57
+ /\bnone introduced\b/i,
58
+ /\bno new\b/i,
59
+ /\bn\/a\b/i,
60
+ /\bnot applicable\b/i,
61
+ /\bout of scope\b/i,
62
+ /\bnot required\b/i,
63
+ /\bfuture\b/i,
64
+ /\bwhen present\b/i,
65
+ /\blater verif(?:y|ies)\b/i,
66
+ /\bdefines controls\b/i,
67
+ /\bphase \d+\b/i,
68
+ /\.aioson\//i,
69
+ /\btemplate sync\b/i,
70
+ /\bruntime sqlite\b/i
71
+ ];
72
+
73
+ function extractAttackSurfaceSection(requirementsContent) {
74
+ if (!requirementsContent) return null;
75
+ const lines = requirementsContent.split(/\r?\n/);
76
+ const startIndex = lines.findIndex((line) => /^##\s+Attack Surface(?: Map)?\b/i.test(line));
77
+ if (startIndex === -1) return null;
78
+ const sectionLines = [];
79
+ for (let i = startIndex + 1; i < lines.length; i += 1) {
80
+ if (/^##\s+/.test(lines[i])) break;
81
+ sectionLines.push(lines[i]);
82
+ }
83
+ return sectionLines.join('\n');
84
+ }
85
+
86
+ function normalizeSurfaceLabel(label) {
87
+ return String(label || '')
88
+ .toLowerCase()
89
+ .replace(/[`*_]/g, '')
90
+ .replace(/\s+/g, ' ')
91
+ .trim();
92
+ }
93
+
94
+ function parseAttackSurfaceRows(sectionContent) {
95
+ if (!sectionContent) return [];
96
+ const rows = [];
97
+ for (const rawLine of sectionContent.split(/\r?\n/)) {
98
+ const line = rawLine.trim();
99
+ if (!line.startsWith('|')) continue;
100
+ const cells = line
101
+ .split('|')
102
+ .slice(1, -1)
103
+ .map((cell) => cell.trim());
104
+ if (cells.length < 2) continue;
105
+ const [label, value] = cells;
106
+ if (!label || /^-+$/.test(label.replace(/\s+/g, ''))) continue;
107
+ if (!value || /^-+$/.test(value.replace(/\s+/g, ''))) continue;
108
+ if (normalizeSurfaceLabel(label) === 'surface') continue;
109
+ rows.push({ label, value });
110
+ }
111
+ return rows;
112
+ }
113
+
114
+ function isApplicableSurfaceValue(value) {
115
+ const normalized = String(value || '').trim();
116
+ if (!normalized) return false;
117
+ return !NON_APPLICABLE_SURFACE_PATTERNS.some((pattern) => pattern.test(normalized));
118
+ }
119
+
120
+ function extractAttackSurfaceFlags(requirementsContent) {
121
+ if (!requirementsContent) {
122
+ return { hasMap: false, surfaces: [] };
123
+ }
124
+ const section = extractAttackSurfaceSection(requirementsContent);
125
+ const hasMap = Boolean(section) || /##\s+Attack Surface Map|##\s+Attack Surface\b/i.test(requirementsContent);
126
+ const surfaces = [];
127
+ if (section) {
128
+ const seen = new Set();
129
+ const rows = parseAttackSurfaceRows(section);
130
+ for (const row of rows) {
131
+ const key = TABLE_ROW_TO_SURFACE[normalizeSurfaceLabel(row.label)];
132
+ if (!key || key === 'pentester_trigger') continue;
133
+ if (!isApplicableSurfaceValue(row.value) || seen.has(key)) continue;
134
+ seen.add(key);
135
+ surfaces.push(key);
136
+ }
137
+ if (rows.length > 0) {
138
+ return { hasMap, surfaces };
139
+ }
140
+ }
141
+
142
+ const checks = [
143
+ { key: 'auth', re: /authenticated_endpoints|authenticated endpoints|\bauth\b/i },
144
+ { key: 'ownership', re: /owned[_ -]?resources|ownership/i },
145
+ { key: 'money', re: /financial[_ -]?state[_ -]?changes|payments?|money/i },
146
+ { key: 'uploads', re: /uploads?/i },
147
+ { key: 'external_urls', re: /external[_ -]?urls?/i },
148
+ { key: 'secrets', re: /secrets?[_ -]?or[_ -]?credentials|api[_ -]?keys?/i },
149
+ { key: 'storage', re: /storage[_ -]?boundaries?|rls\b/i }
150
+ ];
151
+ const fallbackContent = section || requirementsContent;
152
+ for (const c of checks) {
153
+ if (c.re.test(fallbackContent)) surfaces.push(c.key);
154
+ }
155
+ return { hasMap, surfaces };
156
+ }
157
+
158
+ module.exports = {
159
+ ARTIFACT_NAMES,
160
+ readSlugArtifacts,
161
+ extractClassification,
162
+ hasSection,
163
+ extractAttackSurfaceFlags,
164
+ extractAttackSurfaceSection,
165
+ parseAttackSurfaceRows,
166
+ isApplicableSurfaceValue
167
+ };
@@ -0,0 +1,51 @@
1
+ 'use strict';
2
+
3
+ const EXIT_CODES = Object.freeze({
4
+ PASS: 0,
5
+ BLOCKING: 10,
6
+ INCONCLUSIVE: 11,
7
+ BAD_INPUT: 12,
8
+ CONTRACT_VIOLATION: 13
9
+ });
10
+
11
+ const SEVERITY_RANK = Object.freeze({
12
+ critical: 5,
13
+ high: 4,
14
+ medium: 3,
15
+ low: 2,
16
+ info: 1,
17
+ advisory: 0,
18
+ inconclusive: -1
19
+ });
20
+
21
+ function isBlockingSeverity(severity) {
22
+ return severity === 'critical' || severity === 'high';
23
+ }
24
+
25
+ function resolveExitCode({ classification, findings, hasInconclusive, strict }) {
26
+ const cls = String(classification || 'MICRO').toUpperCase();
27
+ const blocking = findings.some(
28
+ (f) => f.status === 'open' && isBlockingSeverity(f.severity)
29
+ );
30
+
31
+ if (strict && findings.some((f) => f.status === 'open')) {
32
+ return EXIT_CODES.BLOCKING;
33
+ }
34
+
35
+ if (cls === 'MEDIUM' && blocking) {
36
+ return EXIT_CODES.BLOCKING;
37
+ }
38
+
39
+ if (hasInconclusive) {
40
+ return EXIT_CODES.INCONCLUSIVE;
41
+ }
42
+
43
+ return EXIT_CODES.PASS;
44
+ }
45
+
46
+ module.exports = {
47
+ EXIT_CODES,
48
+ SEVERITY_RANK,
49
+ isBlockingSeverity,
50
+ resolveExitCode
51
+ };
@@ -0,0 +1,176 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs/promises');
4
+ const path = require('node:path');
5
+ const crypto = require('node:crypto');
6
+
7
+ const SCHEMA_VERSION = '1.0.0';
8
+ const MAX_FINDINGS = 500;
9
+ const ARTIFACT_DIR = path.join('.aioson', 'context');
10
+ const PRESERVED_STATUSES_ON_REDETECT = new Set(['accepted', 'accepted_risk', 'false_positive']);
11
+
12
+ function hash6(input) {
13
+ return crypto.createHash('sha1').update(String(input)).digest('hex').slice(0, 6);
14
+ }
15
+
16
+ function buildFindingId({ source, control_id, scope }) {
17
+ return `${source}-${control_id}-${hash6(scope || '')}`;
18
+ }
19
+
20
+ function normalizeFinding(input, { generator }) {
21
+ const finding_id = input.finding_id || buildFindingId({
22
+ source: input.source,
23
+ control_id: input.control_id,
24
+ scope: input.scope
25
+ });
26
+ return {
27
+ finding_id,
28
+ source: input.source,
29
+ control_id: input.control_id,
30
+ severity: input.severity,
31
+ status: input.status || 'open',
32
+ scope: input.scope,
33
+ affected_artifacts: Array.isArray(input.affected_artifacts) ? [...input.affected_artifacts] : [],
34
+ preconditions: Array.isArray(input.preconditions) ? [...input.preconditions] : [],
35
+ reproduction_steps: Array.isArray(input.reproduction_steps) ? [...input.reproduction_steps] : [],
36
+ evidence: Array.isArray(input.evidence) ? [...input.evidence] : [],
37
+ impact: input.impact || '',
38
+ suggested_fix: input.suggested_fix || '',
39
+ recommended_owner: input.recommended_owner || 'dev',
40
+ recommended_gate_status: input.recommended_gate_status || gateStatusFromSeverity(input.severity),
41
+ safe_to_reproduce: input.safe_to_reproduce !== false,
42
+ detected_by: generator
43
+ };
44
+ }
45
+
46
+ function gateStatusFromSeverity(severity) {
47
+ if (severity === 'critical' || severity === 'high') return 'block';
48
+ if (severity === 'medium') return 'review';
49
+ return 'note';
50
+ }
51
+
52
+ function sortFindings(findings) {
53
+ return [...findings].sort((a, b) => a.finding_id.localeCompare(b.finding_id));
54
+ }
55
+
56
+ function summarize(findings) {
57
+ const summary = { critical: 0, high: 0, medium: 0, low: 0, inconclusive: 0 };
58
+ for (const f of findings) {
59
+ if (f.status !== 'open' && f.status !== 'needs_validation') continue;
60
+ if (f.severity === 'inconclusive') {
61
+ summary.inconclusive += 1;
62
+ } else if (summary[f.severity] !== undefined) {
63
+ summary[f.severity] += 1;
64
+ }
65
+ }
66
+ return summary;
67
+ }
68
+
69
+ function artifactPathFor(targetDir, slug) {
70
+ const safeSlug = slug && slug.length > 0 ? slug : 'project';
71
+ return path.join(targetDir, ARTIFACT_DIR, `security-findings-${safeSlug}.json`);
72
+ }
73
+
74
+ async function readArtifact(artifactPath) {
75
+ try {
76
+ const raw = await fs.readFile(artifactPath, 'utf8');
77
+ const parsed = JSON.parse(raw);
78
+ if (!parsed || typeof parsed !== 'object' || !Array.isArray(parsed.findings)) {
79
+ return null;
80
+ }
81
+ return parsed;
82
+ } catch (err) {
83
+ if (err && err.code === 'ENOENT') return null;
84
+ throw err;
85
+ }
86
+ }
87
+
88
+ function mergeFindings(existing, incoming) {
89
+ const byId = new Map();
90
+ for (const f of existing) {
91
+ byId.set(f.finding_id, f);
92
+ }
93
+ const seenIncoming = new Set();
94
+ for (const f of incoming) {
95
+ seenIncoming.add(f.finding_id);
96
+ const prior = byId.get(f.finding_id);
97
+ if (
98
+ prior &&
99
+ PRESERVED_STATUSES_ON_REDETECT.has(prior.status) &&
100
+ (f.status === 'open' || f.status === 'needs_validation')
101
+ ) {
102
+ byId.set(f.finding_id, { ...f, status: prior.status });
103
+ continue;
104
+ }
105
+ byId.set(f.finding_id, { ...f });
106
+ }
107
+ for (const f of existing) {
108
+ if (!seenIncoming.has(f.finding_id) && (f.status === 'open' || f.status === 'needs_validation')) {
109
+ byId.set(f.finding_id, { ...f, status: 'fixed' });
110
+ }
111
+ }
112
+ return sortFindings([...byId.values()]);
113
+ }
114
+
115
+ async function writeFindings({
116
+ targetDir,
117
+ slug,
118
+ source,
119
+ generator,
120
+ generatedAt,
121
+ scopeMode,
122
+ findings
123
+ }) {
124
+ const artifactPath = artifactPathFor(targetDir, slug);
125
+ const normalized = findings.map((f) => normalizeFinding({ ...f, source: f.source || source }, { generator }));
126
+
127
+ const existing = await readArtifact(artifactPath);
128
+ const previous = existing && Array.isArray(existing.findings) ? existing.findings : [];
129
+ const merged = mergeFindings(previous, normalized);
130
+
131
+ if (merged.length > MAX_FINDINGS) {
132
+ return {
133
+ ok: false,
134
+ reason: 'contract_violation_too_many_findings',
135
+ count: merged.length,
136
+ max: MAX_FINDINGS,
137
+ artifactPath
138
+ };
139
+ }
140
+
141
+ const payload = {
142
+ schema_version: SCHEMA_VERSION,
143
+ slug: slug || 'project',
144
+ generated_at: generatedAt,
145
+ generator,
146
+ review_contract: {
147
+ scope_mode: scopeMode,
148
+ evidence_policy: 'high_critical_require_reproduction',
149
+ findings_artifact_path: path.posix.join('.aioson', 'context', `security-findings-${slug || 'project'}.json`)
150
+ },
151
+ summary: summarize(merged),
152
+ findings: merged
153
+ };
154
+
155
+ await fs.mkdir(path.dirname(artifactPath), { recursive: true });
156
+ const json = JSON.stringify(payload, null, 2) + '\n';
157
+ await fs.writeFile(artifactPath, json, 'utf8');
158
+
159
+ return { ok: true, artifactPath, payload };
160
+ }
161
+
162
+ module.exports = {
163
+ SCHEMA_VERSION,
164
+ MAX_FINDINGS,
165
+ ARTIFACT_DIR,
166
+ buildFindingId,
167
+ hash6,
168
+ gateStatusFromSeverity,
169
+ normalizeFinding,
170
+ summarize,
171
+ sortFindings,
172
+ mergeFindings,
173
+ artifactPathFor,
174
+ readArtifact,
175
+ writeFindings
176
+ };
@@ -0,0 +1,77 @@
1
+ 'use strict';
2
+
3
+ const { openRuntimeDb, appendRunEvent } = require('../../runtime-store');
4
+ const { recordRuntimeOperation, makeWorkflowSessionKey } = require('../../execution-gateway');
5
+
6
+ function normalizeText(value) {
7
+ return String(value || '').trim();
8
+ }
9
+
10
+ async function emitSecurityRuntimeEvent({
11
+ targetDir,
12
+ eventType,
13
+ message,
14
+ payload = null,
15
+ runKey = null,
16
+ status = 'completed',
17
+ agentName = 'qa',
18
+ source = 'direct',
19
+ workflowState = null,
20
+ workflowStage = null
21
+ }) {
22
+ if (!targetDir || !eventType) {
23
+ return { ok: false, reason: 'missing_target_or_event' };
24
+ }
25
+
26
+ try {
27
+ if (runKey) {
28
+ const handle = await openRuntimeDb(targetDir);
29
+ try {
30
+ appendRunEvent(handle.db, {
31
+ runKey,
32
+ eventType,
33
+ phase: 'security',
34
+ status,
35
+ message: normalizeText(message) || eventType,
36
+ payload: payload && typeof payload === 'object' ? payload : null,
37
+ toolName: 'aioson'
38
+ });
39
+ return { ok: true, dbPath: handle.dbPath, runKey };
40
+ } finally {
41
+ handle.db.close();
42
+ }
43
+ }
44
+
45
+ const workflowId = workflowState ? makeWorkflowSessionKey(workflowState) : null;
46
+ const featureSlug = normalizeText(workflowState && workflowState.featureSlug);
47
+ const resolvedStage = normalizeText(workflowStage || (workflowState && workflowState.current) || '');
48
+
49
+ return await recordRuntimeOperation(targetDir, {
50
+ agentName,
51
+ source,
52
+ workflowId: workflowId || null,
53
+ workflowStage: resolvedStage || null,
54
+ sessionKey: workflowId
55
+ ? `${workflowId}:security:${eventType}:${Date.now()}`
56
+ : `security:${eventType}:${Date.now()}`,
57
+ title: featureSlug
58
+ ? `Security event ${eventType} (${featureSlug})`
59
+ : `Security event ${eventType}`,
60
+ runTitle: eventType,
61
+ goal: featureSlug
62
+ ? `Registrar ${eventType} para ${featureSlug}`
63
+ : `Registrar ${eventType}`,
64
+ phase: 'security',
65
+ eventType,
66
+ status,
67
+ message: normalizeText(message) || eventType,
68
+ summary: normalizeText(message) || eventType,
69
+ payload: payload && typeof payload === 'object' ? payload : null,
70
+ toolName: 'aioson'
71
+ });
72
+ } catch {
73
+ return { ok: false, reason: 'runtime_emit_failed' };
74
+ }
75
+ }
76
+
77
+ module.exports = { emitSecurityRuntimeEvent };
@@ -0,0 +1,115 @@
1
+ 'use strict';
2
+
3
+ const ALLOW_MARKERS = Object.freeze([
4
+ 'EXAMPLE',
5
+ 'example',
6
+ 'dummy',
7
+ 'DUMMY',
8
+ 'placeholder',
9
+ 'PLACEHOLDER',
10
+ 'your-key-here',
11
+ 'YOUR_KEY_HERE',
12
+ 'xxxxxxxx',
13
+ 'XXXXXXXX',
14
+ '<replace',
15
+ 'REPLACE_ME',
16
+ 'changeme',
17
+ 'CHANGEME'
18
+ ]);
19
+
20
+ const ALLOW_PATH_SUFFIXES = Object.freeze([
21
+ '.env.example',
22
+ '.env.sample',
23
+ '.env.template'
24
+ ]);
25
+
26
+ const PATTERNS = Object.freeze([
27
+ {
28
+ id: 'aws-access-key',
29
+ name: 'AWS access key',
30
+ pattern: /\bAKIA[0-9A-Z]{16}\b/g,
31
+ severity: 'critical',
32
+ control: 'SEC-SBD-05'
33
+ },
34
+ {
35
+ id: 'stripe-live-key',
36
+ name: 'Stripe live secret key',
37
+ pattern: /\bsk_live_[A-Za-z0-9]{24,}\b/g,
38
+ severity: 'critical',
39
+ control: 'SEC-SBD-05'
40
+ },
41
+ {
42
+ id: 'openai-api-key',
43
+ name: 'OpenAI API key',
44
+ pattern: /\bsk-[A-Za-z0-9]{20,}\b/g,
45
+ severity: 'high',
46
+ control: 'SEC-SBD-05'
47
+ },
48
+ {
49
+ id: 'anthropic-api-key',
50
+ name: 'Anthropic API key',
51
+ pattern: /\bsk-ant-[A-Za-z0-9_-]{20,}\b/g,
52
+ severity: 'high',
53
+ control: 'SEC-SBD-05'
54
+ },
55
+ {
56
+ id: 'rsa-private-key',
57
+ name: 'RSA / SSH private key block',
58
+ pattern: /-----BEGIN (?:RSA |OPENSSH |DSA |EC |PGP )?PRIVATE KEY-----/g,
59
+ severity: 'critical',
60
+ control: 'SEC-SBD-05'
61
+ },
62
+ {
63
+ id: 'generic-password-assignment',
64
+ name: 'Inline password assignment',
65
+ pattern: /\b(?:password|passwd|pwd)\s*[:=]\s*['"][^'"\s]{8,}['"]/gi,
66
+ severity: 'high',
67
+ control: 'SEC-SBD-05'
68
+ },
69
+ {
70
+ id: 'generic-token-assignment',
71
+ name: 'Inline token / api_key assignment with long value',
72
+ pattern: /\b(?:api[_-]?key|access[_-]?token|secret[_-]?token|auth[_-]?token)\s*[:=]\s*['"][A-Za-z0-9._-]{20,}['"]/gi,
73
+ severity: 'high',
74
+ control: 'SEC-SBD-05'
75
+ }
76
+ ]);
77
+
78
+ const FORBIDDEN_FILES = Object.freeze([
79
+ '.env',
80
+ '.env.local',
81
+ '.env.production',
82
+ '.env.staging',
83
+ 'id_rsa',
84
+ 'id_ed25519',
85
+ 'id_dsa',
86
+ 'id_ecdsa'
87
+ ]);
88
+
89
+ function isAllowedByMarkers(line) {
90
+ for (const marker of ALLOW_MARKERS) {
91
+ if (line.indexOf(marker) !== -1) {
92
+ return true;
93
+ }
94
+ }
95
+ return false;
96
+ }
97
+
98
+ function isAllowedByPath(filePath) {
99
+ const lower = filePath.toLowerCase();
100
+ for (const suffix of ALLOW_PATH_SUFFIXES) {
101
+ if (lower.endsWith(suffix)) {
102
+ return true;
103
+ }
104
+ }
105
+ return false;
106
+ }
107
+
108
+ module.exports = {
109
+ PATTERNS,
110
+ FORBIDDEN_FILES,
111
+ ALLOW_MARKERS,
112
+ ALLOW_PATH_SUFFIXES,
113
+ isAllowedByMarkers,
114
+ isAllowedByPath
115
+ };