@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
@@ -3,11 +3,22 @@
3
3
  const fs = require('node:fs/promises');
4
4
  const path = require('node:path');
5
5
  const { getAgentDefinition, resolveInstructionPath, buildAgentPrompt } = require('../agents');
6
- const { resolveAgentLocale } = require('../locales');
7
- const { validateProjectContextFile } = require('../context');
6
+ const { normalizeInteractionLanguage } = require('../locales');
7
+ const { validateProjectContextFile, getInteractionLanguage } = require('../context');
8
8
  const { exists, ensureDir } = require('../utils');
9
9
  const { syncWorkflowRuntime } = require('../execution-gateway');
10
- const { writeHandoff, buildWorkflowHandoff } = require('../session-handoff');
10
+ const { writeHandoff, buildWorkflowHandoff, buildWorkflowHandoffProtocol } = require('../session-handoff');
11
+ const { runTechnicalGate, formatGateError } = require('../workflow-gates');
12
+ const { buildTestBriefing } = require('../test-briefing');
13
+ const { validateHandoffContract, formatContractError, getBlockingRevisions } = require('../handoff-contract');
14
+ const { buildPathGuardBlock } = require('../path-guard');
15
+ const { logError, buildHealingPrompt } = require('../self-healing');
16
+ const { validateHandoffProtocol } = require('../handoff-validator');
17
+ const { readAutonomyProtocol, resolveEffectiveMode } = require('../autonomy-policy');
18
+ const { readAgentManifest, buildAgentCapabilitySummary } = require('../agent-manifests');
19
+ const { inspectStagedChanges } = require('../lib/git-commit-guard');
20
+ const { emitSecurityRuntimeEvent } = require('../lib/security/runtime-events');
21
+ const { runSecurityAudit } = require('./security-audit');
11
22
 
12
23
  const STATE_RELATIVE_PATH = '.aioson/context/workflow.state.json';
13
24
  const CONFIG_RELATIVE_PATH = '.aioson/context/workflow.config.json';
@@ -16,7 +27,7 @@ const EVENTS_RELATIVE_PATH = '.aioson/context/workflow.events.jsonl';
16
27
  const DEFAULT_FEATURE_WORKFLOW_BY_CLASSIFICATION = {
17
28
  MICRO: ['product', 'dev', 'qa'],
18
29
  SMALL: ['product', 'analyst', 'dev', 'qa'],
19
- MEDIUM: ['product', 'analyst', 'dev', 'qa']
30
+ MEDIUM: ['product', 'analyst', 'dev', 'pentester', 'qa']
20
31
  };
21
32
 
22
33
  function normalizeAgentName(input) {
@@ -63,7 +74,8 @@ function parseFeaturesMarkdown(markdown) {
63
74
  started: parts[3],
64
75
  completed: parts[4]
65
76
  }))
66
- .filter((row) => row.slug && row.slug !== 'slug');
77
+ .filter((row) => row.slug && row.slug !== 'slug')
78
+ .filter((row) => !/^-+$/ .test(row.slug));
67
79
  }
68
80
 
