agentic-orchestrator 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (439) hide show
  1. package/.dockerignore +24 -0
  2. package/.github/workflows/mcp-contract-validation.yml +38 -0
  3. package/Agentic-Orchestrator.iml +9 -0
  4. package/LICENSE +21 -0
  5. package/README.md +679 -0
  6. package/agentic/orchestrator/agents.yaml +14 -0
  7. package/agentic/orchestrator/gates.yaml +31 -0
  8. package/agentic/orchestrator/policy.yaml +145 -0
  9. package/agentic/orchestrator/prompts/builder.system.md +1 -0
  10. package/agentic/orchestrator/prompts/planner.system.md +15 -0
  11. package/agentic/orchestrator/prompts/qa.system.md +1 -0
  12. package/agentic/orchestrator/schemas/agents.schema.json +49 -0
  13. package/agentic/orchestrator/schemas/gates.schema.json +65 -0
  14. package/agentic/orchestrator/schemas/index.schema.json +108 -0
  15. package/agentic/orchestrator/schemas/plan.schema.json +127 -0
  16. package/agentic/orchestrator/schemas/policy.schema.json +227 -0
  17. package/agentic/orchestrator/schemas/qa_test_index.schema.json +53 -0
  18. package/agentic/orchestrator/schemas/state.schema.json +92 -0
  19. package/agentic/orchestrator/tools/catalog.json +399 -0
  20. package/agentic/orchestrator/tools/errors.schema.json +21 -0
  21. package/agentic/orchestrator/tools/protocol.json +8 -0
  22. package/agentic/orchestrator/tools/schemas/input/collisions.scan.input.schema.json +7 -0
  23. package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +15 -0
  24. package/agentic/orchestrator/tools/schemas/input/feature.delete.input.schema.json +42 -0
  25. package/agentic/orchestrator/tools/schemas/input/feature.discover_specs.input.schema.json +7 -0
  26. package/agentic/orchestrator/tools/schemas/input/feature.get_context.input.schema.json +15 -0
  27. package/agentic/orchestrator/tools/schemas/input/feature.init.input.schema.json +21 -0
  28. package/agentic/orchestrator/tools/schemas/input/feature.log_append.input.schema.json +26 -0
  29. package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +34 -0
  30. package/agentic/orchestrator/tools/schemas/input/feature.state_get.input.schema.json +15 -0
  31. package/agentic/orchestrator/tools/schemas/input/feature.state_patch.input.schema.json +28 -0
  32. package/agentic/orchestrator/tools/schemas/input/gates.list.input.schema.json +11 -0
  33. package/agentic/orchestrator/tools/schemas/input/gates.run.input.schema.json +29 -0
  34. package/agentic/orchestrator/tools/schemas/input/locks.acquire.input.schema.json +29 -0
  35. package/agentic/orchestrator/tools/schemas/input/locks.release.input.schema.json +26 -0
  36. package/agentic/orchestrator/tools/schemas/input/mutating.schema.json +14 -0
  37. package/agentic/orchestrator/tools/schemas/input/plan.get.input.schema.json +15 -0
  38. package/agentic/orchestrator/tools/schemas/input/plan.submit.input.schema.json +28 -0
  39. package/agentic/orchestrator/tools/schemas/input/plan.update.input.schema.json +29 -0
  40. package/agentic/orchestrator/tools/schemas/input/qa.test_index_get.input.schema.json +15 -0
  41. package/agentic/orchestrator/tools/schemas/input/qa.test_index_update.input.schema.json +38 -0
  42. package/agentic/orchestrator/tools/schemas/input/read.schema.json +6 -0
  43. package/agentic/orchestrator/tools/schemas/input/repo.apply_patch.input.schema.json +25 -0
  44. package/agentic/orchestrator/tools/schemas/input/repo.diff.input.schema.json +21 -0
  45. package/agentic/orchestrator/tools/schemas/input/repo.diff_bundle.input.schema.json +15 -0
  46. package/agentic/orchestrator/tools/schemas/input/repo.ensure_worktree.input.schema.json +21 -0
  47. package/agentic/orchestrator/tools/schemas/input/repo.read_file.input.schema.json +20 -0
  48. package/agentic/orchestrator/tools/schemas/input/repo.search.input.schema.json +20 -0
  49. package/agentic/orchestrator/tools/schemas/input/repo.status.input.schema.json +15 -0
  50. package/agentic/orchestrator/tools/schemas/input/report.dashboard.input.schema.json +7 -0
  51. package/agentic/orchestrator/tools/schemas/input/report.feature_summary.input.schema.json +15 -0
  52. package/agentic/orchestrator/tools/schemas/output/collisions.scan.output.schema.json +17 -0
  53. package/agentic/orchestrator/tools/schemas/output/evidence.latest.output.schema.json +20 -0
  54. package/agentic/orchestrator/tools/schemas/output/feature.delete.output.schema.json +224 -0
  55. package/agentic/orchestrator/tools/schemas/output/feature.discover_specs.output.schema.json +32 -0
  56. package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +40 -0
  57. package/agentic/orchestrator/tools/schemas/output/feature.init.output.schema.json +24 -0
  58. package/agentic/orchestrator/tools/schemas/output/feature.log_append.output.schema.json +24 -0
  59. package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +30 -0
  60. package/agentic/orchestrator/tools/schemas/output/feature.state_get.output.schema.json +18 -0
  61. package/agentic/orchestrator/tools/schemas/output/feature.state_patch.output.schema.json +24 -0
  62. package/agentic/orchestrator/tools/schemas/output/gates.list.output.schema.json +42 -0
  63. package/agentic/orchestrator/tools/schemas/output/gates.run.output.schema.json +37 -0
  64. package/agentic/orchestrator/tools/schemas/output/locks.acquire.output.schema.json +34 -0
  65. package/agentic/orchestrator/tools/schemas/output/locks.release.output.schema.json +24 -0
  66. package/agentic/orchestrator/tools/schemas/output/plan.get.output.schema.json +26 -0
  67. package/agentic/orchestrator/tools/schemas/output/plan.submit.output.schema.json +23 -0
  68. package/agentic/orchestrator/tools/schemas/output/plan.update.output.schema.json +23 -0
  69. package/agentic/orchestrator/tools/schemas/output/qa.test_index_get.output.schema.json +22 -0
  70. package/agentic/orchestrator/tools/schemas/output/qa.test_index_update.output.schema.json +19 -0
  71. package/agentic/orchestrator/tools/schemas/output/repo.apply_patch.output.schema.json +33 -0
  72. package/agentic/orchestrator/tools/schemas/output/repo.diff.output.schema.json +19 -0
  73. package/agentic/orchestrator/tools/schemas/output/repo.diff_bundle.output.schema.json +32 -0
  74. package/agentic/orchestrator/tools/schemas/output/repo.ensure_worktree.output.schema.json +29 -0
  75. package/agentic/orchestrator/tools/schemas/output/repo.read_file.output.schema.json +24 -0
  76. package/agentic/orchestrator/tools/schemas/output/repo.search.output.schema.json +26 -0
  77. package/agentic/orchestrator/tools/schemas/output/repo.status.output.schema.json +27 -0
  78. package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +21 -0
  79. package/agentic/orchestrator/tools/schemas/output/report.feature_summary.output.schema.json +36 -0
  80. package/agentic/orchestrator/tools/schemas/output/standard_success.schema.json +6 -0
  81. package/agentic/orchestrator/tools.md +32 -0
  82. package/apps/control-plane/project.json +39 -0
  83. package/apps/control-plane/scripts/validate-architecture-rules.mjs +170 -0
  84. package/apps/control-plane/scripts/validate-docker-mcp-contract.mjs +84 -0
  85. package/apps/control-plane/scripts/validate-mcp-contracts.ts +61 -0
  86. package/apps/control-plane/src/application/services/collision-queue-service.ts +227 -0
  87. package/apps/control-plane/src/application/services/feature-deletion-service.ts +459 -0
  88. package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +177 -0
  89. package/apps/control-plane/src/application/services/feature-state-service.ts +125 -0
  90. package/apps/control-plane/src/application/services/gate-service.ts +232 -0
  91. package/apps/control-plane/src/application/services/lock-service.ts +298 -0
  92. package/apps/control-plane/src/application/services/merge-service.ts +246 -0
  93. package/apps/control-plane/src/application/services/patch-service.ts +259 -0
  94. package/apps/control-plane/src/application/services/plan-service.ts +302 -0
  95. package/apps/control-plane/src/application/services/qa-index-service.ts +98 -0
  96. package/apps/control-plane/src/application/services/reporting-service.ts +120 -0
  97. package/apps/control-plane/src/application/services/run-lease-service.ts +340 -0
  98. package/apps/control-plane/src/application/tools/tool-metadata.ts +56 -0
  99. package/apps/control-plane/src/application/tools/tool-router.ts +43 -0
  100. package/apps/control-plane/src/cli/aop.ts +31 -0
  101. package/apps/control-plane/src/cli/cli-argument-parser.ts +116 -0
  102. package/apps/control-plane/src/cli/delete-command-handler.ts +90 -0
  103. package/apps/control-plane/src/cli/io.ts +14 -0
  104. package/apps/control-plane/src/cli/resume-command-handler.ts +228 -0
  105. package/apps/control-plane/src/cli/run-command-handler.ts +57 -0
  106. package/apps/control-plane/src/cli/spec-ingestion-service.ts +88 -0
  107. package/apps/control-plane/src/cli/spec-input-resolver.ts +95 -0
  108. package/apps/control-plane/src/cli/spec-utils.ts +40 -0
  109. package/apps/control-plane/src/cli/status-command-handler.ts +17 -0
  110. package/apps/control-plane/src/cli/stop-command-handler.ts +5 -0
  111. package/apps/control-plane/src/cli/tooling.ts +36 -0
  112. package/apps/control-plane/src/cli/types.ts +34 -0
  113. package/apps/control-plane/src/core/collisions.ts +121 -0
  114. package/apps/control-plane/src/core/constants.ts +72 -0
  115. package/apps/control-plane/src/core/error-codes.ts +54 -0
  116. package/apps/control-plane/src/core/frontmatter.ts +42 -0
  117. package/apps/control-plane/src/core/fs.ts +173 -0
  118. package/apps/control-plane/src/core/gates.ts +361 -0
  119. package/apps/control-plane/src/core/git.ts +115 -0
  120. package/apps/control-plane/src/core/kernel.ts +1077 -0
  121. package/apps/control-plane/src/core/patch.ts +152 -0
  122. package/apps/control-plane/src/core/path-layout.ts +113 -0
  123. package/apps/control-plane/src/core/path-rules.ts +71 -0
  124. package/apps/control-plane/src/core/qa-index.ts +179 -0
  125. package/apps/control-plane/src/core/response.ts +62 -0
  126. package/apps/control-plane/src/core/runtime-sessions.ts +20 -0
  127. package/apps/control-plane/src/core/schemas.ts +125 -0
  128. package/apps/control-plane/src/index.ts +21 -0
  129. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +100 -0
  130. package/apps/control-plane/src/mcp/kernel-tool-executor.ts +39 -0
  131. package/apps/control-plane/src/mcp/mcp-server-adapter.ts +74 -0
  132. package/apps/control-plane/src/mcp/operation-ledger.ts +108 -0
  133. package/apps/control-plane/src/mcp/protocol-contract.ts +9 -0
  134. package/apps/control-plane/src/mcp/runtime-factory.ts +105 -0
  135. package/apps/control-plane/src/mcp/runtime-types.ts +44 -0
  136. package/apps/control-plane/src/mcp/token-auth-verifier.ts +63 -0
  137. package/apps/control-plane/src/mcp/token-claims-validator.ts +72 -0
  138. package/apps/control-plane/src/mcp/token-codec.ts +62 -0
  139. package/apps/control-plane/src/mcp/tool-authorizer.ts +43 -0
  140. package/apps/control-plane/src/mcp/tool-client.ts +78 -0
  141. package/apps/control-plane/src/mcp/tool-contract-validator.ts +83 -0
  142. package/apps/control-plane/src/mcp/tool-registry-loader.ts +135 -0
  143. package/apps/control-plane/src/mcp/tool-runtime.ts +336 -0
  144. package/apps/control-plane/src/mcp/tools-markdown-generator.ts +26 -0
  145. package/apps/control-plane/src/mcp/transport-types.ts +16 -0
  146. package/apps/control-plane/src/mcp/types.ts +2 -0
  147. package/apps/control-plane/src/providers/providers.ts +177 -0
  148. package/apps/control-plane/src/supervisor/build-wave-executor.ts +55 -0
  149. package/apps/control-plane/src/supervisor/lease-heartbeat-service.ts +22 -0
  150. package/apps/control-plane/src/supervisor/planning-wave-executor.ts +316 -0
  151. package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +62 -0
  152. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +99 -0
  153. package/apps/control-plane/src/supervisor/run-coordinator.ts +224 -0
  154. package/apps/control-plane/src/supervisor/runtime.ts +347 -0
  155. package/apps/control-plane/src/supervisor/session-orchestrator.ts +268 -0
  156. package/apps/control-plane/src/supervisor/types.ts +149 -0
  157. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +299 -0
  158. package/apps/control-plane/test/aop.spec.ts +101 -0
  159. package/apps/control-plane/test/cli-helpers.spec.ts +102 -0
  160. package/apps/control-plane/test/cli.spec.ts +12 -0
  161. package/apps/control-plane/test/cli.unit.spec.ts +609 -0
  162. package/apps/control-plane/test/collision-queue.spec.ts +158 -0
  163. package/apps/control-plane/test/collisions.spec.ts +138 -0
  164. package/apps/control-plane/test/core-utils.spec.ts +102 -0
  165. package/apps/control-plane/test/delete-command-handler.spec.ts +202 -0
  166. package/apps/control-plane/test/epoch-tracking.spec.ts +121 -0
  167. package/apps/control-plane/test/gates.spec.ts +452 -0
  168. package/apps/control-plane/test/helpers.ts +68 -0
  169. package/apps/control-plane/test/index.spec.ts +18 -0
  170. package/apps/control-plane/test/kernel-collision-replay.spec.ts +222 -0
  171. package/apps/control-plane/test/kernel.branches.spec.ts +321 -0
  172. package/apps/control-plane/test/kernel.coverage.spec.ts +408 -0
  173. package/apps/control-plane/test/kernel.spec.ts +369 -0
  174. package/apps/control-plane/test/mcp-helpers.spec.ts +195 -0
  175. package/apps/control-plane/test/mcp.spec.ts +776 -0
  176. package/apps/control-plane/test/merge-service.spec.ts +357 -0
  177. package/apps/control-plane/test/plan-service.spec.ts +195 -0
  178. package/apps/control-plane/test/planning-wave-executor.spec.ts +229 -0
  179. package/apps/control-plane/test/providers.spec.ts +168 -0
  180. package/apps/control-plane/test/qa-index-service.spec.ts +187 -0
  181. package/apps/control-plane/test/qa-index.spec.ts +317 -0
  182. package/apps/control-plane/test/response.spec.ts +55 -0
  183. package/apps/control-plane/test/run-coordinator.spec.ts +334 -0
  184. package/apps/control-plane/test/schema-date-time.spec.ts +170 -0
  185. package/apps/control-plane/test/service-retry-paths.spec.ts +305 -0
  186. package/apps/control-plane/test/services.spec.ts +693 -0
  187. package/apps/control-plane/test/spec-input-resolver.spec.ts +76 -0
  188. package/apps/control-plane/test/supervisor-collaborators.spec.ts +201 -0
  189. package/apps/control-plane/test/supervisor.calltool.spec.ts +120 -0
  190. package/apps/control-plane/test/supervisor.spec.ts +415 -0
  191. package/apps/control-plane/test/supervisor.unit.spec.ts +522 -0
  192. package/apps/control-plane/test/token-auth-verifier.spec.ts +111 -0
  193. package/apps/control-plane/test/tool-registry-loader.spec.ts +268 -0
  194. package/apps/control-plane/test/tool-runtime.spec.ts +294 -0
  195. package/apps/control-plane/test/worker-decision-loop.spec.ts +587 -0
  196. package/apps/control-plane/tsconfig.build.json +17 -0
  197. package/apps/control-plane/tsconfig.json +11 -0
  198. package/apps/control-plane/vitest.config.ts +28 -0
  199. package/dist/apps/control-plane/application/services/collision-queue-service.d.ts +69 -0
  200. package/dist/apps/control-plane/application/services/collision-queue-service.js +158 -0
  201. package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -0
  202. package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +79 -0
  203. package/dist/apps/control-plane/application/services/feature-deletion-service.js +336 -0
  204. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -0
  205. package/dist/apps/control-plane/application/services/feature-lifecycle-service.d.ts +81 -0
  206. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +117 -0
  207. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -0
  208. package/dist/apps/control-plane/application/services/feature-state-service.d.ts +34 -0
  209. package/dist/apps/control-plane/application/services/feature-state-service.js +90 -0
  210. package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -0
  211. package/dist/apps/control-plane/application/services/gate-service.d.ts +46 -0
  212. package/dist/apps/control-plane/application/services/gate-service.js +160 -0
  213. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -0
  214. package/dist/apps/control-plane/application/services/lock-service.d.ts +56 -0
  215. package/dist/apps/control-plane/application/services/lock-service.js +242 -0
  216. package/dist/apps/control-plane/application/services/lock-service.js.map +1 -0
  217. package/dist/apps/control-plane/application/services/merge-service.d.ts +33 -0
  218. package/dist/apps/control-plane/application/services/merge-service.js +194 -0
  219. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -0
  220. package/dist/apps/control-plane/application/services/patch-service.d.ts +39 -0
  221. package/dist/apps/control-plane/application/services/patch-service.js +189 -0
  222. package/dist/apps/control-plane/application/services/patch-service.js.map +1 -0
  223. package/dist/apps/control-plane/application/services/plan-service.d.ts +60 -0
  224. package/dist/apps/control-plane/application/services/plan-service.js +234 -0
  225. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -0
  226. package/dist/apps/control-plane/application/services/qa-index-service.d.ts +26 -0
  227. package/dist/apps/control-plane/application/services/qa-index-service.js +66 -0
  228. package/dist/apps/control-plane/application/services/qa-index-service.js.map +1 -0
  229. package/dist/apps/control-plane/application/services/reporting-service.d.ts +47 -0
  230. package/dist/apps/control-plane/application/services/reporting-service.js +90 -0
  231. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -0
  232. package/dist/apps/control-plane/application/services/run-lease-service.d.ts +74 -0
  233. package/dist/apps/control-plane/application/services/run-lease-service.js +263 -0
  234. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -0
  235. package/dist/apps/control-plane/application/tools/tool-metadata.d.ts +8 -0
  236. package/dist/apps/control-plane/application/tools/tool-metadata.js +37 -0
  237. package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -0
  238. package/dist/apps/control-plane/application/tools/tool-router.d.ts +16 -0
  239. package/dist/apps/control-plane/application/tools/tool-router.js +25 -0
  240. package/dist/apps/control-plane/application/tools/tool-router.js.map +1 -0
  241. package/dist/apps/control-plane/cli/aop.d.ts +5 -0
  242. package/dist/apps/control-plane/cli/aop.js +19 -0
  243. package/dist/apps/control-plane/cli/aop.js.map +1 -0
  244. package/dist/apps/control-plane/cli/cli-argument-parser.d.ts +5 -0
  245. package/dist/apps/control-plane/cli/cli-argument-parser.js +109 -0
  246. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -0
  247. package/dist/apps/control-plane/cli/delete-command-handler.d.ts +8 -0
  248. package/dist/apps/control-plane/cli/delete-command-handler.js +77 -0
  249. package/dist/apps/control-plane/cli/delete-command-handler.js.map +1 -0
  250. package/dist/apps/control-plane/cli/io.d.ts +2 -0
  251. package/dist/apps/control-plane/cli/io.js +14 -0
  252. package/dist/apps/control-plane/cli/io.js.map +1 -0
  253. package/dist/apps/control-plane/cli/resume-command-handler.d.ts +17 -0
  254. package/dist/apps/control-plane/cli/resume-command-handler.js +178 -0
  255. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -0
  256. package/dist/apps/control-plane/cli/run-command-handler.d.ts +15 -0
  257. package/dist/apps/control-plane/cli/run-command-handler.js +39 -0
  258. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -0
  259. package/dist/apps/control-plane/cli/spec-ingestion-service.d.ts +8 -0
  260. package/dist/apps/control-plane/cli/spec-ingestion-service.js +77 -0
  261. package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -0
  262. package/dist/apps/control-plane/cli/spec-input-resolver.d.ts +9 -0
  263. package/dist/apps/control-plane/cli/spec-input-resolver.js +81 -0
  264. package/dist/apps/control-plane/cli/spec-input-resolver.js.map +1 -0
  265. package/dist/apps/control-plane/cli/spec-utils.d.ts +3 -0
  266. package/dist/apps/control-plane/cli/spec-utils.js +36 -0
  267. package/dist/apps/control-plane/cli/spec-utils.js.map +1 -0
  268. package/dist/apps/control-plane/cli/status-command-handler.d.ts +7 -0
  269. package/dist/apps/control-plane/cli/status-command-handler.js +14 -0
  270. package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -0
  271. package/dist/apps/control-plane/cli/stop-command-handler.d.ts +3 -0
  272. package/dist/apps/control-plane/cli/stop-command-handler.js +6 -0
  273. package/dist/apps/control-plane/cli/stop-command-handler.js.map +1 -0
  274. package/dist/apps/control-plane/cli/tooling.d.ts +4 -0
  275. package/dist/apps/control-plane/cli/tooling.js +24 -0
  276. package/dist/apps/control-plane/cli/tooling.js.map +1 -0
  277. package/dist/apps/control-plane/cli/types.d.ts +31 -0
  278. package/dist/apps/control-plane/cli/types.js +2 -0
  279. package/dist/apps/control-plane/cli/types.js.map +1 -0
  280. package/dist/apps/control-plane/core/collisions.d.ts +39 -0
  281. package/dist/apps/control-plane/core/collisions.js +78 -0
  282. package/dist/apps/control-plane/core/collisions.js.map +1 -0
  283. package/dist/apps/control-plane/core/constants.d.ts +64 -0
  284. package/dist/apps/control-plane/core/constants.js +64 -0
  285. package/dist/apps/control-plane/core/constants.js.map +1 -0
  286. package/dist/apps/control-plane/core/error-codes.d.ts +50 -0
  287. package/dist/apps/control-plane/core/error-codes.js +52 -0
  288. package/dist/apps/control-plane/core/error-codes.js.map +1 -0
  289. package/dist/apps/control-plane/core/frontmatter.d.ts +11 -0
  290. package/dist/apps/control-plane/core/frontmatter.js +30 -0
  291. package/dist/apps/control-plane/core/frontmatter.js.map +1 -0
  292. package/dist/apps/control-plane/core/fs.d.ts +33 -0
  293. package/dist/apps/control-plane/core/fs.js +134 -0
  294. package/dist/apps/control-plane/core/fs.js.map +1 -0
  295. package/dist/apps/control-plane/core/gates.d.ts +88 -0
  296. package/dist/apps/control-plane/core/gates.js +229 -0
  297. package/dist/apps/control-plane/core/gates.js.map +1 -0
  298. package/dist/apps/control-plane/core/git.d.ts +31 -0
  299. package/dist/apps/control-plane/core/git.js +79 -0
  300. package/dist/apps/control-plane/core/git.js.map +1 -0
  301. package/dist/apps/control-plane/core/kernel.d.ts +445 -0
  302. package/dist/apps/control-plane/core/kernel.js +805 -0
  303. package/dist/apps/control-plane/core/kernel.js.map +1 -0
  304. package/dist/apps/control-plane/core/patch.d.ts +23 -0
  305. package/dist/apps/control-plane/core/patch.js +118 -0
  306. package/dist/apps/control-plane/core/patch.js.map +1 -0
  307. package/dist/apps/control-plane/core/path-layout.d.ts +23 -0
  308. package/dist/apps/control-plane/core/path-layout.js +90 -0
  309. package/dist/apps/control-plane/core/path-layout.js.map +1 -0
  310. package/dist/apps/control-plane/core/path-rules.d.ts +13 -0
  311. package/dist/apps/control-plane/core/path-rules.js +52 -0
  312. package/dist/apps/control-plane/core/path-rules.js.map +1 -0
  313. package/dist/apps/control-plane/core/qa-index.d.ts +53 -0
  314. package/dist/apps/control-plane/core/qa-index.js +112 -0
  315. package/dist/apps/control-plane/core/qa-index.js.map +1 -0
  316. package/dist/apps/control-plane/core/response.d.ts +19 -0
  317. package/dist/apps/control-plane/core/response.js +34 -0
  318. package/dist/apps/control-plane/core/response.js.map +1 -0
  319. package/dist/apps/control-plane/core/runtime-sessions.d.ts +19 -0
  320. package/dist/apps/control-plane/core/runtime-sessions.js +2 -0
  321. package/dist/apps/control-plane/core/runtime-sessions.js.map +1 -0
  322. package/dist/apps/control-plane/core/schemas.d.ts +23 -0
  323. package/dist/apps/control-plane/core/schemas.js +80 -0
  324. package/dist/apps/control-plane/core/schemas.js.map +1 -0
  325. package/dist/apps/control-plane/index.d.ts +11 -0
  326. package/dist/apps/control-plane/index.js +9 -0
  327. package/dist/apps/control-plane/index.js.map +1 -0
  328. package/dist/apps/control-plane/interfaces/cli/bootstrap.d.ts +2 -0
  329. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +86 -0
  330. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -0
  331. package/dist/apps/control-plane/mcp/kernel-tool-executor.d.ts +14 -0
  332. package/dist/apps/control-plane/mcp/kernel-tool-executor.js +26 -0
  333. package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -0
  334. package/dist/apps/control-plane/mcp/mcp-server-adapter.d.ts +19 -0
  335. package/dist/apps/control-plane/mcp/mcp-server-adapter.js +55 -0
  336. package/dist/apps/control-plane/mcp/mcp-server-adapter.js.map +1 -0
  337. package/dist/apps/control-plane/mcp/operation-ledger.d.ts +21 -0
  338. package/dist/apps/control-plane/mcp/operation-ledger.js +75 -0
  339. package/dist/apps/control-plane/mcp/operation-ledger.js.map +1 -0
  340. package/dist/apps/control-plane/mcp/protocol-contract.d.ts +8 -0
  341. package/dist/apps/control-plane/mcp/protocol-contract.js +9 -0
  342. package/dist/apps/control-plane/mcp/protocol-contract.js.map +1 -0
  343. package/dist/apps/control-plane/mcp/runtime-factory.d.ts +38 -0
  344. package/dist/apps/control-plane/mcp/runtime-factory.js +71 -0
  345. package/dist/apps/control-plane/mcp/runtime-factory.js.map +1 -0
  346. package/dist/apps/control-plane/mcp/runtime-types.d.ts +40 -0
  347. package/dist/apps/control-plane/mcp/runtime-types.js +2 -0
  348. package/dist/apps/control-plane/mcp/runtime-types.js.map +1 -0
  349. package/dist/apps/control-plane/mcp/token-auth-verifier.d.ts +24 -0
  350. package/dist/apps/control-plane/mcp/token-auth-verifier.js +45 -0
  351. package/dist/apps/control-plane/mcp/token-auth-verifier.js.map +1 -0
  352. package/dist/apps/control-plane/mcp/token-claims-validator.d.ts +9 -0
  353. package/dist/apps/control-plane/mcp/token-claims-validator.js +62 -0
  354. package/dist/apps/control-plane/mcp/token-claims-validator.js.map +1 -0
  355. package/dist/apps/control-plane/mcp/token-codec.d.ts +11 -0
  356. package/dist/apps/control-plane/mcp/token-codec.js +46 -0
  357. package/dist/apps/control-plane/mcp/token-codec.js.map +1 -0
  358. package/dist/apps/control-plane/mcp/tool-authorizer.d.ts +8 -0
  359. package/dist/apps/control-plane/mcp/tool-authorizer.js +36 -0
  360. package/dist/apps/control-plane/mcp/tool-authorizer.js.map +1 -0
  361. package/dist/apps/control-plane/mcp/tool-client.d.ts +30 -0
  362. package/dist/apps/control-plane/mcp/tool-client.js +50 -0
  363. package/dist/apps/control-plane/mcp/tool-client.js.map +1 -0
  364. package/dist/apps/control-plane/mcp/tool-contract-validator.d.ts +29 -0
  365. package/dist/apps/control-plane/mcp/tool-contract-validator.js +61 -0
  366. package/dist/apps/control-plane/mcp/tool-contract-validator.js.map +1 -0
  367. package/dist/apps/control-plane/mcp/tool-registry-loader.d.ts +15 -0
  368. package/dist/apps/control-plane/mcp/tool-registry-loader.js +109 -0
  369. package/dist/apps/control-plane/mcp/tool-registry-loader.js.map +1 -0
  370. package/dist/apps/control-plane/mcp/tool-runtime.d.ts +34 -0
  371. package/dist/apps/control-plane/mcp/tool-runtime.js +252 -0
  372. package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -0
  373. package/dist/apps/control-plane/mcp/tools-markdown-generator.d.ts +7 -0
  374. package/dist/apps/control-plane/mcp/tools-markdown-generator.js +22 -0
  375. package/dist/apps/control-plane/mcp/tools-markdown-generator.js.map +1 -0
  376. package/dist/apps/control-plane/mcp/transport-types.d.ts +14 -0
  377. package/dist/apps/control-plane/mcp/transport-types.js +2 -0
  378. package/dist/apps/control-plane/mcp/transport-types.js.map +1 -0
  379. package/dist/apps/control-plane/mcp/types.d.ts +2 -0
  380. package/dist/apps/control-plane/mcp/types.js +3 -0
  381. package/dist/apps/control-plane/mcp/types.js.map +1 -0
  382. package/dist/apps/control-plane/providers/providers.d.ts +72 -0
  383. package/dist/apps/control-plane/providers/providers.js +94 -0
  384. package/dist/apps/control-plane/providers/providers.js.map +1 -0
  385. package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +13 -0
  386. package/dist/apps/control-plane/supervisor/build-wave-executor.js +40 -0
  387. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -0
  388. package/dist/apps/control-plane/supervisor/lease-heartbeat-service.d.ts +12 -0
  389. package/dist/apps/control-plane/supervisor/lease-heartbeat-service.js +14 -0
  390. package/dist/apps/control-plane/supervisor/lease-heartbeat-service.js.map +1 -0
  391. package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +19 -0
  392. package/dist/apps/control-plane/supervisor/planning-wave-executor.js +249 -0
  393. package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -0
  394. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.d.ts +9 -0
  395. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +53 -0
  396. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js.map +1 -0
  397. package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +24 -0
  398. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +70 -0
  399. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -0
  400. package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +49 -0
  401. package/dist/apps/control-plane/supervisor/run-coordinator.js +162 -0
  402. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -0
  403. package/dist/apps/control-plane/supervisor/runtime.d.ts +58 -0
  404. package/dist/apps/control-plane/supervisor/runtime.js +270 -0
  405. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -0
  406. package/dist/apps/control-plane/supervisor/session-orchestrator.d.ts +29 -0
  407. package/dist/apps/control-plane/supervisor/session-orchestrator.js +211 -0
  408. package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -0
  409. package/dist/apps/control-plane/supervisor/types.d.ts +148 -0
  410. package/dist/apps/control-plane/supervisor/types.js +2 -0
  411. package/dist/apps/control-plane/supervisor/types.js.map +1 -0
  412. package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +37 -0
  413. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +236 -0
  414. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -0
  415. package/docker/mcp.Dockerfile +14 -0
  416. package/docker/mcp.compose.yaml +15 -0
  417. package/docker/mcp.entrypoint.sh +17 -0
  418. package/eslint.config.mjs +93 -0
  419. package/example-configurations/README.md +26 -0
  420. package/example-configurations/java/agents.yaml +14 -0
  421. package/example-configurations/java/gates.yaml +29 -0
  422. package/example-configurations/java/policy.yaml +148 -0
  423. package/example-configurations/node/agents.yaml +14 -0
  424. package/example-configurations/node/gates.yaml +32 -0
  425. package/example-configurations/node/policy.yaml +143 -0
  426. package/nx.json +16 -0
  427. package/package.json +39 -0
  428. package/prompts/vitest-testing-standards.instructions.md +204 -0
  429. package/scripts/dev-shell-env.sh +7 -0
  430. package/scripts/nx-safe.mjs +33 -0
  431. package/spec-files/agentic_orchestrator_cli_delete_command_spec.md +310 -0
  432. package/spec-files/agentic_orchestrator_dot_aop_generated_artifacts_spec.md +211 -0
  433. package/spec-files/agentic_orchestrator_mcp_formalization_spec.md +379 -0
  434. package/spec-files/agentic_orchestrator_oop_refactor_spec.md +415 -0
  435. package/spec-files/agentic_orchestrator_single_global_orchestrator_spec.md +265 -0
  436. package/spec-files/agentic_orchestrator_spec.md +1334 -0
  437. package/spec-files/progress.md +452 -0
  438. package/tsconfig.base.json +15 -0
  439. package/tsconfig.json +11 -0