69
81
  async function readJsonIfExists(filePath) {
@@ -155,11 +167,11 @@ async function readWorkflowConfig(targetDir) {
155
167
 
156
168
  async function resolveLocaleForTarget(targetDir, options) {
157
169
  const fromOption = options.language || options.lang;
158
- if (fromOption) return resolveAgentLocale(fromOption);
170
+ if (fromOption) return normalizeInteractionLanguage(fromOption);
159
171
 
160
172
  const context = await validateProjectContextFile(targetDir);
161
- if (context.parsed && context.data && context.data.conversation_language) {
162
- return resolveAgentLocale(context.data.conversation_language);
173
+ if (context.parsed && context.data) {
174
+ return getInteractionLanguage(context.data, 'en');
163
175
  }
164
176
 
165
177
  return 'en';
@@ -270,12 +282,134 @@ function findNextFromSequence(sequence, completed, skipped) {
270
282
  return sequence.find((stage) => !done.has(normalizeAgentName(stage))) || null;
271
283
  }
272
284
 
285
+ function reconcileWorkflowState(state) {
286
+ if (!state || typeof state !== 'object' || !Array.isArray(state.sequence)) {
287
+ return { state, changed: false };
288
+ }
289
+
290
+ const sequence = state.sequence.map(normalizeAgentName);
291
+ const completed = Array.from(new Set((state.completed || []).map(normalizeAgentName).filter(Boolean)));
292
+ const skippedSet = new Set((state.skipped || []).map(normalizeAgentName).filter(Boolean));
293
+ const detour = state.detour && typeof state.detour === 'object'
294
+ ? {
295
+ ...state.detour,
296
+ agent: normalizeAgentName(state.detour.agent),
297
+ returnTo: normalizeAgentName(state.detour.returnTo)
298
+ }
299
+ : null;
300
+ let changed = false;
301
+
302
+ // If a later stage is already completed, any unresolved earlier stage was
303
+ // effectively bypassed outside the workflow and must not remain "active".
304
+ const furthestCompletedIndex = sequence.reduce((max, stage, index) => (
305
+ completed.includes(stage) ? Math.max(max, index) : max
306
+ ), -1);
307
+
308
+ if (furthestCompletedIndex >= 0) {
309
+ for (let index = 0; index < furthestCompletedIndex; index += 1) {
310
+ const stage = sequence[index];
311
+ if (!completed.includes(stage) && !skippedSet.has(stage)) {
312
+ skippedSet.add(stage);
313
+ changed = true;
314
+ }
315
+ }
316
+ }
317
+
318
+ const skipped = sequence.filter((stage) => skippedSet.has(stage));
319
+ const resolved = new Set([...completed, ...skipped]);
320
+ let current = state.current ? normalizeAgentName(state.current) : null;
321
+ let next = state.next ? normalizeAgentName(state.next) : null;
322
+ const currentIsActiveDetour = Boolean(
323
+ detour &&
324
+ detour.active &&
325
+ current &&
326
+ current === detour.agent
327
+ );
328
+
329
+ if (current && ((!sequence.includes(current) && !currentIsActiveDetour) || resolved.has(current))) {
330
+ current = null;
331
+ changed = true;
332
+ }
333
+
334
+ if (!detour || !detour.active) {
335
+ if (current) {
336
+ const currentIndex = sequence.indexOf(current);
337
+ const expectedQueuedNext = sequence.find(
338
+ (stage, index) => index > currentIndex && !resolved.has(stage)
339
+ ) || null;
340
+ if (next && next !== current && next !== expectedQueuedNext) {
341
+ next = expectedQueuedNext || current;
342
+ changed = true;
343
+ } else if (!next) {
344
+ next = expectedQueuedNext || current;
345
+ changed = true;
346
+ }
347
+ } else {
348
+ const inferredNext = findNextFromSequence(sequence, completed, skipped);
349
+ if (next !== inferredNext) {
350
+ next = inferredNext;
351
+ changed = true;
352
+ }
353
+ }
354
+ }
355
+
356
+ if (!changed) {
357
+ return { state, changed: false };
358
+ }
359
+
360
+ return {
361
+ changed: true,
362
+ state: buildStatePayload({
363
+ ...state,
364
+ sequence,
365
+ completed,
366
+ skipped,
367
+ current,
368
+ next,
369
+ detour
370
+ })
371
+ };
372
+ }
373
+
273
374
  function isInferableStage(stage) {
274
375
  return ['setup', 'product', 'analyst', 'architect', 'ux-ui', 'orchestrator'].includes(
275
376
  normalizeAgentName(stage)
276
377
  );
277
378
  }
278
379
 
380
+ function isSecurityGateBlocked(contractCheck, state, stageName) {
381
+ if (normalizeAgentName(stageName) !== 'qa' || state.mode !== 'feature' || !state.featureSlug) {
382
+ return false;
383
+ }
384
+ return contractCheck.missing.some((item) =>
385
+ item.includes('security:') ||
386
+ item.includes(`security-findings-${state.featureSlug}.json`)
387
+ );
388
+ }
389
+
390
+ function buildQaSecurityAuditBriefing(result, targetDir) {
391
+ if (!result) return '';
392
+
393
+ if (result.ok === false && result.reason) {
394
+ return [
395
+ '## Secure by Default audit',
396
+ `- Auto-run failed before QA review: ${result.reason}.`,
397
+ '- Gate D will remain blocked until a valid `security-findings-{slug}.json` artifact exists.',
398
+ '- If CLI is unavailable in your client, use the fallback checklist and record the limitation explicitly in the QA report and `project-pulse.md`.'
399
+ ].join('\n');
400
+ }
401
+
402
+ return [
403
+ '## Secure by Default audit',
404
+ `- Auto-ran \`security:audit\` for feature \`${result.slug}\` at QA activation.`,
405
+ `- Exit code: ${result.exitCode}. Findings: ${result.findingsCount}.`,
406
+ `- Summary: critical=${result.summary.critical}, high=${result.summary.high}, medium=${result.summary.medium}, low=${result.summary.low}, inconclusive=${result.summary.inconclusive}.`,
407
+ `- Artifact: \`${path.relative(targetDir, result.artifactPath)}\`.`,
408
+ '- If the audit or manual heuristics indicate auth, money, or ownership risk, invoke `@pentester` with `--mode=app_target --feature=<slug> --scope=<target>` before final Gate D sign-off.',
409
+ '- If CLI is unavailable in your client, use the fallback checklist and record the limitation explicitly in the QA report and `project-pulse.md`.'
410
+ ].join('\n');
411
+ }
412
+
279
413
  async function inferCompletedStages(targetDir, draftState) {
280
414
  const completed = [];
281
415
  for (const stage of draftState.sequence) {
@@ -291,7 +425,11 @@ async function loadOrCreateState(targetDir, options = {}) {
291
425
  const statePath = path.join(targetDir, STATE_RELATIVE_PATH);
292
426
  const existing = await readJsonIfExists(statePath);
293
427
  if (existing && typeof existing === 'object' && Array.isArray(existing.sequence)) {
294
- return { statePath, state: existing, created: false };
428
+ const reconciled = reconcileWorkflowState(existing);
429
+ if (reconciled.changed) {
430
+ await writeJson(statePath, reconciled.state);
431
+ }
432
+ return { statePath, state: reconciled.state, created: false };
295
433
  }
296
434
 
297
435
  const context = await validateProjectContextFile(targetDir);
@@ -371,6 +509,27 @@ async function finalizeCurrentStage(targetDir, config, state, stageName) {
371
509
  throw new Error('No stage is active to complete.');
372
510
  }
373
511
 
512
+ // ── Harness Done Gate ───────────────────────────────────────────────────
513
+ if (state.mode === 'feature' && state.featureSlug) {
514
+ const contractPath = path.join(targetDir, '.aioson', 'plans', state.featureSlug, 'harness-contract.json');
515
+ const progressPath = path.join(targetDir, '.aioson', 'plans', state.featureSlug, 'progress.json');
516
+
517
+ // Se contrato existe, verificamos o progresso
518
+ const fs = require('node:fs');
519
+ if (fs.existsSync(contractPath) && fs.existsSync(progressPath)) {
520
+ try {
521
+ const progress = JSON.parse(fs.readFileSync(progressPath, 'utf8'));
522
+ // Bloqueia se não estiver pronto para o gate E o estágio for crítico (dev/qa)
523
+ if (!progress.ready_for_done_gate && (normalizedStage === 'dev' || normalizedStage === 'qa')) {
524
+ throw new Error(`[Harness Block] A feature "${state.featureSlug}" não passou na validação contratual. Execute 'aioson harness:validate' e resolva os problemas antes de concluir o estágio @${normalizedStage}.`);
525
+ }
526
+ } catch (err) {
527
+ if (err.message.includes('[Harness Block]')) throw err;
528
+ // Se erro de parse, ignoramos para não quebrar o workflow por corrupção
529
+ }
530
+ }
531
+ }
532
+
374
533
  if (state.detour && state.detour.active && normalizeAgentName(state.detour.agent) === normalizedStage) {
375
534
  const validDetour = await validateStageArtifacts(targetDir, state, normalizedStage);
376
535
  if (!validDetour) {
@@ -391,6 +550,56 @@ async function finalizeCurrentStage(targetDir, config, state, stageName) {
391
550
  throw new Error(`Cannot complete ${normalizedStage}; expected artifacts are missing.`);
392
551
  }
393
552
 
553
+ // ── Handoff Contract Gate ───────────────────────────────────────────────
554
+ const contractCheck = await validateHandoffContract(targetDir, state, normalizedStage);
555
+ if (!contractCheck.ok) {
556
+ if (isSecurityGateBlocked(contractCheck, state, normalizedStage)) {
557
+ await emitSecurityRuntimeEvent({
558
+ targetDir,
559
+ eventType: 'security_gate_blocked',
560
+ message: `Gate D blocked for ${state.featureSlug} at @qa`,
561
+ status: 'failed',
562
+ agentName: 'qa',
563
+ source: 'workflow',
564
+ workflowState: state,
565
+ workflowStage: 'qa',
566
+ payload: {
567
+ feature_slug: state.featureSlug,
568
+ classification: state.classification,
569
+ blockers: contractCheck.missing
570
+ }
571
+ });
572
+ }
573
+ const errMsg = formatContractError(contractCheck);
574
+ await logError(targetDir, normalizedStage, errMsg, 'contract');
575
+ throw new Error(errMsg);
576
+ }
577
+
578
+ // ── Revision Gate (Phase 2) ─────────────────────────────────────────────
579
+ const blockingRevisions = await getBlockingRevisions(targetDir, state.featureSlug);
580
+ if (blockingRevisions.length > 0) {
581
+ const ids = blockingRevisions.map((r) => r.id).join(', ');
582
+ const errMsg = [
583
+ `[Revision Gate BLOCKED]`,
584
+ `Feature: ${state.featureSlug}`,
585
+ ``,
586
+ `Pending blocking revision(s): ${ids}`,
587
+ ``,
588
+ `Resolve each revision before completing this stage:`,
589
+ ...blockingRevisions.map((r) => ` aioson revision:resolve . --slug=${state.featureSlug} --rev-id=${r.id} --approve|--reject`)
590
+ ].join('\n');
591
+ await logError(targetDir, normalizedStage, errMsg, 'revision');
592
+ throw new Error(errMsg);
593
+ }
594
+
595
+ // ── Technical Compilation/Test Gate ─────────────────────────────────────
596
+ const techGate = await runTechnicalGate(targetDir, normalizedStage);
597
+ if (!techGate.ok) {
598
+ const errMsg = formatGateError(techGate);
599
+ await logError(targetDir, normalizedStage, errMsg, 'technical');
600
+ throw new Error(errMsg);
601
+ }
602
+
394
603
  const completed = Array.from(new Set([...(state.completed || []), normalizedStage]));
395
604
  const next = findNextFromSequence(state.sequence, completed, state.skipped || []);
396
605
  const nextState = buildStatePayload({
@@ -423,7 +632,7 @@ function applySkip(config, state, target) {
423
632
  });
424
633
  }
425
634
 
426
- async function activateStage(targetDir, state, locale, tool, explicitAgent = null) {
635
+ async function activateStage(targetDir, state, locale, tool, explicitAgent = null, requestedMode = null) {
427
636
  const stageName = normalizeAgentName(explicitAgent || state.current || state.next);
428
637
  if (!stageName) {
429
638
  return {
@@ -434,13 +643,109 @@ async function activateStage(targetDir, state, locale, tool, explicitAgent = nul
434
643
  };
435
644
  }
436
645
 
646
+ // ── Committer Safety Gate ───────────────────────────────────────────────
647
+ if (stageName === 'committer') {
648
+ const guard = await inspectStagedChanges(targetDir, { allowWarnings: false });
649
+ if (guard.summary.stagedCount === 0) {
650
+ throw new Error(
651
+ `[Committer Gate BLOCKED] Nenhum arquivo no stage para commit. ` +
652
+ `Execute primeiro: aioson commit:prepare . --agent-safe --staged-only --mode=headless`
653
+ );
654
+ }
655
+ if (!guard.ok) {
656
+ throw new Error(
657
+ `[Committer Gate BLOCKED] Arquivos proibidos detectados no stage ` +
658
+ `(node_modules, build artifacts, secrets, etc.). ` +
659
+ `Execute 'aioson git:guard .' para ver detalhes, corrija e rode 'aioson commit:prepare . --agent-safe --staged-only --mode=headless' antes de ativar @committer.`
660
+ );
661
+ }
662
+ }
663
+
664
+ // ── Test Briefing Injection for qa/tester ───────────────────────────────
665
+ let testBriefing = '';
666
+ let securityAuditBriefing = '';
667
+ if (stageName === 'qa' || stageName === 'tester') {
668
+ try {
669
+ testBriefing = await buildTestBriefing(targetDir);
670
+ } catch {
671
+ // Non-fatal: if briefing generation fails, proceed without it
672
+ testBriefing = '';
673
+ }
674
+ }
675
+
676
+ if (
677
+ stageName === 'qa' &&
678
+ state.mode === 'feature' &&
679
+ state.classification === 'MEDIUM' &&
680
+ state.featureSlug
681
+ ) {
682
+ try {
683
+ const auditResult = await runSecurityAudit({
684
+ args: [targetDir],
685
+ options: {
686
+ slug: state.featureSlug,
687
+ json: true,
688
+ runtimeAgentName: 'qa',
689
+ runtimeSource: 'workflow',
690
+ runtimeState: state,
691
+ runtimeWorkflowStage: 'qa'
692
+ },
693
+ logger: { log() {}, error() {}, warn() {} }
694
+ });
695
+ securityAuditBriefing = buildQaSecurityAuditBriefing(auditResult, targetDir);
696
+ } catch {
697
+ securityAuditBriefing = buildQaSecurityAuditBriefing({
698
+ ok: false,
699
+ reason: 'audit_runtime_failure'
700
+ }, targetDir);
701
+ }
702
+ }
703
+
704
+ // ── Path Guard Injection for implementation agents ────────────────────────
705
+ let pathGuardBlock = '';
706
+ if (['dev', 'architect', 'ux-ui', 'pentester', 'qa', 'tester', 'committer'].includes(stageName)) {
707
+ try {
708
+ pathGuardBlock = await buildPathGuardBlock(targetDir);
709
+ } catch {
710
+ pathGuardBlock = '';
711
+ }
712
+ }
713
+
437
714
  const agent = getAgentDefinition(stageName);
438
715
  if (!agent) {
439
716
  throw new Error(`Unknown agent: ${stageName}`);
440
717
  }
441
718
 
719
+ const autonomyProtocol = await readAutonomyProtocol(targetDir);
720
+ const agentManifest = await readAgentManifest(targetDir, agent.id);
721
+ const effectiveMode = resolveEffectiveMode({
722
+ protocol: autonomyProtocol,
723
+ tool,
724
+ agentId: agent.id,
725
+ manifest: agentManifest,
726
+ requestedMode
727
+ });
728
+
442
729
  const instructionPath = await resolveExistingInstructionPath(targetDir, agent, locale);
443
- const prompt = buildAgentPrompt(agent, tool, { instructionPath, targetDir });
730
+ let prompt = buildAgentPrompt(agent, tool, {
731
+ instructionPath,
732
+ targetDir,
733
+ interactionLanguage: locale,
734
+ autonomyMode: effectiveMode,
735
+ capabilitySummary: buildAgentCapabilitySummary(agentManifest, tool)
736
+ });
737
+
738
+ if (testBriefing) {
739
+ prompt += '\n\n' + testBriefing;
740
+ }
741
+
742
+ if (securityAuditBriefing) {
743
+ prompt += '\n\n' + securityAuditBriefing;
744
+ }
745
+
746
+ if (pathGuardBlock) {
747
+ prompt += '\n\n' + pathGuardBlock;
748
+ }
444
749
 
445
750
  let nextState = state;
446
751
  if (explicitAgent && stageName !== normalizeAgentName(state.next)) {
@@ -464,11 +769,23 @@ async function activateStage(targetDir, state, locale, tool, explicitAgent = nul
464
769
  state: nextState,
465
770
  agent: stageName,
466
771
  instructionPath,
467
- prompt
772
+ prompt,
773
+ effectiveMode
468
774
  };
469
775
  }
470
776
 
471
777
  async function runWorkflowNext({ args, options, logger, t }) {
778
+ if (options.status || options.suggest) {
779
+ const { runWorkflowStatus } = require('./workflow-status');
780
+ return runWorkflowStatus({ args, options, logger, t });
781
+ }
782
+
783
+ const logErrorLine = typeof logger.error === 'function'
784
+ ? logger.error.bind(logger)
785
+ : typeof logger.log === 'function'
786
+ ? logger.log.bind(logger)
787
+ : () => {};
788
+
472
789
  const targetDir = path.resolve(process.cwd(), args[0] || '.');
473
790
  const tool = options.tool || 'codex';
474
791
  const locale = await resolveLocaleForTarget(targetDir, options);
@@ -478,14 +795,119 @@ async function runWorkflowNext({ args, options, logger, t }) {
478
795
  let completedStage = null;
479
796
 
480
797
  if (options.complete || options['complete-current']) {
481
- const result = await finalizeCurrentStage(
482
- targetDir,
483
- config,
484
- state,
485
- options.complete === true ? state.current || state.next : options.complete
486
- );
487
- state = result.state;
488
- completedStage = result.completedStage;
798
+ let finalized;
799
+ try {
800
+ finalized = await finalizeCurrentStage(
801
+ targetDir,
802
+ config,
803
+ state,
804
+ options.complete === true ? state.current || state.next : options.complete
805
+ );
806
+ } catch (err) {
807
+ // ── Auto-heal intercept ───────────────────────────────────────────────
808
+ const autoHeal = Boolean(options['auto-heal'] || options.autoHeal);
809
+ const isHealabled = autoHeal && (
810
+ err.message.includes('[Technical Gate BLOCKED]') ||
811
+ err.message.includes('[Handoff Contract BLOCKED]')
812
+ );
813
+ if (isHealabled) {
814
+ const failedStage = normalizeAgentName(options.complete === true ? state.current || state.next : options.complete);
815
+ await logError(targetDir, failedStage, err.message, 'technical');
816
+ const retryCount = await require('../self-healing').getRetryCount(targetDir, failedStage);
817
+ if (retryCount < require('../self-healing').MAX_RETRIES) {
818
+ await require('../self-healing').incrementRetryCount(targetDir, failedStage, err.message.substring(0, 200));
819
+ // Build healing activation
820
+ const baseActivation = await activateStage(targetDir, state, locale, tool, failedStage, options.mode || null);
821
+ const healingPrompt = buildHealingPrompt(
822
+ baseActivation.prompt || '',
823
+ failedStage,
824
+ { error: err.message },
825
+ retryCount + 1
826
+ );
827
+ const healedState = {
828
+ ...baseActivation.state,
829
+ current: failedStage,
830
+ detour: null
831
+ };
832
+ await persistState(targetDir, healedState);
833
+ const eventPayload = {
834
+ id: Date.now(),
835
+ kind: 'workflow',
836
+ createdAt: new Date().toISOString(),
837
+ eventType: 'heal',
838
+ message: `Auto-heal @${failedStage} — retry ${retryCount + 1}/3`,
839
+ mode: state.mode,
840
+ classification: state.classification,
841
+ featureSlug: state.featureSlug,
842
+ current: failedStage,
843
+ next: state.next,
844
+ completed: state.completed,
845
+ skipped: state.skipped,
846
+ sequence: state.sequence,
847
+ healing: true,
848
+ retryCount: retryCount + 1,
849
+ autonomyMode: baseActivation.effectiveMode || null
850
+ };
851
+ await appendWorkflowEvent(targetDir, eventPayload);
852
+ const runtime = await syncWorkflowRuntime(targetDir, {
853
+ state: healedState,
854
+ eventPayload,
855
+ activationAgent: failedStage,
856
+ completedStage: null
857
+ });
858
+ const healingHandoff = buildWorkflowHandoff(healedState, null, failedStage);
859
+ healingHandoff.protocol = buildWorkflowHandoffProtocol(healedState, null, failedStage, {
860
+ autonomyMode: baseActivation.effectiveMode || null,
861
+ handoffContractOk: true,
862
+ technicalGateOk: false,
863
+ artifactUris: []
864
+ });
865
+ const healingValidation = await validateHandoffProtocol(targetDir, healingHandoff.protocol);
866
+ if (!healingValidation.ok) {
867
+ logErrorLine('Handoff protocol warning:');
868
+ for (const err of healingValidation.errors) logErrorLine(` - ${err}`);
869
+ }
870
+ await writeHandoff(targetDir, healingHandoff);
871
+ logger.log(t('workflow_heal.title', { stage: `@${failedStage}`, count: retryCount + 1 }));
872
+ logger.log(healingPrompt);
873
+ return {
874
+ ok: true,
875
+ targetDir,
876
+ locale,
877
+ tool,
878
+ statePath: STATE_RELATIVE_PATH,
879
+ configPath: CONFIG_RELATIVE_PATH,
880
+ created: loaded.created,
881
+ mode: state.mode,
882
+ classification: state.classification,
883
+ current: healedState.current,
884
+ next: healedState.next,
885
+ detour: healedState.detour,
886
+ completed: healedState.completed,
887
+ skipped: healedState.skipped,
888
+ completedStage: null,
889
+ featureSlug: state.featureSlug,
890
+ runtime,
891
+ agent: failedStage,
892
+ instructionPath: baseActivation.instructionPath,
893
+ prompt: healingPrompt,
894
+ autoHealed: true,
895
+ effectiveMode: baseActivation.effectiveMode || null
896
+ };
897
+ }
898
+ }
899
+ throw err;
900
+ }
901
+ state = finalized.state;
902
+ completedStage = finalized.completedStage;
903
+ await require('../self-healing').incrementRetryCount(targetDir, completedStage, '');
904
+ const { getRetryCount } = require('../self-healing');
905
+ const retries = await getRetryCount(targetDir, completedStage);
906
+ if (retries > 0) {
907
+ // Reset retry count on successful completion after healing
908
+ const retriesPath = path.join(targetDir, '.aioson/context/pipeline-retries', `${completedStage}.json`);
909
+ try { await fs.unlink(retriesPath); } catch { /* ignore */ }
910
+ }
489
911
  }
490
912
 
491
913
  if (options.skip) {
@@ -493,7 +915,7 @@ async function runWorkflowNext({ args, options, logger, t }) {
493
915
  }
494
916
 
495
917
  const requestedAgent = options.agent ? normalizeAgentName(options.agent) : null;
496
- const activation = await activateStage(targetDir, state, locale, tool, requestedAgent);
918
+ const activation = await activateStage(targetDir, state, locale, tool, requestedAgent, options.mode || null);
497
919
  state = activation.state;
498
920
  const statePath = await persistState(targetDir, state);
499
921
  const eventPayload = {
@@ -518,7 +940,8 @@ async function runWorkflowNext({ args, options, logger, t }) {
518
940
  requestedAgent: options.requestedAgent ? normalizeAgentName(options.requestedAgent) : null,
519
941
  completed: state.completed,
520
942
  skipped: state.skipped,
521
- sequence: state.sequence
943
+ sequence: state.sequence,
944
+ autonomyMode: activation.effectiveMode || null
522
945
  };
523
946
  await appendWorkflowEvent(targetDir, eventPayload);
524
947
  const runtime = await syncWorkflowRuntime(targetDir, {
@@ -531,6 +954,18 @@ async function runWorkflowNext({ args, options, logger, t }) {
531
954
  // Generate session handoff when a stage completes or workflow finishes
532
955
  if (completedStage || !activation.agent) {
533
956
  const handoffData = buildWorkflowHandoff(state, completedStage, activation.agent);
957
+ handoffData.autonomyMode = activation.effectiveMode || null;
958
+ handoffData.protocol = buildWorkflowHandoffProtocol(state, completedStage, activation.agent, {
959
+ autonomyMode: activation.effectiveMode || null,
960
+ handoffContractOk: true,
961
+ technicalGateOk: true,
962
+ artifactUris: []
963
+ });
964
+ const handoffValidation = await validateHandoffProtocol(targetDir, handoffData.protocol);
965
+ if (!handoffValidation.ok) {
966
+ logErrorLine('Handoff protocol warning:');
967
+ for (const err of handoffValidation.errors) logErrorLine(` - ${err}`);
968
+ }
534
969
  await writeHandoff(targetDir, handoffData);
535
970
  }
536
971
 
@@ -553,6 +988,7 @@ async function runWorkflowNext({ args, options, logger, t }) {
553
988
  featureSlug: state.featureSlug,
554
989
  runtime,
555
990
  agent: activation.agent,
991
+ effectiveMode: activation.effectiveMode || null,
556
992
  instructionPath: activation.instructionPath,
557
993
  prompt: activation.prompt
558
994
  };
@@ -595,7 +1031,9 @@ module.exports = {
595
1031
  readWorkflowConfig,
596
1032
  detectWorkflowMode,
597
1033
  loadOrCreateState,
1034
+ reconcileWorkflowState,
598
1035
  finalizeCurrentStage,
599
1036
  applySkip,
1037
+ activateStage,
600
1038
  runWorkflowNext
601
1039
  };