@@ -0,0 +1,1334 @@
1
+ # Feature Spec: MCP‑First, Platform‑Agnostic Multi‑Agent Orchestrator for Parallel Feature Development (AOP)
2
+
3
+ > **Purpose of this document**: A single, implementable specification an AI agent can use to build the complete feature set described across the conversation: an **MCP-first “kernel”** plus a **Supervisor Runtime** that runs an **Orchestrator/Agent‑Cluster architecture** to develop **multiple features in parallel** with deterministic gates, collision detection, locks, worktrees, evidence, and auditable state.
4
+
5
+ ---
6
+
7
+ ## 1. Objectives
8
+
9
+ ### 1.1 Must‑Have Capabilities
10
+
11
+ - **MCP-first kernel** (deterministic): Git worktrees, patch application, gate execution, locking, collision detection, evidence/log capture, and canonical state writing.
12
+ - **Platform-agnostic**: Gate commands are defined by repo-local config (`agentic/orchestrator/gates.yaml`) and executed by MCP; no toolchain-specific logic in MCP beyond generic process execution and optional artifact parsing.
13
+ - **Implementation substrate**: The orchestrator implementation itself MUST be delivered as an **Nx monorepo**.
14
+ - **Testing standard**: The orchestrator implementation test framework MUST be **Vitest**.
15
+ - **Scope of Nx+Vitest requirement**: This applies only to the orchestrator control-plane codebase (CLI/Supervisor/MCP). It does not constrain managed target repository toolchains.
16
+ - **Orchestrator/Agent Cluster model**:
17
+ - User only interacts with **Orchestrator Agent**.
18
+ - Orchestrator consumes `spec.md` per feature and supervises an **Agent Cluster (Planner, Builder, QA)** per feature.
19
+ - **Supervisor Runtime** spawns worker sessions and enforces role permissions.
20
+ - **Parallelism**: Support at least **5 features** in parallel with isolation using **git worktrees** and conflict prevention using **locks + collision detection** at plan time.
21
+ - **Host review**: All changes must be visible on host filesystem prior to merge. User review occurs while feature diffs are still unmerged.
22
+ - **Explicit merge control**: MCP/Supervisor MUST NOT auto-merge as part of gate success alone. Commit + merge is only allowed through an explicit `feature.ready_to_merge` tool call after user approval.
23
+
24
+ ### 1.2 Non‑Goals
25
+
26
+ - Not building a proprietary agent model framework.
27
+ - Not requiring cloud infrastructure.
28
+ - Not forcing auto-merge; explicit user review and approval remain default.
29
+ - Not implementing a full PR hosting integration (optional later).
30
+
31
+ ---
32
+
33
+ ## 2. Concepts and Terminology
34
+
35
+ - **Control Plane (deterministic)**: MCP server + tool handlers.
36
+ - **Cognitive Plane (non-deterministic)**: Orchestrator agent and worker agents generating plans/patches and reacting to logs.
37
+ - **Agent Cluster (AC)**: Planner + Builder + QA agents for a single feature.
38
+ - **Ralph Loop**: propose → validate (via MCP gates) → repair → repeat.
39
+ - **Worktree**: Separate checkout per feature branch via `git worktree`.
40
+ - **Gate**: A deterministic command sequence that must pass (exit code 0 and policy constraints) to advance.
41
+ - **Lock**: Exclusive resource ownership (openapi, db migrations, protected libs, etc.).
42
+
43
+ ---
44
+
45
+ ## 3. System Architecture
46
+
47
+ ### 3.1 Processes
48
+
49
+ **A) MCP Server (inside Docker, bind-mounted repo)**
50
+ - Exposes tools via MCP.
51
+ - Runs git and gate commands inside bind mount.
52
+ - Enforces schemas, policies, locks, collisions, and patch constraints.
53
+ - Writes canonical state and evidence.
54
+
55
+ **B) Supervisor Runtime (outside MCP, vendor-agnostic)**
56
+ - Responsible for “spinning up agents” (Orchestrator + workers).
57
+ - Applies role-scoped tool permissions.
58
+ - Runs orchestration algorithm across features and clusters.
59
+
60
+ **C) Agent Runtime(s) (Claude Code, Codex CLI, etc.)**
61
+ - Connect to MCP tools.
62
+ - Generate structured artifacts and diffs under Supervisor control.
63
+
64
+ > **Key design decision**: MCP server is vendor-agnostic and should **not** call Claude/Codex directly. The Supervisor Runtime owns provider-specific session management.
65
+
66
+ ### 3.2 Docker + Host Visibility
67
+
68
+ - Target repo **MUST be bind-mounted** into container at `/repo`.
69
+ - Worktrees MUST be created under `/repo/.worktrees/<featureId>` (or configurable but within bind mount).
70
+ - Therefore host sees changes immediately at `<repo>/.worktrees/<featureId>`.
71
+
72
+ ### 3.3 Isolation and Parallelism
73
+
74
+ - For N features in parallel (target 5): one worktree per feature branch.
75
+ - MCP never switches the main working tree branch; it operates only in the worktree per feature.
76
+ - Concurrency controls:
77
+ - gate execution concurrency limit (CPU)
78
+ - lock ownership checks
79
+ - collision rejection/blocking at plan submit
80
+
81
+ ### 3.4 State Consistency (Atomicity + Concurrency)
82
+
83
+ - All writes to `agentic/features/index.json` and `agentic/features/*/state.md` MUST be atomic using write-temp + fsync + rename semantics.
84
+ - MCP MUST serialize mutations with file locks:
85
+ - global index lock for `index.json` updates
86
+ - per-feature lock for `state.md` + `plan.json` updates
87
+ - State-bearing files MUST include `version` (monotonic integer).
88
+ - Mutating tools MUST use optimistic concurrency (`expected_version`) and fail with `error=version_conflict` when stale.
89
+ - Deterministic ordering rule for concurrent lock acquisitions: lexicographic lock ordering by resource id.
90
+
91
+ ---
92
+
93
+ ## 4. Repo File Layout (Canonical)
94
+
95
+ At repo root:
96
+
97
+ ```
98
+ agentic/
99
+ orchestrator/
100
+ gates.yaml
101
+ policy.yaml
102
+ agents.yaml
103
+ prompts/
104
+ planner.system.md
105
+ builder.system.md
106
+ qa.system.md
107
+ schemas/
108
+ plan.schema.json
109
+ state.schema.json
110
+ index.schema.json
111
+ gates.schema.json
112
+ policy.schema.json
113
+ agents.schema.json
114
+ qa_test_index.schema.json
115
+ tools/
116
+ catalog.json
117
+ protocol.json
118
+ errors.schema.json
119
+ schemas/
120
+ input/*.schema.json
121
+ output/*.schema.json
122
+ tools.md
123
+ features/
124
+ index.json
125
+ my_feature/
126
+ spec.md
127
+ state.md
128
+ plan.json
129
+ qa_test_index.json
130
+ decisions.md
131
+ logs/
132
+ evidence/
133
+ another_feature/...
134
+ .git/
135
+ .worktrees/
136
+ my_feature/
137
+ another_feature/
138
+ ...
139
+ ```
140
+
141
+ ---
142
+
143
+ ## 5. Deterministic vs Agent Responsibilities
144
+
145
+ ### 5.1 MCP (deterministic) MUST do
146
+
147
+ - Validate `plan.json` against schema and policy.
148
+ - Validate `state.md` front matter against schema when writing.
149
+ - Detect collisions at plan time using accepted plans.
150
+ - Enforce locks for contract resources and protected areas.
151
+ - Apply patches with policy enforcement (allowed areas, planned files, lock constraints).
152
+ - Run gates from config; capture logs; parse artifacts; enforce thresholds.
153
+ - Persist evidence and update state files.
154
+ - Produce review bundles (diff summaries, evidence summaries).
155
+ - Enforce legal status transitions and optimistic concurrency on state changes.
156
+ - Enforce configuration precedence across policy/gates/plan overrides.
157
+ - Maintain per-feature `qa_test_index.json` from current worktree diff (file + line hunk granularity).
158
+ - Provide resumable context bundles for agent respawn (state, plan, diff/evidence summary, QA index).
159
+
160
+ ### 5.2 Agents MUST do
161
+
162
+ - Interpret `spec.md` and existing code patterns.
163
+ - Produce `plan.json` and diffs (unified patches).
164
+ - Use Ralph Loop by reacting to MCP gate outputs.
165
+ - Orchestrator chooses collision resolution strategy and merge order.
166
+
167
+ ### 5.3 Supervisor Runtime MUST do (enforcement that is *not* MCP)
168
+
169
+ - Spawn/maintain sessions for orchestrator + workers.
170
+ - Enforce role tool permissions (tool-call firewall).
171
+ - Route tool results and failure logs to the correct worker.
172
+ - Decide when to advance phase: planning → building → qa → ready.
173
+ - Support ephemeral QA workers: close QA session after a test batch and respawn later with MCP-sourced context.
174
+
175
+ ---
176
+
177
+ ## 6. Schemas (Formal Definitions)
178
+
179
+ > **Requirement**: MCP server MUST load these schemas from `agentic/orchestrator/schemas/` and validate on relevant tool calls. Rejection MUST be structured and actionable.
180
+
181
+ ### 6.0 MCP Tool Contract Schemas
182
+
183
+ In addition to runtime state schemas, the MCP boundary MUST be formalized with:
184
+ - `agentic/orchestrator/tools/catalog.json` as the single source of truth for tool metadata and schema references.
185
+ - `agentic/orchestrator/tools/protocol.json` for pinned MCP protocol/SDK/transports.
186
+ - `agentic/orchestrator/tools/errors.schema.json` for normalized error envelopes.
187
+ - `agentic/orchestrator/tools/schemas/input/*.schema.json` and `agentic/orchestrator/tools/schemas/output/*.schema.json` for per-tool contracts.
188
+
189
+ Contract validation MUST fail CI when protocol pins drift or when `catalog.json`, `tools.md`, and schema files are out of sync.
190
+
191
+ ### 6.1 `plan.json` JSON Schema (`plan.schema.json`)
192
+
193
+ **Required fields**:
194
+ - `feature_id` (string, derived from spec filename; pattern `^[a-z0-9_][a-z0-9_-]*$` recommended)
195
+ - `plan_version` (integer, starts at `1`, increments by `+1` on each accepted update)
196
+ - `summary` (string, min 5 chars)
197
+ - `allowed_areas` (array of non-empty strings)
198
+ - `forbidden_areas` (array; can be empty)
199
+ - `base_ref` (string, commit SHA or ref used for planning snapshot)
200
+ - `files` object:
201
+ - `create` array
202
+ - `modify` array
203
+ - `delete` array
204
+ - `contracts` object with enums:
205
+ - `openapi`: `"none" | "modify"`
206
+ - `events`: `"none" | "modify"`
207
+ - `db`: `"none" | "migration"`
208
+ - `acceptance_criteria` (array of non-empty strings, minItems=1)
209
+ - `gate_profile` (string, default `"default"`)
210
+ - Optional: `gate_targets` (array of strings)
211
+ - Optional: `verification_overrides` (object) – see below
212
+ - Optional: `risk` (array of strings)
213
+ - Optional: `revision_of` (integer plan version being replaced)
214
+ - Optional: `revision_reason` (string)
215
+
216
+ **Verification overrides** (optional):
217
+ - `modes.fast.steps` array of gate step overrides (rare; discourage)
218
+ - `modes.full.steps` overrides
219
+ Default behavior is use `gates.yaml`.
220
+
221
+ **Plan revision rules**:
222
+ - First accepted plan MUST have `plan_version=1` and no `revision_of`.
223
+ - `plan.update` MUST require `expected_plan_version` and reject stale updates.
224
+ - MCP MUST re-run schema, policy, lock, and collision checks for every revision.
225
+
226
+ **Plan Schema (canonical draft)**: see Appendix A for full JSON Schema.
227
+
228
+ ### 6.2 `state.md` JSON Schema (`state.schema.json`)
229
+
230
+ State file is Markdown with YAML front matter. MCP validates the front matter object.
231
+
232
+ Required fields:
233
+ - `feature_id` (string)
234
+ - `version` (integer, monotonic)
235
+ - `branch` (string)
236
+ - `worktree_path` (string)
237
+ - `status` enum: `planning|building|qa|blocked|ready_to_merge|merged|failed`
238
+ - `gate_profile` (string)
239
+ - `gates` object with gate result enums `pass|fail|na`
240
+ - `locks.held` array
241
+ - `collisions` structure
242
+ - `cluster` session ids (strings; may be `"unknown"` if runtime doesn’t provide)
243
+ - `role_status` for planner/builder/qa
244
+ - `last_updated` ISO string
245
+ - Optional: `evidence` object (last gate id, artifacts)
246
+ - Optional: `status_reason` (string)
247
+
248
+ ### 6.3 `index.json` JSON Schema (`index.schema.json`)
249
+
250
+ Tracks global orchestration status.
251
+
252
+ Required fields:
253
+ - `version` integer (monotonic)
254
+ - `active` array of feature ids
255
+ - `blocked` array
256
+ - `merged` array
257
+ - `locks` object mapping resource name → feature id or null
258
+ - `lock_leases` object mapping resource name → lease metadata (holder, lease_id, expires_at)
259
+ - `blocked_queue` array (for `collision_policy=block`)
260
+ - Optional: `updated_at`
261
+
262
+ ### 6.4 `gates.yaml` Schema (`gates.schema.json`)
263
+
264
+ YAML is validated by loading and validating against JSON schema equivalent.
265
+
266
+ Required fields:
267
+ - `version` number
268
+ - `profiles` object:
269
+ - profile name → profile object
270
+ - Profile object required:
271
+ - `modes` object:
272
+ - mode name (`fast`, `full`, optional `merge`) → array of steps
273
+ - Step object required:
274
+ - `name` string
275
+ - `cmd` array of strings (exec args)
276
+ - Optional: `cwd` string (relative to worktree root)
277
+ - Optional: `env` object
278
+ - Optional: `timeout_seconds` number
279
+
280
+ Optional:
281
+ - `parsers.coverage` with:
282
+ - `type`: `none|lcov|junit_xml|jacoco_xml|cobertura_xml|custom`
283
+ - `path` string
284
+ - `thresholds.coverage_line_min` number 0..1
285
+ - `thresholds.coverage_branch_min` number 0..1
286
+ - `thresholds.coverage_line_target` number 0..1
287
+ - `thresholds.coverage_branch_target` number 0..1
288
+ - `capabilities` list (declares supported parsers)
289
+
290
+ ### 6.5 `policy.yaml` Schema (`policy.schema.json`)
291
+
292
+ Required fields:
293
+ - `version`
294
+ - `commit_policy.allow_commit` boolean
295
+ - `commit_policy.allow_merge` boolean
296
+ - `patch_policy.enforce_plan` boolean
297
+ - `patch_policy.enforce_allowed_areas` boolean
298
+ - `locks.resources` array
299
+ - `locks.contract_to_resource` object (`openapi|events|db` to lock resource id)
300
+ - `locks.lease_ttl_seconds` number
301
+ - `protected_areas` array
302
+ - `exclusive_areas` array (optional but recommended for high-collision repos)
303
+ - `required_modes` array
304
+ - `required_merge_mode` string
305
+ - `collision_policy` enum `reject|block`
306
+ - `config_precedence` object defining deterministic precedence:
307
+ - `policy_hard_constraints`
308
+ - `gates_profile_defaults`
309
+ - `plan_verification_overrides`
310
+ - `locks.acquire_behavior` enum `wait|fail` (default `wait`)
311
+ - `locks.default_wait_timeout_seconds` number (default `300`)
312
+ - `locks.acquire_backoff` object with jittered exponential settings
313
+ - `rbac` matrix: role -> allowed tool names
314
+ - `path_rules` object:
315
+ - `matching` enum `repo_prefix|glob`
316
+ - `normalize_paths` boolean (must be true)
317
+ - `allow_symlink_traversal` boolean (must default false)
318
+ - `execution.default_step_timeout_seconds` number (default `600`)
319
+ - `execution.retry_policy` object:
320
+ - `transient_max_retries` number (default `1`)
321
+ - `transient_error_codes` array
322
+ - `non_retryable_error_codes` array
323
+ - `execution.env_allowlist` array
324
+ - `implementation.workspace` enum `nx` (required for this implementation)
325
+ - `testing.framework` enum `vitest`
326
+ - `testing.coverage.minimums.line` number (default `0.90`)
327
+ - `testing.coverage.minimums.branch` number (default `0.90`)
328
+ - `testing.coverage.targets.line` number (default `1.00`)
329
+ - `testing.coverage.targets.branch` number (default `1.00`)
330
+ - `merge_policy.require_user_approval` boolean
331
+ - `merge_policy.allowed_strategies` array (`merge_commit|squash|rebase`)
332
+ - `worktree.base_branch` string (for initial branch cut)
333
+ - Optional additional thresholds (coverage, performance, repo-specific gates) beyond the required testing minima above.
334
+
335
+ Policy interpretation notes:
336
+ - `commit_policy.*` controls direct low-level commit tools (`repo.commit`).
337
+ - `merge_policy.*` controls high-level merge promotion (`feature.ready_to_merge`), including the commit created as part of merge promotion.
338
+ - `implementation.workspace` and `testing.*` constrain the orchestrator codebase implementation; they do not remove platform-agnostic support for managed target repositories.
339
+
340
+ ### 6.6 Path Canonicalization and Matching Rules
341
+
342
+ - MCP MUST canonicalize all candidate paths to repo-relative POSIX form before validation.
343
+ - Any path that escapes repo root (`..`, absolute host paths) MUST fail with `error=path_out_of_bounds`.
344
+ - Symlink traversal outside repo root is forbidden by default and controlled by `policy.path_rules.allow_symlink_traversal`.
345
+ - Area matching semantics are policy-controlled:
346
+ - `repo_prefix`: area `src/api` means any path with that normalized prefix.
347
+ - `glob`: area values interpreted as POSIX globs.
348
+ - `repo.apply_patch` MUST evaluate renamed, copied, deleted, and mode-changed files against plan/policy with both old and new paths.
349
+
350
+ ### 6.7 `agents.yaml` Schema (`agents.schema.json`)
351
+
352
+ Repo-level worker prompt configuration.
353
+
354
+ Required fields:
355
+ - `version`
356
+ - `roles` object:
357
+ - `planner.system_prompt_path` (optional)
358
+ - `builder.system_prompt_path` (optional)
359
+ - `qa.system_prompt_path` (optional)
360
+ - `missing_prompt_behavior` enum `ignore|error` (default `ignore`)
361
+ - Optional `runtime` object:
362
+ - `default_provider` enum `codex|claude|gemini|custom`
363
+ - `default_model` string
364
+ - `provider_config_env` string (env var name containing provider auth/config)
365
+ - `role_provider_overrides` object (optional per-role provider/model overrides)
366
+
367
+ Prompt loading rules:
368
+ - If configured prompt path exists, Supervisor MUST load and inject it as the role system prompt.
369
+ - If path is absent or file missing and `missing_prompt_behavior=ignore`, Supervisor uses built-in defaults.
370
+ - Prompt paths MUST be repo-relative and validated with path rules (§6.6).
371
+ - Provider defaults in `runtime` are used only when CLI/env do not override.
372
+
373
+ ### 6.8 `qa_test_index.json` Schema (`qa_test_index.schema.json`)
374
+
375
+ Per-feature QA execution index used to keep QA agent context small and resumable.
376
+
377
+ Required fields:
378
+ - `feature_id`
379
+ - `version` (integer, monotonic)
380
+ - `source_diff_ref` (string identifying diff snapshot)
381
+ - `items` array where each item includes:
382
+ - `path` (repo-relative)
383
+ - `hunks` array of `{start_line, end_line, change_type}`
384
+ - `required_tests` array of strings
385
+ - `status` enum `pending|running|passed|failed|waived`
386
+ - optional `last_run_at`
387
+ - optional `evidence_refs` array
388
+
389
+ Rules:
390
+ - MCP MUST update file/hunk entries after every successful `repo.apply_patch`.
391
+ - MCP MUST compute `required_tests` deterministically from configured gate steps and changed paths/hunks so QA sees exact pending test obligations at any time.
392
+ - QA agent MUST update statuses/evidence after each executed test batch.
393
+
394
+ ---
395
+
396
+ ## 7. MCP Tool Catalog (Deterministic Kernel)
397
+
398
+ ### 7.1 Tool Contract Norms
399
+
400
+ All tools MUST:
401
+ - Accept `actor_type` (`orchestrator|planner|builder|qa|system`) and `actor_id` (string).
402
+ - Return JSON with at least:
403
+ - `ok` boolean
404
+ - `data` object if ok
405
+ - `error` object if not ok
406
+ - `evidence` object when relevant (log paths, command, exit code)
407
+
408
+ Tools MUST be idempotent when reasonable (`ensure_worktree`, `feature.init`).
409
+ Mutating tools MUST require `expected_version` for optimistic concurrency where a state/index file is updated.
410
+ Authorization MUST be deny-by-default; any disallowed role/tool attempt fails with `error=forbidden_tool_for_role`.
411
+
412
+ ### 7.1.1 Normative RBAC Matrix (Default)
413
+
414
+ - `orchestrator`: may call all read/report tools, `feature.init`, `plan.get`, `plan.submit`, `plan.update`, `locks.acquire`, `locks.release`, `gates.run`, `feature.ready_to_merge`.
415
+ - `planner`: may call read tools, `plan.submit`, `plan.update`, `collisions.scan`.
416
+ - `builder`: may call read tools, `repo.apply_patch`, `repo.status`, `repo.diff`, `gates.run`.
417
+ - `qa`: may call read tools, `repo.apply_patch`, `repo.diff`, `gates.run`, `evidence.latest`, `qa.test_index_get`, `qa.test_index_update`.
418
+ - `system`: unrestricted internal automation role.
419
+ - `feature.state_patch` is restricted to `system|orchestrator` unless policy explicitly expands access.
420
+ - `locks.acquire`/`locks.release` are restricted to `orchestrator|system`; worker roles request lock actions via `REQUEST`.
421
+
422
+ ### 7.2 Required Tools (V1)
423
+
424
+ #### Feature lifecycle
425
+ 1) `feature.discover_specs()`
426
+ - Returns list of `{feature_id, spec_path}` under `agentic/features/*/spec.md`.
427
+
428
+ 2) `feature.init(feature_id)`
429
+ - Creates feature folder structure if missing.
430
+ - Creates/ensures branch + worktree (see `repo.ensure_worktree`).
431
+ - Writes `state.md` default with `status=planning`.
432
+
433
+ 3) `feature.get_context(feature_id)`
434
+ - Returns: spec.md text, parsed state front matter, plan.json (if exists), latest evidence summary, and current `qa_test_index.json`.
435
+
436
+ 4) `feature.state_get(feature_id)`
437
+ - Returns parsed state front matter + raw markdown body.
438
+
439
+ 5) `feature.state_patch(feature_id, expected_version, patch)`
440
+ - Restricted: allowed only for `actor_type=system|orchestrator` by policy; typically MCP internal.
441
+ - Validates against schema before writing.
442
+
443
+ 6) `feature.log_append(feature_id, note)`
444
+ - Appends to `decisions.md` or `state.md` body section; includes `actor` stamp.
445
+
446
+ #### Plan
447
+ 7) `plan.submit(feature_id, plan_json, expected_version?)`
448
+ - Validates plan schema.
449
+ - Enforces `policy.yaml` constraints:
450
+ - required fields
451
+ - disallowed contract changes without locks
452
+ - forbidden/protected areas
453
+ - Collision scan against other accepted plans (see §8).
454
+ - Persists `plan.json`.
455
+ - Updates `state.md` gates: `plan=pass` and status to `building` if allowed.
456
+
457
+ 8) `plan.get(feature_id)`
458
+
459
+ 9) `plan.update(feature_id, expected_plan_version, plan_json)`
460
+ - Requires `plan_json.plan_version = expected_plan_version + 1`.
461
+ - Requires `plan_json.revision_of = expected_plan_version`.
462
+ - Re-runs full validation, lock checks, and collision scan.
463
+ - Overwrites `plan.json` atomically only if checks pass.
464
+ - Existing worktree diffs are retained, but all subsequent `repo.apply_patch` operations MUST validate against the latest accepted plan.
465
+
466
+ #### Repo/worktree
467
+ 10) `repo.ensure_worktree(feature_id)`
468
+ - Ensures `.worktrees/<feature_id>` exists and is checked out to `<feature_id>` branch.
469
+ - If branch is newly created, cut it from `policy.worktree.base_branch` at the current head SHA.
470
+ - Must store branch name in state.
471
+
472
+ 11) `repo.apply_patch(feature_id, unified_diff)`
473
+ - Validates: plan exists (unless policy allows).
474
+ - Parses patch to determine touched paths.
475
+ - Enforces:
476
+ - touched paths ⊆ allowed_areas
477
+ - no forbidden/protected area edits without permission/lock
478
+ - touched files are in plan’s create/modify/delete lists (strict by default)
479
+ - contract resources require locks
480
+ - path normalization and path-out-of-bounds checks (§6.6)
481
+ - Applies patch in the worktree.
482
+ - Returns updated `git status --porcelain` plus list of changed files.
483
+ - Rebuilds or incrementally updates `qa_test_index.json` for changed files/hunks.
484
+
485
+ 12) `repo.status(feature_id)`
486
+ 13) `repo.diff(feature_id, options?)`
487
+ - Options: `--stat`, `--name-only`, etc.
488
+
489
+ 14) `repo.read_file(feature_id, path)`
490
+ 15) `repo.search(feature_id, query)`
491
+ - Wrapper around `rg` with safe defaults; returns file/line matches.
492
+
493
+ 16) `repo.diff_bundle(feature_id)`
494
+ - Returns a “review bundle”:
495
+ - diff stat
496
+ - full diff (or path to stored diff)
497
+ - touched file list
498
+ - last gate summary
499
+
500
+ 17) `feature.ready_to_merge(feature_id, commit_message, merge_strategy, user_approval_token)`
501
+ - Preconditions:
502
+ - feature status is `ready_to_merge`
503
+ - required `full` + `merge` modes pass (policy-controlled)
504
+ - `merge_policy.require_user_approval=true` implies valid `user_approval_token`
505
+ - Performs deterministic commit in feature branch and merge into base branch.
506
+ - On success:
507
+ - updates state status to `merged`
508
+ - appends merge evidence (commit SHA, merge SHA, strategy, gate snapshot)
509
+ - releases held locks.
510
+
511
+ > Low-level git tools MAY exist for debugging but SHOULD be blocked by RBAC for non-system roles:
512
+ 18) `repo.commit(feature_id, message)` (internal/optional)
513
+ 19) `repo.rebase_onto_main(feature_id)` (internal/optional)
514
+ 20) `repo.merge(feature_id)` (internal/optional)
515
+
516
+ #### Gates/evidence
517
+ 21) `gates.list(profile?)`
518
+ 22) `gates.run(feature_id, profile, mode)`
519
+ - Loads `gates.yaml`, selects profile and mode.
520
+ - Runs steps sequentially (or optionally parallel if configured, but default sequential for determinism).
521
+ - Captures stdout/stderr per step to `logs/`.
522
+ - On non-zero exit code: stop and report failure.
523
+ - If configured, parse coverage artifact and enforce thresholds.
524
+ - Writes state updates:
525
+ - per-step results
526
+ - overall mode result
527
+ - evidence pointers
528
+
529
+ 23) `evidence.latest(feature_id)`
530
+ - Returns last gate run summary with key log excerpt tail.
531
+
532
+ #### QA context / test index
533
+ 24) `qa.test_index_get(feature_id)`
534
+ - Returns parsed `qa_test_index.json`, summary counts by status, and exact pending `required_tests` grouped by file/hunk.
535
+
536
+ 25) `qa.test_index_update(feature_id, expected_version, updates, evidence_refs?)`
537
+ - Allowed for `qa|system|orchestrator`.
538
+ - Applies status updates to index entries and increments index version.
539
+ - Requires line-hunk references when marking entries `passed|failed|waived`.
540
+ - MUST be called by QA agent after each test batch.
541
+
542
+ #### Locks/collisions
543
+ 26) `locks.acquire(resource, feature_id, wait_timeout_seconds?)`
544
+ - Resource names from policy.
545
+ - Stores in `index.json` and feature state.
546
+ - Enforces ownership.
547
+ - MUST create lease metadata (`lease_id`, `expires_at`) and renew while holder is healthy.
548
+
549
+ 27) `locks.release(resource, feature_id)`
550
+
551
+ 28) `collisions.scan()`
552
+ - Returns global collision matrix based on accepted plans.
553
+
554
+ #### Reporting (for orchestrator UX)
555
+ 29) `report.dashboard()`
556
+ - Returns summary of all features: status, blocks, locks, last gates.
557
+
558
+ 30) `report.feature_summary(feature_id)`
559
+ - Returns state summary + diff summary + latest evidence links.
560
+
561
+ ---
562
+
563
+ ## 8. Collision Detection and Resolution
564
+
565
+ ### 8.1 Collision Types (detected by MCP at `plan.submit`)
566
+
567
+ - **File collision:** two accepted plans modify the same file path.
568
+ - **Area collision:** overlap within protected_areas or explicitly configured “exclusive areas”.
569
+ - **Contract collision:** multiple plans request `openapi/events/db` modification.
570
+ - **Migration collision:** multiple plans set `db=migration` simultaneously (serializable via lock).
571
+
572
+ ### 8.2 Collision Policy
573
+
574
+ Defined in `policy.yaml`:
575
+ - `collision_policy: reject|block`
576
+ Default: `reject` with structured report so orchestrator can revise.
577
+
578
+ If `collision_policy=block`:
579
+ - MCP MUST persist blocked plan requests in `index.json.blocked_queue`.
580
+ - Queue entries MUST include `{feature_id, plan_version, detected_at, collision_fingerprint, required_resources}`.
581
+ - MCP MUST re-evaluate queued entries when relevant locks are released or plans change.
582
+ - Queue order MUST be deterministic: oldest `detected_at`, then `feature_id`.
583
+
584
+ ### 8.3 Collision Report Format
585
+
586
+ On collision, MCP returns:
587
+ - collision items
588
+ - owning feature ids
589
+ - normalized path/resource identifiers
590
+ - collision fingerprint (stable hash for dedupe)
591
+ - recommended actions:
592
+ - acquire lock
593
+ - revise plan to avoid overlap
594
+ - create “shared prerequisite” feature
595
+
596
+ Orchestrator agent decides strategy; Supervisor updates states accordingly.
597
+
598
+ ---
599
+
600
+ ## 9. Locks
601
+
602
+ ### 9.1 Lock Resources
603
+
604
+ Configured by `policy.yaml`, recommended defaults:
605
+ - `openapi`
606
+ - `events`
607
+ - `db_migrations`
608
+ - optionally: `protected:libs/core`
609
+
610
+ Contract-to-lock mapping MUST be explicit:
611
+ - `contracts.openapi=modify` requires lock `policy.locks.contract_to_resource.openapi` (default `openapi`).
612
+ - `contracts.events=modify` requires lock `policy.locks.contract_to_resource.events` (default `events`).
613
+ - `contracts.db=migration` requires lock `policy.locks.contract_to_resource.db` (default `db_migrations`).
614
+
615
+ Lease rules:
616
+ - Locks are leased, not perpetual.
617
+ - Lease TTL is `policy.locks.lease_ttl_seconds`.
618
+ - Supervisor/MCP heartbeat renews leases.
619
+ - Expired leases may be reclaimed by MCP with `error=stale_lock_reclaimed` evidence.
620
+ - Default acquisition behavior is queued/blocking (`locks.acquire_behavior=wait`) with timeout/backoff from policy.
621
+
622
+ ### 9.2 Lock Enforcement
623
+
624
+ - `plan.submit` fails if plan indicates contract changes but lock not acquired.
625
+ - `repo.apply_patch` fails if patch touches contract paths without lock.
626
+ - `feature.ready_to_merge` MUST fail if any required lock is lost before merge.
627
+ - Lock operations are performed by `orchestrator|system`; workers issue `REQUEST` outputs for arbitration.
628
+
629
+ ---
630
+
631
+ ## 10. Supervisor Runtime (Cluster Runner) — Required Behavior
632
+
633
+ ### 10.1 Responsibilities
634
+
635
+ - Maintain **one Orchestrator Agent** session (user-facing).
636
+ - Spawn **three worker sessions per feature**:
637
+ - Planner
638
+ - Builder
639
+ - QA
640
+ - Enforce **role-scoped tool access**:
641
+ - Implement a “tool-call firewall” that blocks calls not allowed for the role.
642
+ - Load role system prompts from `agentic/orchestrator/agents.yaml` when configured and inject at worker creation.
643
+ - Resolve agent runtime provider/model selection from CLI/env/config and initialize the corresponding provider adapter.
644
+ - Maintain lock lease heartbeats for active features.
645
+ - Support restart recovery:
646
+ - reattach to existing sessions when possible
647
+ - reconstruct state from `index.json` + feature states when sessions are unavailable
648
+ - re-drive blocked/retryable operations deterministically
649
+ - Run orchestration loop across features:
650
+ 1) init
651
+ 2) planning wave
652
+ 3) collision arbitration
653
+ 4) build wave
654
+ 5) qa wave
655
+ 6) readiness report (full gates)
656
+
657
+ ### 10.2 Vendor-Agnostic Worker Interface
658
+
659
+ Supervisor must treat workers abstractly:
660
+
661
+ - Worker input: `{role, feature_id, context_bundle, instructions, last_tool_results}`
662
+ - Worker input MUST include runtime selection metadata: `{provider, model, provider_config_ref}`.
663
+ - Worker output types:
664
+ - `PLAN_SUBMISSION` (planner emits plan json)
665
+ - `PATCH` (builder/qa emits unified diff)
666
+ - `NOTE` (decisions/summary)
667
+ - `REQUEST` (ask for lock, ask to amend plan, ask for more context)
668
+
669
+ Supervisor routes outputs to MCP tools and returns results to worker.
670
+
671
+ Context bundle MUST include:
672
+ - current feature state + accepted plan
673
+ - latest evidence summary
674
+ - current diff summary
675
+ - `qa_test_index.json` for QA workers
676
+
677
+ ### 10.3 Concurrency
678
+
679
+ Configurable:
680
+ - `max_active_features` default 5
681
+ - `max_parallel_gate_runs` default 2–3 (CPU dependent)
682
+ - `max_iterations_per_phase` default 5–10
683
+ - `lock_acquire_backoff_seconds` default jittered exponential backoff
684
+ - `lock_wait_timeout_seconds` default 300
685
+
686
+ ### 10.4 Phase Advancement Rules
687
+
688
+ - Feature can move to `building` only after `plan.submit` accepted.
689
+ - Feature can move to `qa` only after `fast` gates pass (policy-configurable).
690
+ - Feature can move to `ready_to_merge` only after `full` gates pass; this state is still unmerged and reviewable.
691
+ - User review MUST happen while in `ready_to_merge` before merge execution.
692
+ - `feature.ready_to_merge` (explicit call) performs commit + merge and transitions to `merged` on success.
693
+ - Feature becomes `blocked` on lock denial or collision policy outcome.
694
+
695
+ Supervisor updates status through MCP state patch tool (or via MCP internal updates triggered by other tools).
696
+ Supervisor proposes transitions; MCP is source of truth and MUST validate transition legality.
697
+
698
+ ### 10.5 Legal Status Transition Matrix (Normative)
699
+
700
+ - `planning -> building`: only via accepted `plan.submit` or `plan.update`.
701
+ - `building -> qa`: only via passing required `fast` gates.
702
+ - `qa -> ready_to_merge`: only via passing required `full` gates.
703
+ - `ready_to_merge -> merged`: only via successful `feature.ready_to_merge` call.
704
+ - `* -> blocked`: on lock/collision denial, unrecoverable gate failure, or policy violation.
705
+ - `blocked -> planning|building|qa`: only after explicit unblock event with `status_reason` update.
706
+ - Any undefined transition MUST fail with `error=invalid_status_transition`.
707
+
708
+ ### 10.6 Crash Recovery and Resume Algorithm
709
+
710
+ On Supervisor or MCP restart:
711
+ 1) Load and validate `index.json` and all active feature `state.md` files.
712
+ 2) Reconcile lock leases:
713
+ - if holder heartbeat is fresh, preserve lease
714
+ - if stale, reclaim and mark affected features `blocked` with reason
715
+ 3) Reconstruct pending work from:
716
+ - features not terminal (`merged|failed`)
717
+ - queued collisions (`blocked_queue`)
718
+ - gate runs with no terminal evidence record
719
+ - current `qa_test_index.json` entries not in terminal status (`passed|waived`)
720
+ 4) Resume orchestration from the earliest incomplete phase per feature.
721
+ 5) All tool retries MUST be idempotent and keyed by operation id; duplicate execution must not double-apply patches or merges.
722
+
723
+ ### 10.7 Ephemeral QA Session Lifecycle (Context Control)
724
+
725
+ - QA workers are intentionally short-lived to prevent unbounded context growth.
726
+ - After each QA test batch:
727
+ - QA worker MUST call `qa.test_index_update`.
728
+ - Supervisor MUST close the QA worker session.
729
+ - On next QA iteration, Supervisor MUST be able to spawn a fresh QA worker that consumes:
730
+ - `feature.get_context`
731
+ - `qa.test_index_get`
732
+ - latest gate/evidence summaries
733
+ - This resume flow MUST preserve progress without requiring prior conversational context.
734
+
735
+ ---
736
+
737
+ ## 11. Orchestrator Agent Contract (User-Facing Behavior)
738
+
739
+ Orchestrator Agent must:
740
+ - Discover provided specs from CLI-resolved inputs (`-fi`/`-fl`) or canonical repo discovery and ask user which to run if more than N are present (optional; default pick first N).
741
+ - Report dashboard status periodically (using `report.dashboard`).
742
+ - Decide collision resolution (revise plan, wait, shared prerequisite).
743
+ - Provide user review pack before merge execution:
744
+ - `repo.diff_bundle`
745
+ - `report.feature_summary`
746
+ - evidence links
747
+ - Request explicit user approval token before invoking `feature.ready_to_merge`.
748
+
749
+ Orchestrator must never claim gates passed without MCP results.
750
+
751
+ ---
752
+
753
+ ## 12. Gate Execution (Platform-Agnostic)
754
+
755
+ ### 12.1 Command Execution
756
+
757
+ MCP executes `cmd` arrays from `gates.yaml` with:
758
+ - `cwd` set to the feature worktree root
759
+ - safe environment with secret scrubbing enabled by default
760
+ - environment variable pass-through restricted to `policy.execution.env_allowlist`
761
+
762
+ ### 12.2 Parsers / Metrics
763
+
764
+ Supported parsers (V1):
765
+ - `none`
766
+ - `lcov` (line coverage)
767
+ - `junit_xml` (pass/fail + counts)
768
+ - `jacoco_xml` (line coverage)
769
+ - `cobertura_xml` (line coverage)
770
+
771
+ If parser type is unrecognized: gate fails with `error=unsupported_parser` unless policy allows skip.
772
+
773
+ ### 12.3 Threshold Enforcement
774
+
775
+ If coverage threshold configured in policy or gates:
776
+ - MCP must parse coverage and compare.
777
+ - Failure sets `gates.coverage_* = fail`.
778
+
779
+ For this implementation:
780
+ - Minimum blocking thresholds are `line >= 0.90` and `branch >= 0.90`.
781
+ - Target thresholds are `line = 1.00` and `branch = 1.00` (reported as target attainment metrics).
782
+
783
+ ### 12.4 Timeouts and Retry Defaults (Normative)
784
+
785
+ - If a gate step omits `timeout_seconds`, MCP MUST apply `policy.execution.default_step_timeout_seconds` (default `600`).
786
+ - Retries are allowed only for transient execution failures per `policy.execution.retry_policy.transient_error_codes`.
787
+ - Default transient retry count is `1`.
788
+ - Schema/policy/authorization/path violations are non-retryable by default.
789
+
790
+ ### 12.5 Configuration Precedence (Normative)
791
+
792
+ For any gate execution parameter, precedence is:
793
+ 1) `policy.yaml` hard constraints (cannot be relaxed)
794
+ 2) `gates.yaml` selected profile/mode defaults
795
+ 3) `plan.json.verification_overrides` (may only narrow scope or tighten thresholds)
796
+
797
+ If a lower-priority source attempts to relax a higher-priority constraint, MCP MUST fail with `error=invalid_override_precedence`.
798
+
799
+ ### 12.6 Nx + Vitest Testing Contract (Implementation)
800
+
801
+ - The orchestrator codebase MUST be implemented as an Nx monorepo.
802
+ - The unit/integration test runner for the orchestrator codebase MUST be Vitest.
803
+ - Default test gate commands for orchestrator projects SHOULD use Nx task execution (for example `nx test <project> --coverage`).
804
+ - Coverage artifacts MUST be emitted in a parser-compatible format (`lcov` preferred) so MCP can enforce thresholds.
805
+
806
+ ---
807
+
808
+ ## 13. Docker Deployment Requirements
809
+
810
+ ### 13.1 Required Mounts
811
+
812
+ - Repo mounted to `/repo`
813
+ - Optional caches:
814
+ - `/cache/pnpm`
815
+ - `/cache/m2`
816
+ - `/cache/cargo`
817
+
818
+ ### 13.2 Toolchains
819
+
820
+ Repo toolchains must exist in the container image used to run MCP (either per-repo image or universal). MCP itself stays toolchain-agnostic.
821
+ For this implementation, container/runtime environment MUST include Node.js and Nx-compatible tooling required to run Vitest via Nx tasks.
822
+
823
+ ---
824
+
825
+ ## 14. Acceptance Criteria (Complete)
826
+
827
+ A) **Kernel correctness**
828
+ - Plan schema validation rejects invalid plans with actionable errors.
829
+ - Plan revisions are versioned and protected by optimistic concurrency.
830
+ - Patch enforcement prevents edits outside plan/allowed areas.
831
+ - Gate runner executes config commands and stores logs/evidence.
832
+ - Locks and collisions prevent conflicting edits deterministically.
833
+ - State files are updated only by MCP and validated by schema.
834
+ - State/index writes are atomic and race-safe under parallel runs.
835
+
836
+ B) **Parallelism and visibility**
837
+ - 5 features can run concurrently with 5 worktrees.
838
+ - User can open `.worktrees/<feature_id>` (for example `.worktrees/my_feature`) locally to review unmerged changes.
839
+
840
+ C) **Platform-agnostic gates**
841
+ - Same MCP works on managed target repositories:
842
+ - Nx repo (nx commands in gates.yaml)
843
+ - Java repo (mvn/gradle commands in gates.yaml)
844
+ - Rust repo (cargo commands in gates.yaml)
845
+ No MCP code changes required.
846
+
847
+ D) **Orchestrator/cluster architecture**
848
+ - User interacts only with Orchestrator Agent.
849
+ - Supervisor spawns worker sessions per feature.
850
+ - Tool-call firewall enforces role tool permissions.
851
+ - System produces dashboard and per-feature review bundle.
852
+ - Merge only occurs via explicit `feature.ready_to_merge` call after user approval.
853
+ - If role prompts exist in repo config, spawned workers receive them as system prompts.
854
+ - QA worker runs can be closed/restarted while preserving progress via MCP-backed `qa_test_index.json`.
855
+
856
+ E) **CLI entrypoint contract**
857
+ - `aop run -fi <file>` launches exactly one Agent Cluster for that file.
858
+ - `aop run -fl <folder>` launches one Agent Cluster per resolved spec file in the folder.
859
+ - `-fi` and `-fl` mutual exclusion is enforced with deterministic structured errors.
860
+ - Folder inputs are resolved deterministically and queued beyond `max_active_features`.
861
+ - Agent runtime provider/model can be selected via CLI flags with env/config fallback and deterministic precedence.
862
+ - Feature branch/worktree folder names are derived from spec filenames using the `.spec` / `-spec` trimming rules.
863
+
864
+ F) **Implementation testing standards**
865
+ - Orchestrator control-plane implementation (CLI/Supervisor/MCP) is structured as an Nx monorepo.
866
+ - Automated tests for that control-plane implementation are executed with Vitest.
867
+ - Blocking coverage minimum is 90% for both line and branch.
868
+ - Coverage target is 100% for both line and branch, reported in evidence summaries.
869
+ - Managed target repositories remain toolchain-agnostic and are validated only by their configured gates.
870
+
871
+ ---
872
+
873
+ ## 15. Implementation Milestones
874
+
875
+ ### 15.1 Implementation Progress Artifact (Non-Runtime Requirement)
876
+
877
+ While implementing this spec, the implementing agent MUST maintain `spec-files/progress.md` used only for implementation continuity.
878
+
879
+ Required `spec-files/progress.md` contents:
880
+ - current milestone (`M0..M9`) and current task
881
+ - completed tasks since last update
882
+ - next tasks planned
883
+ - open blockers/risks
884
+ - handoff summary for the next agent session
885
+ - last updated timestamp
886
+
887
+ Update policy:
888
+ - update `spec-files/progress.md` after each meaningful implementation step
889
+ - update `spec-files/progress.md` before ending/closing an agent session for context reset
890
+ - the next agent session MUST start by reading `spec-files/progress.md` before making changes
891
+
892
+ Scope note:
893
+ - `spec-files/progress.md` in this section is an implementation-process artifact only.
894
+ - It MUST NOT be required by, read by, or enforced by the orchestrator runtime (MCP/Supervisor/worker logic).
895
+
896
+ **M0: Implementation Handoff Tracking (non-runtime)**
897
+ - create and maintain `spec-files/progress.md` throughout implementation.
898
+ - keep milestone position and handoff notes current for session-to-session continuity.
899
+
900
+ **M1: MCP Kernel V1 (single feature)**
901
+ - feature.init, plan.submit validation, ensure_worktree, apply_patch enforcement, gates.run, evidence.latest, state updates.
902
+
903
+ **M2: Worktrees + Parallelism**
904
+ - worktree-per-feature, index.json, locks, collisions.
905
+
906
+ **M3: Supervisor Runtime**
907
+ - orchestrator + worker abstractions, role enforcement, orchestration loop, reporting tools.
908
+
909
+ **M4: Platform-Agnostic Profiles**
910
+ - gates.yaml profiles, multi-target gate runs, line/branch coverage parsing.
911
+
912
+ **M5: Review + Merge Control**
913
+ - diff bundles, dashboard summary, explicit user approval flow, `feature.ready_to_merge` commit+merge path.
914
+
915
+ **M6: Resilience and Recovery**
916
+ - lock leases + heartbeat, restart recovery, queued collision unblock processing.
917
+
918
+ **M7: Prompt + QA Context Management**
919
+ - repo-level worker prompt loading via `agents.yaml`.
920
+ - per-feature QA change/test index maintenance and short-lived QA worker resume flow.
921
+
922
+ **M8: Supervisor CLI Entrypoint**
923
+ - implement `aop run` contract with `-fi` and `-fl`.
924
+ - deterministic folder scan + spec ingestion to canonical feature layout.
925
+ - derive `feature_id`/branch/worktree folder names from spec filename stems with `.spec` / `-spec` suffix trimming.
926
+ - startup validation, provider selection resolution, structured errors, and dashboard streaming bootstrap.
927
+
928
+ **M9: Nx + Vitest Quality Gates**
929
+ - scaffold/organize orchestrator implementation as Nx monorepo projects.
930
+ - implement Vitest-based test tasks and coverage artifact generation.
931
+ - enforce 90% line/branch minimums with 100% line/branch target reporting.
932
+
933
+ ---
934
+
935
+ ## 16. Resolved Operational Defaults
936
+
937
+ The following defaults are accepted and normative:
938
+
939
+ 1) Lock operations are owned by `orchestrator|system`; worker roles submit `REQUEST`.
940
+ 2) Lock acquisition defaults to blocking/queued with timeout + jittered backoff.
941
+ 3) Plan revisions keep existing diffs in worktree; future patch applies are validated against latest accepted plan.
942
+ 4) Supervisor proposes state transitions, MCP validates legality and persists canonical state.
943
+ 5) `collision_policy=block` uses persistent `blocked_queue` with deterministic ordering.
944
+ 6) Precedence is `policy hard constraints > gates profile defaults > plan overrides (tighten-only)`.
945
+ 7) Gate timeout default is 600s when unspecified; transient retry default is 1; policy/schema violations are non-retryable.
946
+ 8) Review artifacts are unmerged worktree diffs; commit+merge happen only through explicit `feature.ready_to_merge`.
947
+ 9) Restart recovery uses lease heartbeats and stale-lease reclamation with deterministic unblock flow.
948
+ 10) Secret handling is default-on scrub/redaction with explicit env allowlist.
949
+ 11) Orchestrator implementation uses Nx + Vitest with 90% line/branch minimum coverage and 100% line/branch target.
950
+ 12) Agent provider/model selection precedence is CLI flags > env vars > `agents.yaml` runtime defaults.
951
+
952
+ ---
953
+
954
+ ## 17. CLI Entrypoint Contract
955
+
956
+ The Supervisor Runtime MUST provide a CLI entrypoint named `aop`.
957
+
958
+ ### 17.1 Primary Command
959
+
960
+ ```bash
961
+ aop run [options]
962
+ ```
963
+
964
+ Required behavior:
965
+ - Starts/attaches MCP connectivity.
966
+ - Creates one user-facing Orchestrator session.
967
+ - Resolves input specs (from `-fi`, `-fl`, or default discovery).
968
+ - Spins up one Agent Cluster per resolved feature spec (subject to `max_active_features`; overflow queues deterministically).
969
+
970
+ ### 17.2 Input Selection Options
971
+
972
+ Supported options:
973
+ - `-fi <path>`: file input. Treat the referenced file as one feature spec and spin up exactly one Agent Cluster.
974
+ - `-fl <path>`: folder input. Treat all spec files in the folder as feature inputs and spin up one Agent Cluster per resolved file.
975
+ - `--agent-provider <codex|claude|gemini|custom>`: selects agent runtime provider for orchestrator and worker sessions.
976
+ - `--agent-model <model-id>`: selects provider model identifier.
977
+ - `--provider-config-env <ENV_VAR>`: env var name carrying provider credentials/config reference.
978
+
979
+ Mutual exclusion and defaults:
980
+ - `-fi` and `-fl` are mutually exclusive.
981
+ - If both are provided, CLI MUST fail with `error=invalid_cli_args`.
982
+ - If neither is provided, use canonical discovery (`feature.discover_specs`).
983
+
984
+ Example:
985
+
986
+ ```bash
987
+ aop run -fl ./specfiles
988
+ ```
989
+
990
+ ### 17.3 Folder Resolution Rules (`-fl`)
991
+
992
+ - Folder traversal MUST be deterministic (lexicographic path order).
993
+ - Default scan pattern is recursive `**/*.md`.
994
+ - Each resolved file is treated as an independent feature spec input.
995
+ - If no spec files are found, CLI MUST fail with `error=no_specs_found`.
996
+
997
+ ### 17.4 Spec Ingestion to Canonical Repo Layout
998
+
999
+ For inputs outside `agentic/features/*/spec.md`, Supervisor MUST ingest them into canonical layout:
1000
+ - Derive `feature_id` deterministically from spec filename using this algorithm:
1001
+ 1. Start from filename stem (basename without final extension).
1002
+ 2. If the stem ends with `.spec`, remove that suffix.
1003
+ 3. Else if the stem ends with `-spec`, remove that suffix.
1004
+ 4. Resulting value is `feature_id` and MUST be used as both branch name and worktree folder name.
1005
+ 5. Resulting `feature_id` MUST match `^[a-z0-9_][a-z0-9_-]*$`.
1006
+ - Copy source content to `agentic/features/<feature_id>/spec.md`.
1007
+ - Record source path and source hash in feature state metadata.
1008
+ - If derived `feature_id` is empty or does not meet naming rules, fail with `error=invalid_feature_slug`.
1009
+ - If multiple inputs resolve to the same `feature_id`, fail with `error=feature_slug_collision`.
1010
+
1011
+ If input path is already canonical (`agentic/features/<feature_id>/spec.md`):
1012
+ - Use existing `feature_id` from path and do not duplicate content.
1013
+
1014
+ Examples:
1015
+ - `my_feature.spec.md` -> `feature_id=my_feature`, branch `my_feature`, worktree `.worktrees/my_feature`
1016
+ - `my_feature-spec.md` -> `feature_id=my_feature`, branch `my_feature`, worktree `.worktrees/my_feature`
1017
+ - `my_feature.md` -> `feature_id=my_feature`, branch `my_feature`, worktree `.worktrees/my_feature`
1018
+
1019
+ ### 17.5 Operational Semantics
1020
+
1021
+ - `aop run -fi ...` starts one feature flow.
1022
+ - `aop run -fl ...` starts N feature flows (N = resolved spec files).
1023
+ - Features beyond `max_active_features` MUST be queued and activated as slots free up.
1024
+ - CLI SHOULD stream dashboard updates derived from `report.dashboard`.
1025
+
1026
+ ### 17.6 Exit and Status Contract
1027
+
1028
+ - Exit `0` when run initializes successfully and runtime enters active orchestration mode.
1029
+ - Non-zero exit on startup/argument/input validation failures.
1030
+ - MUST return structured error payloads aligned with Appendix D error format for machine callers.
1031
+
1032
+ ### 17.7 Agent Provider Selection Contract
1033
+
1034
+ Provider selection precedence (highest to lowest):
1035
+ 1) CLI flags: `--agent-provider`, `--agent-model`, `--provider-config-env`
1036
+ 2) Environment variables:
1037
+ - `AOP_AGENT_PROVIDER`
1038
+ - `AOP_AGENT_MODEL`
1039
+ - `AOP_PROVIDER_CONFIG_ENV`
1040
+ 3) `agentic/orchestrator/agents.yaml` `runtime.*` defaults
1041
+
1042
+ Rules:
1043
+ - If no provider can be resolved, CLI MUST fail with `error=agent_provider_not_configured`.
1044
+ - If provider value is unsupported, CLI MUST fail with `error=unsupported_agent_provider`.
1045
+ - If provider requires credentials/config and none is available, CLI MUST fail with `error=provider_auth_missing`.
1046
+ - Supervisor MUST record resolved provider/model in run metadata for auditability.
1047
+
1048
+ Recommended additional commands (V1.1):
1049
+ - `aop status` (reads dashboard/status)
1050
+ - `aop resume` (resume prior run state)
1051
+ - `aop stop` (graceful shutdown)
1052
+
1053
+ ---
1054
+
1055
+ ## Appendix A — Full JSON Schema: plan.schema.json (Draft)
1056
+
1057
+ ```json
1058
+ {
1059
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
1060
+ "$id": "https://example.local/agentic/plan.schema.json",
1061
+ "type": "object",
1062
+ "additionalProperties": false,
1063
+ "required": [
1064
+ "feature_id",
1065
+ "plan_version",
1066
+ "summary",
1067
+ "allowed_areas",
1068
+ "forbidden_areas",
1069
+ "base_ref",
1070
+ "files",
1071
+ "contracts",
1072
+ "acceptance_criteria",
1073
+ "gate_profile"
1074
+ ],
1075
+ "properties": {
1076
+ "feature_id": {
1077
+ "type": "string",
1078
+ "pattern": "^[a-z0-9_][a-z0-9_-]*$"
1079
+ },
1080
+ "plan_version": {
1081
+ "type": "integer",
1082
+ "minimum": 1
1083
+ },
1084
+ "summary": {
1085
+ "type": "string",
1086
+ "minLength": 5
1087
+ },
1088
+ "allowed_areas": {
1089
+ "type": "array",
1090
+ "items": { "type": "string", "minLength": 1 },
1091
+ "minItems": 1
1092
+ },
1093
+ "forbidden_areas": {
1094
+ "type": "array",
1095
+ "items": { "type": "string", "minLength": 1 }
1096
+ },
1097
+ "base_ref": {
1098
+ "type": "string",
1099
+ "minLength": 1
1100
+ },
1101
+ "files": {
1102
+ "type": "object",
1103
+ "additionalProperties": false,
1104
+ "required": ["create", "modify", "delete"],
1105
+ "properties": {
1106
+ "create": { "type": "array", "items": { "type": "string", "minLength": 1 } },
1107
+ "modify": { "type": "array", "items": { "type": "string", "minLength": 1 } },
1108
+ "delete": { "type": "array", "items": { "type": "string", "minLength": 1 } }
1109
+ }
1110
+ },
1111
+ "contracts": {
1112
+ "type": "object",
1113
+ "additionalProperties": false,
1114
+ "required": ["openapi", "events", "db"],
1115
+ "properties": {
1116
+ "openapi": { "type": "string", "enum": ["none", "modify"] },
1117
+ "events": { "type": "string", "enum": ["none", "modify"] },
1118
+ "db": { "type": "string", "enum": ["none", "migration"] }
1119
+ }
1120
+ },
1121
+ "acceptance_criteria": {
1122
+ "type": "array",
1123
+ "items": { "type": "string", "minLength": 1 },
1124
+ "minItems": 1
1125
+ },
1126
+ "gate_profile": { "type": "string", "minLength": 1 },
1127
+ "gate_targets": {
1128
+ "type": "array",
1129
+ "items": { "type": "string", "minLength": 1 },
1130
+ "minItems": 1
1131
+ },
1132
+ "risk": {
1133
+ "type": "array",
1134
+ "items": { "type": "string", "minLength": 1 }
1135
+ },
1136
+ "revision_of": {
1137
+ "type": "integer",
1138
+ "minimum": 1
1139
+ },
1140
+ "revision_reason": {
1141
+ "type": "string",
1142
+ "minLength": 1
1143
+ },
1144
+ "verification_overrides": {
1145
+ "type": "object",
1146
+ "additionalProperties": false,
1147
+ "properties": {
1148
+ "modes": {
1149
+ "type": "object",
1150
+ "additionalProperties": false,
1151
+ "properties": {
1152
+ "fast": { "$ref": "#/$defs/modeOverride" },
1153
+ "full": { "$ref": "#/$defs/modeOverride" }
1154
+ }
1155
+ }
1156
+ }
1157
+ }
1158
+ },
1159
+ "$defs": {
1160
+ "modeOverride": {
1161
+ "type": "object",
1162
+ "additionalProperties": false,
1163
+ "properties": {
1164
+ "steps": {
1165
+ "type": "array",
1166
+ "items": {
1167
+ "type": "object",
1168
+ "additionalProperties": false,
1169
+ "required": ["name", "cmd"],
1170
+ "properties": {
1171
+ "name": { "type": "string", "minLength": 1 },
1172
+ "cmd": {
1173
+ "type": "array",
1174
+ "items": { "type": "string", "minLength": 1 },
1175
+ "minItems": 1
1176
+ },
1177
+ "timeout_seconds": { "type": "number", "minimum": 1 }
1178
+ }
1179
+ }
1180
+ }
1181
+ }
1182
+ }
1183
+ }
1184
+ }
1185
+ ```
1186
+
1187
+ ---
1188
+
1189
+ ## Appendix B — state.schema.json (Front matter object) Outline
1190
+
1191
+ ```json
1192
+ {
1193
+ "$schema": "https://json-schema.org/draft/2020-12/schema",
1194
+ "type": "object",
1195
+ "additionalProperties": true,
1196
+ "required": [
1197
+ "feature_id",
1198
+ "version",
1199
+ "branch",
1200
+ "worktree_path",
1201
+ "status",
1202
+ "gate_profile",
1203
+ "gates",
1204
+ "locks",
1205
+ "collisions",
1206
+ "cluster",
1207
+ "role_status",
1208
+ "last_updated"
1209
+ ],
1210
+ "properties": {
1211
+ "feature_id": { "type": "string" },
1212
+ "version": { "type": "integer", "minimum": 1 },
1213
+ "branch": { "type": "string" },
1214
+ "worktree_path": { "type": "string" },
1215
+ "status": {
1216
+ "type": "string",
1217
+ "enum": ["planning","building","qa","blocked","ready_to_merge","merged","failed"]
1218
+ },
1219
+ "gate_profile": { "type": "string" },
1220
+ "gates": {
1221
+ "type": "object",
1222
+ "additionalProperties": { "type": "string", "enum": ["pass","fail","na"] }
1223
+ },
1224
+ "locks": {
1225
+ "type": "object",
1226
+ "required": ["held"],
1227
+ "properties": {
1228
+ "held": { "type": "array", "items": { "type": "string" } }
1229
+ }
1230
+ },
1231
+ "collisions": {
1232
+ "type": "object",
1233
+ "required": ["files","areas","contracts"],
1234
+ "properties": {
1235
+ "files": { "type": "array", "items": { "type": "object" } },
1236
+ "areas": { "type": "array", "items": { "type": "object" } },
1237
+ "contracts": { "type": "array", "items": { "type": "object" } }
1238
+ }
1239
+ },
1240
+ "cluster": {
1241
+ "type": "object",
1242
+ "required": ["orchestrator_session_id","planner_session_id","builder_session_id","qa_session_id"],
1243
+ "properties": {
1244
+ "orchestrator_session_id": { "type": "string" },
1245
+ "planner_session_id": { "type": "string" },
1246
+ "builder_session_id": { "type": "string" },
1247
+ "qa_session_id": { "type": "string" }
1248
+ }
1249
+ },
1250
+ "role_status": {
1251
+ "type": "object",
1252
+ "required": ["planner","builder","qa"],
1253
+ "properties": {
1254
+ "planner": { "type": "string", "enum": ["ready","running","blocked","done"] },
1255
+ "builder": { "type": "string", "enum": ["ready","running","blocked","done"] },
1256
+ "qa": { "type": "string", "enum": ["ready","running","blocked","done"] }
1257
+ }
1258
+ },
1259
+ "last_updated": { "type": "string" },
1260
+ "status_reason": { "type": "string" }
1261
+ }
1262
+ }
1263
+ ```
1264
+
1265
+ ---
1266
+
1267
+ ## Appendix C — gates.yaml + policy.yaml + agents.yaml Schema Notes
1268
+
1269
+ - MCP MUST validate loaded YAML against `gates.schema.json` and `policy.schema.json` and fail fast if invalid.
1270
+ - Supervisor/MCP MUST validate `agents.yaml` against `agents.schema.json` if file is present.
1271
+ - Unknown gate profile/mode must yield `error=unknown_gate_profile_or_mode`.
1272
+ - If `policy.commit_policy.allow_commit=false`, `repo.commit` must return `error=commit_disabled`.
1273
+ - Precedence MUST follow §12.5; invalid relaxations must return `error=invalid_override_precedence`.
1274
+ - If `policy.merge_policy.require_user_approval=true`, `feature.ready_to_merge` without valid approval token MUST return `error=user_approval_required`.
1275
+ - If `agents.yaml.missing_prompt_behavior=error`, missing configured prompt file MUST return `error=missing_role_prompt`.
1276
+ - For this implementation, `policy.implementation.workspace` MUST be `nx` and `policy.testing.framework` MUST be `vitest`.
1277
+ - Coverage policy minimums MUST enforce `line>=0.90` and `branch>=0.90`; targets MUST be configured at `1.00`.
1278
+ - CLI/env/provider resolution MUST follow §17.7 and fail closed on unresolved/unsupported providers.
1279
+
1280
+ ---
1281
+
1282
+ ## Appendix D — Required Structured Error Format
1283
+
1284
+ All MCP tool failures must return:
1285
+
1286
+ ```json
1287
+ {
1288
+ "ok": false,
1289
+ "error": {
1290
+ "code": "string_enum",
1291
+ "message": "human readable",
1292
+ "details": { "any": "json" }
1293
+ },
1294
+ "evidence": { "log_path": "optional" }
1295
+ }
1296
+ ```
1297
+
1298
+ Required error codes (minimum set):
1299
+ - `forbidden_tool_for_role`
1300
+ - `version_conflict`
1301
+ - `invalid_status_transition`
1302
+ - `unknown_gate_profile_or_mode`
1303
+ - `unsupported_parser`
1304
+ - `gate_timeout`
1305
+ - `transient_exec_failure`
1306
+ - `coverage_below_minimum`
1307
+ - `invalid_override_precedence`
1308
+ - `path_out_of_bounds`
1309
+ - `lock_not_held`
1310
+ - `lock_conflict`
1311
+ - `stale_lock_reclaimed`
1312
+ - `collision_detected`
1313
+ - `blocked_by_collision_policy`
1314
+ - `commit_disabled`
1315
+ - `merge_disabled`
1316
+ - `user_approval_required`
1317
+ - `missing_role_prompt`
1318
+ - `qa_index_version_conflict`
1319
+ - `invalid_cli_args`
1320
+ - `input_path_not_found`
1321
+ - `no_specs_found`
1322
+ - `spec_ingest_failed`
1323
+ - `invalid_feature_slug`
1324
+ - `feature_slug_collision`
1325
+ - `invalid_workspace_implementation`
1326
+ - `agent_provider_not_configured`
1327
+ - `unsupported_agent_provider`
1328
+ - `provider_auth_missing`
1329
+
1330
+ Error details SHOULD include:
1331
+ - `retryable` boolean
1332
+ - `requires_human` boolean
1333
+ - `conflicting_feature_ids` (when relevant)
1334
+ - `suggested_next_actions` array