agentic-orchestrator 0.1.28 → 0.2.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 (836) hide show
  1. package/.claude/settings.local.json +46 -1
  2. package/.cortexrc +28 -0
  3. package/.github/agents/copilot-instructions.md +29 -0
  4. package/.github/copilot-instructions.md +93 -0
  5. package/.vscode/settings.json +13 -0
  6. package/.vscode/tms.code-snippets +223 -0
  7. package/AGENTS.md +72 -1
  8. package/Agentic-Orchestrator.iml +12 -11
  9. package/CLAUDE.md +72 -1
  10. package/CONSTITUTION.md +504 -0
  11. package/FUTURE-ENHANCEMENTS.md +85 -0
  12. package/NEXT-TASKS.md +25 -0
  13. package/PROMPTS.md +161 -0
  14. package/README.md +126 -29
  15. package/agentic/orchestrator/agents.yaml +4 -3
  16. package/agentic/orchestrator/defaults/policy.defaults.yaml +39 -3
  17. package/agentic/orchestrator/gates.yaml +15 -3
  18. package/agentic/orchestrator/policy.yaml +47 -3
  19. package/agentic/orchestrator/prompts/builder.system.md +69 -20
  20. package/agentic/orchestrator/prompts/planner-intake.system.md +149 -0
  21. package/agentic/orchestrator/prompts/planner.system.md +113 -40
  22. package/agentic/orchestrator/prompts/qa.system.md +73 -18
  23. package/agentic/orchestrator/prompts/reconciler.system.md +119 -0
  24. package/agentic/orchestrator/schemas/agents.schema.json +89 -1
  25. package/agentic/orchestrator/schemas/execution-control.schema.json +242 -0
  26. package/agentic/orchestrator/schemas/index.schema.json +234 -0
  27. package/agentic/orchestrator/schemas/intake.review.schema.json +82 -0
  28. package/agentic/orchestrator/schemas/organizer-ordering-artifact.schema.json +75 -0
  29. package/agentic/orchestrator/schemas/plan.schema.json +44 -0
  30. package/agentic/orchestrator/schemas/policy.schema.json +238 -9
  31. package/agentic/orchestrator/schemas/policy.user.schema.json +129 -1
  32. package/agentic/orchestrator/schemas/spec.manifest.bootstrap.schema.json +101 -0
  33. package/agentic/orchestrator/schemas/spec.manifest.verified.schema.json +80 -0
  34. package/agentic/orchestrator/schemas/state.schema.json +298 -3
  35. package/agentic/orchestrator/tools/catalog.json +145 -15
  36. package/agentic/orchestrator/tools/schemas/input/doctor.run.input.schema.json +18 -0
  37. package/agentic/orchestrator/tools/schemas/input/evidence.latest.input.schema.json +4 -0
  38. package/agentic/orchestrator/tools/schemas/input/evidence.verify_chain.input.schema.json +13 -0
  39. package/agentic/orchestrator/tools/schemas/input/feature.intake_submit.input.schema.json +11 -0
  40. package/agentic/orchestrator/tools/schemas/input/feature.question_answer.input.schema.json +15 -0
  41. package/agentic/orchestrator/tools/schemas/input/feature.question_create.input.schema.json +21 -0
  42. package/agentic/orchestrator/tools/schemas/input/feature.question_list.input.schema.json +13 -0
  43. package/agentic/orchestrator/tools/schemas/input/feature.ready_to_merge.input.schema.json +5 -0
  44. package/agentic/orchestrator/tools/schemas/input/feature.send_message.input.schema.json +1 -1
  45. package/agentic/orchestrator/tools/schemas/input/replay.timeline_get.input.schema.json +32 -0
  46. package/agentic/orchestrator/tools/schemas/input/repo.conflict_abort.input.schema.json +16 -0
  47. package/agentic/orchestrator/tools/schemas/input/repo.conflict_files.input.schema.json +16 -0
  48. package/agentic/orchestrator/tools/schemas/input/repo.reconcile_mainline.input.schema.json +37 -0
  49. package/agentic/orchestrator/tools/schemas/input/repo.resolve_conflict.input.schema.json +40 -0
  50. package/agentic/orchestrator/tools/schemas/input/runtime.execution_request_list.input.schema.json +7 -0
  51. package/agentic/orchestrator/tools/schemas/input/runtime.execution_request_submit.input.schema.json +25 -0
  52. package/agentic/orchestrator/tools/schemas/output/doctor.run.output.schema.json +34 -0
  53. package/agentic/orchestrator/tools/schemas/output/evidence.verify_chain.output.schema.json +23 -0
  54. package/agentic/orchestrator/tools/schemas/output/feature.get_context.output.schema.json +62 -2
  55. package/agentic/orchestrator/tools/schemas/output/feature.intake_submit.output.schema.json +24 -0
  56. package/agentic/orchestrator/tools/schemas/output/feature.question_answer.output.schema.json +21 -0
  57. package/agentic/orchestrator/tools/schemas/output/feature.question_create.output.schema.json +12 -0
  58. package/agentic/orchestrator/tools/schemas/output/feature.question_list.output.schema.json +14 -0
  59. package/agentic/orchestrator/tools/schemas/output/feature.ready_to_merge.output.schema.json +31 -0
  60. package/agentic/orchestrator/tools/schemas/output/feature.send_message.output.schema.json +8 -18
  61. package/agentic/orchestrator/tools/schemas/output/replay.timeline_get.output.schema.json +64 -0
  62. package/agentic/orchestrator/tools/schemas/output/repo.conflict_abort.output.schema.json +16 -0
  63. package/agentic/orchestrator/tools/schemas/output/repo.conflict_files.output.schema.json +22 -0
  64. package/agentic/orchestrator/tools/schemas/output/repo.reconcile_mainline.output.schema.json +61 -0
  65. package/agentic/orchestrator/tools/schemas/output/repo.resolve_conflict.output.schema.json +19 -0
  66. package/agentic/orchestrator/tools/schemas/output/report.dashboard.output.schema.json +26 -0
  67. package/agentic/orchestrator/tools/schemas/output/runtime.execution_request_list.output.schema.json +17 -0
  68. package/agentic/orchestrator/tools/schemas/output/runtime.execution_request_submit.output.schema.json +24 -0
  69. package/agentic/orchestrator/tools.md +13 -0
  70. package/apps/control-plane/scripts/validate-mcp-contracts.ts +1 -1
  71. package/apps/control-plane/src/application/kernel-tool-wiring.ts +140 -2
  72. package/apps/control-plane/src/application/services/activity-monitor-service.ts +44 -1
  73. package/apps/control-plane/src/application/services/bootstrap-manifest-generator-service.ts +251 -0
  74. package/apps/control-plane/src/application/services/checkpoint-service.ts +87 -27
  75. package/apps/control-plane/src/application/services/collision-override-service.ts +906 -0
  76. package/apps/control-plane/src/application/services/collision-queue-service.ts +129 -38
  77. package/apps/control-plane/src/application/services/cost-tracking-service.ts +94 -0
  78. package/apps/control-plane/src/application/services/execution-control-service.ts +599 -0
  79. package/apps/control-plane/src/application/services/feature-deletion-service.ts +37 -1
  80. package/apps/control-plane/src/application/services/feature-lifecycle-service.ts +182 -4
  81. package/apps/control-plane/src/application/services/feature-send-message-service.ts +17 -8
  82. package/apps/control-plane/src/application/services/feature-state-service.ts +191 -6
  83. package/apps/control-plane/src/application/services/gate-service.ts +121 -2
  84. package/apps/control-plane/src/application/services/git-reconciliation-service.ts +1591 -0
  85. package/apps/control-plane/src/application/services/intake-service.ts +1468 -0
  86. package/apps/control-plane/src/application/services/merge-service.ts +308 -17
  87. package/apps/control-plane/src/application/services/notifier-service.ts +3 -1
  88. package/apps/control-plane/src/application/services/performance-analytics-service.ts +75 -0
  89. package/apps/control-plane/src/application/services/plan-service.ts +336 -20
  90. package/apps/control-plane/src/application/services/question-service.ts +693 -0
  91. package/apps/control-plane/src/application/services/reactions-service.ts +73 -17
  92. package/apps/control-plane/src/application/services/replay-timeline-service.ts +295 -0
  93. package/apps/control-plane/src/application/services/reporting-service.ts +194 -10
  94. package/apps/control-plane/src/application/services/run-lease-service.ts +121 -5
  95. package/apps/control-plane/src/application/services/worktree-watchdog-service.ts +95 -8
  96. package/apps/control-plane/src/application/tools/tool-metadata.ts +7 -0
  97. package/apps/control-plane/src/application/usage-types.ts +138 -0
  98. package/apps/control-plane/src/cli/add-command-handler.ts +162 -0
  99. package/apps/control-plane/src/cli/answer-command-handler.ts +113 -0
  100. package/apps/control-plane/src/cli/attach-command-handler.ts +12 -3
  101. package/apps/control-plane/src/cli/cli-argument-parser.ts +133 -11
  102. package/apps/control-plane/src/cli/collision-command-handler.ts +113 -0
  103. package/apps/control-plane/src/cli/command-catalog.ts +479 -0
  104. package/apps/control-plane/src/cli/complete-command-handler.ts +23 -0
  105. package/apps/control-plane/src/cli/completion-command-handler.ts +25 -0
  106. package/apps/control-plane/src/cli/completion-resolver.ts +319 -0
  107. package/apps/control-plane/src/cli/completion-shell-renderer.ts +58 -0
  108. package/apps/control-plane/src/cli/dashboard-command-handler.ts +110 -1
  109. package/apps/control-plane/src/cli/dashboard-runtime-runner.ts +1036 -0
  110. package/apps/control-plane/src/cli/dashboard-runtime.ts +31 -0
  111. package/apps/control-plane/src/cli/help-command-handler.ts +17 -185
  112. package/apps/control-plane/src/cli/init-command-handler.ts +51 -6
  113. package/apps/control-plane/src/cli/merge-command-handler.ts +200 -0
  114. package/apps/control-plane/src/cli/questions-command-handler.ts +70 -0
  115. package/apps/control-plane/src/cli/replay-command-handler.ts +98 -0
  116. package/apps/control-plane/src/cli/resume-command-handler.ts +231 -16
  117. package/apps/control-plane/src/cli/retry-command-handler.ts +229 -17
  118. package/apps/control-plane/src/cli/retry-resume-decision.ts +75 -0
  119. package/apps/control-plane/src/cli/rollback-command-handler.ts +4 -2
  120. package/apps/control-plane/src/cli/run-command-handler.ts +35 -1
  121. package/apps/control-plane/src/cli/spec-ingestion-service.ts +45 -55
  122. package/apps/control-plane/src/cli/spec-preparation.ts +114 -0
  123. package/apps/control-plane/src/cli/spec-utils.ts +90 -11
  124. package/apps/control-plane/src/cli/status-command-handler.ts +122 -0
  125. package/apps/control-plane/src/cli/types.ts +41 -3
  126. package/apps/control-plane/src/core/collisions.ts +150 -31
  127. package/apps/control-plane/src/core/constants.ts +18 -1
  128. package/apps/control-plane/src/core/error-codes.ts +39 -0
  129. package/apps/control-plane/src/core/execution-control.ts +56 -0
  130. package/apps/control-plane/src/core/feature-resume-phase.ts +118 -0
  131. package/apps/control-plane/src/core/gate-freshness.ts +359 -0
  132. package/apps/control-plane/src/core/gate-log-extractor.ts +97 -0
  133. package/apps/control-plane/src/core/gates.ts +90 -1
  134. package/apps/control-plane/src/core/intake-artifacts.ts +295 -0
  135. package/apps/control-plane/src/core/kernel-types.ts +11 -0
  136. package/apps/control-plane/src/core/kernel.ts +604 -16
  137. package/apps/control-plane/src/core/mainline-conflict.ts +22 -0
  138. package/apps/control-plane/src/core/merge-repair.ts +149 -0
  139. package/apps/control-plane/src/core/path-layout.ts +46 -2
  140. package/apps/control-plane/src/core/path-rules.ts +11 -3
  141. package/apps/control-plane/src/core/plan-submit-recovery.ts +130 -0
  142. package/apps/control-plane/src/core/questions.ts +49 -0
  143. package/apps/control-plane/src/core/runtime-sessions.ts +4 -0
  144. package/apps/control-plane/src/core/schemas.ts +40 -1
  145. package/apps/control-plane/src/core/tool-caller.ts +25 -1
  146. package/apps/control-plane/src/core/utils/index-normalizer.ts +25 -4
  147. package/apps/control-plane/src/core/worktree-diff.ts +66 -0
  148. package/apps/control-plane/src/index.ts +29 -1
  149. package/apps/control-plane/src/interfaces/cli/bootstrap.ts +300 -6
  150. package/apps/control-plane/src/mcp/kernel-tool-executor.ts +17 -0
  151. package/apps/control-plane/src/mcp/tool-runtime.ts +63 -4
  152. package/apps/control-plane/src/providers/api-worker-provider.ts +62 -15
  153. package/apps/control-plane/src/providers/cli-worker-provider.ts +1037 -61
  154. package/apps/control-plane/src/providers/output-parsers/generic-output-parser.ts +99 -1
  155. package/apps/control-plane/src/providers/output-parsers/types.ts +2 -0
  156. package/apps/control-plane/src/providers/provider-defaults.ts +116 -7
  157. package/apps/control-plane/src/providers/providers.ts +225 -21
  158. package/apps/control-plane/src/providers/worker-provider-factory.ts +26 -2
  159. package/apps/control-plane/src/supervisor/artifact-stager.ts +52 -0
  160. package/apps/control-plane/src/supervisor/build-wave-executor.ts +477 -166
  161. package/apps/control-plane/src/supervisor/execution-enrollment-service.ts +408 -0
  162. package/apps/control-plane/src/supervisor/organizer-enrollment-scheduler.ts +117 -0
  163. package/apps/control-plane/src/supervisor/organizer-sidecar-service.ts +394 -0
  164. package/apps/control-plane/src/supervisor/plan-conformance-scorer.ts +2 -5
  165. package/apps/control-plane/src/supervisor/planner-phase.ts +85 -0
  166. package/apps/control-plane/src/supervisor/planning-wave-executor.ts +993 -64
  167. package/apps/control-plane/src/supervisor/prompt-bundle-loader.ts +20 -1
  168. package/apps/control-plane/src/supervisor/qa-wave-executor.ts +384 -177
  169. package/apps/control-plane/src/supervisor/run-coordinator.ts +723 -20
  170. package/apps/control-plane/src/supervisor/runtime.ts +485 -9
  171. package/apps/control-plane/src/supervisor/session-orchestrator.ts +220 -1
  172. package/apps/control-plane/src/supervisor/types.ts +152 -1
  173. package/apps/control-plane/src/supervisor/worker-decision-loop.ts +1030 -92
  174. package/apps/control-plane/test/activity-monitor.spec.ts +76 -0
  175. package/apps/control-plane/test/add-command-handler.spec.ts +189 -0
  176. package/apps/control-plane/test/application/services/feature-state-service.spec.ts +208 -0
  177. package/apps/control-plane/test/artifact-stager.spec.ts +93 -0
  178. package/apps/control-plane/test/batch-operations.spec.ts +58 -0
  179. package/apps/control-plane/test/bootstrap-edge-cases.spec.ts +50 -2
  180. package/apps/control-plane/test/bootstrap-manifest-generator-service.spec.ts +99 -0
  181. package/apps/control-plane/test/bootstrap.spec.ts +177 -4
  182. package/apps/control-plane/test/checkpoint-service.spec.ts +977 -29
  183. package/apps/control-plane/test/cli-argument-parser.spec.ts +119 -0
  184. package/apps/control-plane/test/cli-helpers.spec.ts +1202 -12
  185. package/apps/control-plane/test/cli.unit.spec.ts +797 -16
  186. package/apps/control-plane/test/collision-command-handler.spec.ts +182 -0
  187. package/apps/control-plane/test/collision-override-service.spec.ts +878 -0
  188. package/apps/control-plane/test/collision-queue.spec.ts +430 -2
  189. package/apps/control-plane/test/collisions.spec.ts +209 -1
  190. package/apps/control-plane/test/core-utils.spec.ts +61 -0
  191. package/apps/control-plane/test/cost-tracking.spec.ts +224 -0
  192. package/apps/control-plane/test/dashboard-api.integration.spec.ts +185 -5
  193. package/apps/control-plane/test/dashboard-client.spec.ts +948 -0
  194. package/apps/control-plane/test/dashboard-command.spec.ts +138 -6
  195. package/apps/control-plane/test/dashboard-runtime-runner.spec.ts +1550 -0
  196. package/apps/control-plane/test/dashboard-runtime.spec.ts +138 -0
  197. package/apps/control-plane/test/dashboard-ui-utils.spec.ts +56 -12
  198. package/apps/control-plane/test/dependency-scheduler.spec.ts +7 -1
  199. package/apps/control-plane/test/env-file.spec.ts +76 -0
  200. package/apps/control-plane/test/execution-control-service.spec.ts +535 -0
  201. package/apps/control-plane/test/execution-enrollment-service.spec.ts +648 -0
  202. package/apps/control-plane/test/feature-lifecycle.spec.ts +126 -0
  203. package/apps/control-plane/test/feature-resume-phase.spec.ts +164 -0
  204. package/apps/control-plane/test/feature-send-message-service.spec.ts +161 -0
  205. package/apps/control-plane/test/feature-state-service.spec.ts +295 -0
  206. package/apps/control-plane/test/fs.spec.ts +80 -0
  207. package/apps/control-plane/test/gate-freshness.spec.ts +590 -0
  208. package/apps/control-plane/test/gate-log-extractor.spec.ts +170 -0
  209. package/apps/control-plane/test/gates.spec.ts +108 -0
  210. package/apps/control-plane/test/git-reconciliation-service.spec.ts +2307 -0
  211. package/apps/control-plane/test/helpers.ts +65 -0
  212. package/apps/control-plane/test/incremental-gates.spec.ts +271 -0
  213. package/apps/control-plane/test/index-normalizer.spec.ts +98 -0
  214. package/apps/control-plane/test/init-wizard.spec.ts +17 -0
  215. package/apps/control-plane/test/intake-artifacts.spec.ts +203 -0
  216. package/apps/control-plane/test/intake-service.spec.ts +3176 -0
  217. package/apps/control-plane/test/kernel-collision-replay.spec.ts +3 -2
  218. package/apps/control-plane/test/kernel-tool-executor.spec.ts +77 -0
  219. package/apps/control-plane/test/kernel-tool-wiring.spec.ts +279 -0
  220. package/apps/control-plane/test/kernel.branches.spec.ts +15 -2
  221. package/apps/control-plane/test/kernel.coverage.spec.ts +7 -3
  222. package/apps/control-plane/test/kernel.coverage2.spec.ts +731 -2
  223. package/apps/control-plane/test/kernel.spec.ts +464 -2
  224. package/apps/control-plane/test/mainline-conflict.spec.ts +66 -0
  225. package/apps/control-plane/test/mcp-helpers.spec.ts +79 -0
  226. package/apps/control-plane/test/mcp.spec.ts +177 -13
  227. package/apps/control-plane/test/merge-command-handler.spec.ts +531 -0
  228. package/apps/control-plane/test/merge-service.spec.ts +570 -4
  229. package/apps/control-plane/test/notifier-service.spec.ts +26 -0
  230. package/apps/control-plane/test/organizer-enrollment-scheduler.spec.ts +340 -0
  231. package/apps/control-plane/test/organizer-ordering-artifact.spec.ts +95 -0
  232. package/apps/control-plane/test/organizer-sidecar-service.spec.ts +468 -0
  233. package/apps/control-plane/test/output-loop-detector.spec.ts +6 -0
  234. package/apps/control-plane/test/path-layout.spec.ts +70 -0
  235. package/apps/control-plane/test/performance-analytics.spec.ts +124 -0
  236. package/apps/control-plane/test/plan-conformance-scorer.spec.ts +53 -0
  237. package/apps/control-plane/test/plan-service.spec.ts +686 -4
  238. package/apps/control-plane/test/planning-wave-executor.spec.ts +3272 -86
  239. package/apps/control-plane/test/policy-loader-service.spec.ts +5 -0
  240. package/apps/control-plane/test/prompt-overlay.spec.ts +65 -0
  241. package/apps/control-plane/test/provider-command-runner-epipe.spec.ts +64 -0
  242. package/apps/control-plane/test/providers/api-worker-provider.spec.ts +129 -0
  243. package/apps/control-plane/test/providers/cli-worker-provider.spec.ts +148 -0
  244. package/apps/control-plane/test/providers/usage-types.spec.ts +98 -0
  245. package/apps/control-plane/test/providers.spec.ts +293 -16
  246. package/apps/control-plane/test/question-command-handlers.spec.ts +156 -0
  247. package/apps/control-plane/test/question-service.spec.ts +1119 -0
  248. package/apps/control-plane/test/reactions.spec.ts +114 -0
  249. package/apps/control-plane/test/replay-command-handler.spec.ts +144 -0
  250. package/apps/control-plane/test/replay-timeline-service.spec.ts +459 -0
  251. package/apps/control-plane/test/response.spec.ts +31 -0
  252. package/apps/control-plane/test/resume-command.spec.ts +757 -9
  253. package/apps/control-plane/test/retry-resume-decision.spec.ts +133 -0
  254. package/apps/control-plane/test/rollback-command-handler.spec.ts +334 -0
  255. package/apps/control-plane/test/rollback-command.spec.ts +120 -0
  256. package/apps/control-plane/test/run-coordinator.spec.ts +3062 -404
  257. package/apps/control-plane/test/schemas/state.schema.spec.ts +71 -0
  258. package/apps/control-plane/test/service-retry-paths.spec.ts +112 -0
  259. package/apps/control-plane/test/services.spec.ts +472 -2
  260. package/apps/control-plane/test/session-management.spec.ts +346 -1
  261. package/apps/control-plane/test/spec-ingestion.spec.ts +102 -28
  262. package/apps/control-plane/test/spec-preparation.spec.ts +182 -0
  263. package/apps/control-plane/test/supervisor-collaborators.spec.ts +191 -3
  264. package/apps/control-plane/test/supervisor.calltool.spec.ts +198 -0
  265. package/apps/control-plane/test/supervisor.spec.ts +95 -16
  266. package/apps/control-plane/test/supervisor.unit.spec.ts +385 -18
  267. package/apps/control-plane/test/tool-runtime.spec.ts +122 -0
  268. package/apps/control-plane/test/worker-decision-loop.spec.ts +3479 -476
  269. package/apps/control-plane/test/worker-execution-policy.spec.ts +1416 -6
  270. package/apps/control-plane/test/worker-provider-adapters.spec.ts +1894 -37
  271. package/apps/control-plane/test/worker-provider-factory.spec.ts +81 -0
  272. package/apps/control-plane/test/worktree-watchdog-service.spec.ts +125 -0
  273. package/apps/control-plane/vitest.config.ts +5 -0
  274. package/config/agentic/orchestrator/agents.yaml +22 -1
  275. package/config/agentic/orchestrator/gates.yaml +24 -7
  276. package/config/agentic/orchestrator/policy.yaml +23 -1
  277. package/config/agentic/orchestrator/prompts/builder.system.md +69 -20
  278. package/config/agentic/orchestrator/prompts/organizer.system.md +85 -0
  279. package/config/agentic/orchestrator/prompts/overrides/builder.claude.md +28 -0
  280. package/config/agentic/orchestrator/prompts/overrides/builder.codex.md +28 -0
  281. package/config/agentic/orchestrator/prompts/overrides/planner.claude.md +20 -0
  282. package/config/agentic/orchestrator/prompts/overrides/planner.codex.md +20 -0
  283. package/config/agentic/orchestrator/prompts/planner-intake.system.md +149 -0
  284. package/config/agentic/orchestrator/prompts/planner.system.md +113 -40
  285. package/config/agentic/orchestrator/prompts/qa.system.md +75 -18
  286. package/config/agentic/orchestrator/prompts/reconciler.system.md +119 -0
  287. package/dist/apps/control-plane/application/kernel-tool-wiring.d.ts +26 -2
  288. package/dist/apps/control-plane/application/kernel-tool-wiring.js +40 -2
  289. package/dist/apps/control-plane/application/kernel-tool-wiring.js.map +1 -1
  290. package/dist/apps/control-plane/application/services/activity-monitor-service.js +37 -1
  291. package/dist/apps/control-plane/application/services/activity-monitor-service.js.map +1 -1
  292. package/dist/apps/control-plane/application/services/bootstrap-manifest-generator-service.d.ts +4 -0
  293. package/dist/apps/control-plane/application/services/bootstrap-manifest-generator-service.js +188 -0
  294. package/dist/apps/control-plane/application/services/bootstrap-manifest-generator-service.js.map +1 -0
  295. package/dist/apps/control-plane/application/services/checkpoint-service.d.ts +5 -0
  296. package/dist/apps/control-plane/application/services/checkpoint-service.js +69 -24
  297. package/dist/apps/control-plane/application/services/checkpoint-service.js.map +1 -1
  298. package/dist/apps/control-plane/application/services/collision-override-service.d.ts +139 -0
  299. package/dist/apps/control-plane/application/services/collision-override-service.js +568 -0
  300. package/dist/apps/control-plane/application/services/collision-override-service.js.map +1 -0
  301. package/dist/apps/control-plane/application/services/collision-queue-service.d.ts +15 -0
  302. package/dist/apps/control-plane/application/services/collision-queue-service.js +92 -33
  303. package/dist/apps/control-plane/application/services/collision-queue-service.js.map +1 -1
  304. package/dist/apps/control-plane/application/services/cost-tracking-service.d.ts +11 -0
  305. package/dist/apps/control-plane/application/services/cost-tracking-service.js +75 -0
  306. package/dist/apps/control-plane/application/services/cost-tracking-service.js.map +1 -1
  307. package/dist/apps/control-plane/application/services/execution-control-service.d.ts +75 -0
  308. package/dist/apps/control-plane/application/services/execution-control-service.js +421 -0
  309. package/dist/apps/control-plane/application/services/execution-control-service.js.map +1 -0
  310. package/dist/apps/control-plane/application/services/feature-deletion-service.d.ts +1 -0
  311. package/dist/apps/control-plane/application/services/feature-deletion-service.js +23 -1
  312. package/dist/apps/control-plane/application/services/feature-deletion-service.js.map +1 -1
  313. package/dist/apps/control-plane/application/services/feature-lifecycle-service.d.ts +24 -1
  314. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js +132 -3
  315. package/dist/apps/control-plane/application/services/feature-lifecycle-service.js.map +1 -1
  316. package/dist/apps/control-plane/application/services/feature-send-message-service.js +16 -8
  317. package/dist/apps/control-plane/application/services/feature-send-message-service.js.map +1 -1
  318. package/dist/apps/control-plane/application/services/feature-state-service.d.ts +36 -0
  319. package/dist/apps/control-plane/application/services/feature-state-service.js +163 -6
  320. package/dist/apps/control-plane/application/services/feature-state-service.js.map +1 -1
  321. package/dist/apps/control-plane/application/services/gate-service.d.ts +2 -1
  322. package/dist/apps/control-plane/application/services/gate-service.js +95 -5
  323. package/dist/apps/control-plane/application/services/gate-service.js.map +1 -1
  324. package/dist/apps/control-plane/application/services/git-reconciliation-service.d.ts +92 -0
  325. package/dist/apps/control-plane/application/services/git-reconciliation-service.js +1097 -0
  326. package/dist/apps/control-plane/application/services/git-reconciliation-service.js.map +1 -0
  327. package/dist/apps/control-plane/application/services/intake-service.d.ts +63 -0
  328. package/dist/apps/control-plane/application/services/intake-service.js +1050 -0
  329. package/dist/apps/control-plane/application/services/intake-service.js.map +1 -0
  330. package/dist/apps/control-plane/application/services/merge-service.d.ts +5 -1
  331. package/dist/apps/control-plane/application/services/merge-service.js +233 -18
  332. package/dist/apps/control-plane/application/services/merge-service.js.map +1 -1
  333. package/dist/apps/control-plane/application/services/notifier-service.d.ts +1 -1
  334. package/dist/apps/control-plane/application/services/notifier-service.js +1 -0
  335. package/dist/apps/control-plane/application/services/notifier-service.js.map +1 -1
  336. package/dist/apps/control-plane/application/services/performance-analytics-service.d.ts +11 -0
  337. package/dist/apps/control-plane/application/services/performance-analytics-service.js +59 -0
  338. package/dist/apps/control-plane/application/services/performance-analytics-service.js.map +1 -1
  339. package/dist/apps/control-plane/application/services/plan-service.d.ts +5 -0
  340. package/dist/apps/control-plane/application/services/plan-service.js +254 -15
  341. package/dist/apps/control-plane/application/services/plan-service.js.map +1 -1
  342. package/dist/apps/control-plane/application/services/question-service.d.ts +72 -0
  343. package/dist/apps/control-plane/application/services/question-service.js +507 -0
  344. package/dist/apps/control-plane/application/services/question-service.js.map +1 -0
  345. package/dist/apps/control-plane/application/services/reactions-service.d.ts +2 -0
  346. package/dist/apps/control-plane/application/services/reactions-service.js +60 -17
  347. package/dist/apps/control-plane/application/services/reactions-service.js.map +1 -1
  348. package/dist/apps/control-plane/application/services/replay-timeline-service.d.ts +39 -0
  349. package/dist/apps/control-plane/application/services/replay-timeline-service.js +205 -0
  350. package/dist/apps/control-plane/application/services/replay-timeline-service.js.map +1 -0
  351. package/dist/apps/control-plane/application/services/reporting-service.d.ts +59 -0
  352. package/dist/apps/control-plane/application/services/reporting-service.js +121 -9
  353. package/dist/apps/control-plane/application/services/reporting-service.js.map +1 -1
  354. package/dist/apps/control-plane/application/services/run-lease-service.d.ts +20 -0
  355. package/dist/apps/control-plane/application/services/run-lease-service.js +81 -4
  356. package/dist/apps/control-plane/application/services/run-lease-service.js.map +1 -1
  357. package/dist/apps/control-plane/application/services/worktree-watchdog-service.d.ts +10 -0
  358. package/dist/apps/control-plane/application/services/worktree-watchdog-service.js +65 -8
  359. package/dist/apps/control-plane/application/services/worktree-watchdog-service.js.map +1 -1
  360. package/dist/apps/control-plane/application/tools/tool-metadata.js +7 -0
  361. package/dist/apps/control-plane/application/tools/tool-metadata.js.map +1 -1
  362. package/dist/apps/control-plane/application/usage-types.d.ts +65 -0
  363. package/dist/apps/control-plane/application/usage-types.js +75 -0
  364. package/dist/apps/control-plane/application/usage-types.js.map +1 -0
  365. package/dist/apps/control-plane/cli/add-command-handler.d.ts +18 -0
  366. package/dist/apps/control-plane/cli/add-command-handler.js +110 -0
  367. package/dist/apps/control-plane/cli/add-command-handler.js.map +1 -0
  368. package/dist/apps/control-plane/cli/answer-command-handler.d.ts +8 -0
  369. package/dist/apps/control-plane/cli/answer-command-handler.js +96 -0
  370. package/dist/apps/control-plane/cli/answer-command-handler.js.map +1 -0
  371. package/dist/apps/control-plane/cli/attach-command-handler.js +8 -3
  372. package/dist/apps/control-plane/cli/attach-command-handler.js.map +1 -1
  373. package/dist/apps/control-plane/cli/cli-argument-parser.js +131 -11
  374. package/dist/apps/control-plane/cli/cli-argument-parser.js.map +1 -1
  375. package/dist/apps/control-plane/cli/collision-command-handler.d.ts +8 -0
  376. package/dist/apps/control-plane/cli/collision-command-handler.js +90 -0
  377. package/dist/apps/control-plane/cli/collision-command-handler.js.map +1 -0
  378. package/dist/apps/control-plane/cli/command-catalog.d.ts +21 -0
  379. package/dist/apps/control-plane/cli/command-catalog.js +416 -0
  380. package/dist/apps/control-plane/cli/command-catalog.js.map +1 -0
  381. package/dist/apps/control-plane/cli/complete-command-handler.d.ts +15 -0
  382. package/dist/apps/control-plane/cli/complete-command-handler.js +26 -0
  383. package/dist/apps/control-plane/cli/complete-command-handler.js.map +1 -0
  384. package/dist/apps/control-plane/cli/completion-command-handler.d.ts +8 -0
  385. package/dist/apps/control-plane/cli/completion-command-handler.js +20 -0
  386. package/dist/apps/control-plane/cli/completion-command-handler.js.map +1 -0
  387. package/dist/apps/control-plane/cli/completion-resolver.d.ts +1 -0
  388. package/dist/apps/control-plane/cli/completion-resolver.js +250 -0
  389. package/dist/apps/control-plane/cli/completion-resolver.js.map +1 -0
  390. package/dist/apps/control-plane/cli/completion-shell-renderer.d.ts +3 -0
  391. package/dist/apps/control-plane/cli/completion-shell-renderer.js +53 -0
  392. package/dist/apps/control-plane/cli/completion-shell-renderer.js.map +1 -0
  393. package/dist/apps/control-plane/cli/dashboard-command-handler.d.ts +1 -0
  394. package/dist/apps/control-plane/cli/dashboard-command-handler.js +83 -1
  395. package/dist/apps/control-plane/cli/dashboard-command-handler.js.map +1 -1
  396. package/dist/apps/control-plane/cli/dashboard-runtime-runner.d.ts +81 -0
  397. package/dist/apps/control-plane/cli/dashboard-runtime-runner.js +724 -0
  398. package/dist/apps/control-plane/cli/dashboard-runtime-runner.js.map +1 -0
  399. package/dist/apps/control-plane/cli/dashboard-runtime.d.ts +1 -0
  400. package/dist/apps/control-plane/cli/dashboard-runtime.js +26 -0
  401. package/dist/apps/control-plane/cli/dashboard-runtime.js.map +1 -0
  402. package/dist/apps/control-plane/cli/help-command-handler.js +13 -172
  403. package/dist/apps/control-plane/cli/help-command-handler.js.map +1 -1
  404. package/dist/apps/control-plane/cli/init-command-handler.js +51 -6
  405. package/dist/apps/control-plane/cli/init-command-handler.js.map +1 -1
  406. package/dist/apps/control-plane/cli/merge-command-handler.d.ts +8 -0
  407. package/dist/apps/control-plane/cli/merge-command-handler.js +139 -0
  408. package/dist/apps/control-plane/cli/merge-command-handler.js.map +1 -0
  409. package/dist/apps/control-plane/cli/questions-command-handler.d.ts +8 -0
  410. package/dist/apps/control-plane/cli/questions-command-handler.js +59 -0
  411. package/dist/apps/control-plane/cli/questions-command-handler.js.map +1 -0
  412. package/dist/apps/control-plane/cli/replay-command-handler.d.ts +15 -0
  413. package/dist/apps/control-plane/cli/replay-command-handler.js +55 -0
  414. package/dist/apps/control-plane/cli/replay-command-handler.js.map +1 -0
  415. package/dist/apps/control-plane/cli/resume-command-handler.d.ts +2 -0
  416. package/dist/apps/control-plane/cli/resume-command-handler.js +180 -17
  417. package/dist/apps/control-plane/cli/resume-command-handler.js.map +1 -1
  418. package/dist/apps/control-plane/cli/retry-command-handler.js +202 -16
  419. package/dist/apps/control-plane/cli/retry-command-handler.js.map +1 -1
  420. package/dist/apps/control-plane/cli/retry-resume-decision.d.ts +26 -0
  421. package/dist/apps/control-plane/cli/retry-resume-decision.js +61 -0
  422. package/dist/apps/control-plane/cli/retry-resume-decision.js.map +1 -0
  423. package/dist/apps/control-plane/cli/rollback-command-handler.js +3 -2
  424. package/dist/apps/control-plane/cli/rollback-command-handler.js.map +1 -1
  425. package/dist/apps/control-plane/cli/run-command-handler.js +26 -2
  426. package/dist/apps/control-plane/cli/run-command-handler.js.map +1 -1
  427. package/dist/apps/control-plane/cli/spec-ingestion-service.d.ts +2 -0
  428. package/dist/apps/control-plane/cli/spec-ingestion-service.js +37 -48
  429. package/dist/apps/control-plane/cli/spec-ingestion-service.js.map +1 -1
  430. package/dist/apps/control-plane/cli/spec-preparation.d.ts +14 -0
  431. package/dist/apps/control-plane/cli/spec-preparation.js +81 -0
  432. package/dist/apps/control-plane/cli/spec-preparation.js.map +1 -0
  433. package/dist/apps/control-plane/cli/spec-utils.d.ts +4 -0
  434. package/dist/apps/control-plane/cli/spec-utils.js +70 -11
  435. package/dist/apps/control-plane/cli/spec-utils.js.map +1 -1
  436. package/dist/apps/control-plane/cli/status-command-handler.js +69 -0
  437. package/dist/apps/control-plane/cli/status-command-handler.js.map +1 -1
  438. package/dist/apps/control-plane/cli/types.d.ts +41 -4
  439. package/dist/apps/control-plane/cli/types.js +9 -1
  440. package/dist/apps/control-plane/cli/types.js.map +1 -1
  441. package/dist/apps/control-plane/core/collisions.d.ts +37 -19
  442. package/dist/apps/control-plane/core/collisions.js +87 -12
  443. package/dist/apps/control-plane/core/collisions.js.map +1 -1
  444. package/dist/apps/control-plane/core/constants.d.ts +17 -1
  445. package/dist/apps/control-plane/core/constants.js +18 -1
  446. package/dist/apps/control-plane/core/constants.js.map +1 -1
  447. package/dist/apps/control-plane/core/error-codes.d.ts +39 -0
  448. package/dist/apps/control-plane/core/error-codes.js +39 -0
  449. package/dist/apps/control-plane/core/error-codes.js.map +1 -1
  450. package/dist/apps/control-plane/core/execution-control.d.ts +45 -0
  451. package/dist/apps/control-plane/core/execution-control.js +2 -0
  452. package/dist/apps/control-plane/core/execution-control.js.map +1 -0
  453. package/dist/apps/control-plane/core/feature-resume-phase.d.ts +3 -0
  454. package/dist/apps/control-plane/core/feature-resume-phase.js +88 -0
  455. package/dist/apps/control-plane/core/feature-resume-phase.js.map +1 -0
  456. package/dist/apps/control-plane/core/gate-freshness.d.ts +48 -0
  457. package/dist/apps/control-plane/core/gate-freshness.js +267 -0
  458. package/dist/apps/control-plane/core/gate-freshness.js.map +1 -0
  459. package/dist/apps/control-plane/core/gate-log-extractor.d.ts +22 -0
  460. package/dist/apps/control-plane/core/gate-log-extractor.js +66 -0
  461. package/dist/apps/control-plane/core/gate-log-extractor.js.map +1 -0
  462. package/dist/apps/control-plane/core/gates.d.ts +11 -2
  463. package/dist/apps/control-plane/core/gates.js +67 -3
  464. package/dist/apps/control-plane/core/gates.js.map +1 -1
  465. package/dist/apps/control-plane/core/intake-artifacts.d.ts +109 -0
  466. package/dist/apps/control-plane/core/intake-artifacts.js +143 -0
  467. package/dist/apps/control-plane/core/intake-artifacts.js.map +1 -0
  468. package/dist/apps/control-plane/core/kernel-types.d.ts +8 -0
  469. package/dist/apps/control-plane/core/kernel.d.ts +256 -8
  470. package/dist/apps/control-plane/core/kernel.js +400 -14
  471. package/dist/apps/control-plane/core/kernel.js.map +1 -1
  472. package/dist/apps/control-plane/core/mainline-conflict.d.ts +7 -0
  473. package/dist/apps/control-plane/core/mainline-conflict.js +20 -0
  474. package/dist/apps/control-plane/core/mainline-conflict.js.map +1 -0
  475. package/dist/apps/control-plane/core/merge-repair.d.ts +35 -0
  476. package/dist/apps/control-plane/core/merge-repair.js +99 -0
  477. package/dist/apps/control-plane/core/merge-repair.js.map +1 -0
  478. package/dist/apps/control-plane/core/path-layout.d.ts +10 -0
  479. package/dist/apps/control-plane/core/path-layout.js +32 -2
  480. package/dist/apps/control-plane/core/path-layout.js.map +1 -1
  481. package/dist/apps/control-plane/core/path-rules.js +9 -3
  482. package/dist/apps/control-plane/core/path-rules.js.map +1 -1
  483. package/dist/apps/control-plane/core/plan-submit-recovery.d.ts +22 -0
  484. package/dist/apps/control-plane/core/plan-submit-recovery.js +78 -0
  485. package/dist/apps/control-plane/core/plan-submit-recovery.js.map +1 -0
  486. package/dist/apps/control-plane/core/questions.d.ts +40 -0
  487. package/dist/apps/control-plane/core/questions.js +2 -0
  488. package/dist/apps/control-plane/core/questions.js.map +1 -0
  489. package/dist/apps/control-plane/core/runtime-sessions.d.ts +4 -0
  490. package/dist/apps/control-plane/core/schemas.d.ts +2 -0
  491. package/dist/apps/control-plane/core/schemas.js +31 -1
  492. package/dist/apps/control-plane/core/schemas.js.map +1 -1
  493. package/dist/apps/control-plane/core/tool-caller.d.ts +18 -1
  494. package/dist/apps/control-plane/core/utils/index-normalizer.js +17 -4
  495. package/dist/apps/control-plane/core/utils/index-normalizer.js.map +1 -1
  496. package/dist/apps/control-plane/core/worktree-diff.d.ts +4 -0
  497. package/dist/apps/control-plane/core/worktree-diff.js +52 -0
  498. package/dist/apps/control-plane/core/worktree-diff.js.map +1 -0
  499. package/dist/apps/control-plane/index.d.ts +10 -2
  500. package/dist/apps/control-plane/index.js +9 -2
  501. package/dist/apps/control-plane/index.js.map +1 -1
  502. package/dist/apps/control-plane/interfaces/cli/bootstrap.js +236 -6
  503. package/dist/apps/control-plane/interfaces/cli/bootstrap.js.map +1 -1
  504. package/dist/apps/control-plane/mcp/kernel-tool-executor.js +16 -0
  505. package/dist/apps/control-plane/mcp/kernel-tool-executor.js.map +1 -1
  506. package/dist/apps/control-plane/mcp/tool-runtime.d.ts +5 -0
  507. package/dist/apps/control-plane/mcp/tool-runtime.js +40 -5
  508. package/dist/apps/control-plane/mcp/tool-runtime.js.map +1 -1
  509. package/dist/apps/control-plane/providers/api-worker-provider.d.ts +2 -2
  510. package/dist/apps/control-plane/providers/api-worker-provider.js +40 -9
  511. package/dist/apps/control-plane/providers/api-worker-provider.js.map +1 -1
  512. package/dist/apps/control-plane/providers/cli-worker-provider.d.ts +59 -3
  513. package/dist/apps/control-plane/providers/cli-worker-provider.js +758 -46
  514. package/dist/apps/control-plane/providers/cli-worker-provider.js.map +1 -1
  515. package/dist/apps/control-plane/providers/output-parsers/generic-output-parser.js +91 -1
  516. package/dist/apps/control-plane/providers/output-parsers/generic-output-parser.js.map +1 -1
  517. package/dist/apps/control-plane/providers/output-parsers/types.d.ts +2 -0
  518. package/dist/apps/control-plane/providers/provider-defaults.d.ts +12 -0
  519. package/dist/apps/control-plane/providers/provider-defaults.js +103 -7
  520. package/dist/apps/control-plane/providers/provider-defaults.js.map +1 -1
  521. package/dist/apps/control-plane/providers/providers.d.ts +50 -4
  522. package/dist/apps/control-plane/providers/providers.js +145 -14
  523. package/dist/apps/control-plane/providers/providers.js.map +1 -1
  524. package/dist/apps/control-plane/providers/worker-provider-factory.d.ts +2 -0
  525. package/dist/apps/control-plane/providers/worker-provider-factory.js +8 -1
  526. package/dist/apps/control-plane/providers/worker-provider-factory.js.map +1 -1
  527. package/dist/apps/control-plane/supervisor/artifact-stager.d.ts +5 -0
  528. package/dist/apps/control-plane/supervisor/artifact-stager.js +45 -0
  529. package/dist/apps/control-plane/supervisor/artifact-stager.js.map +1 -0
  530. package/dist/apps/control-plane/supervisor/build-wave-executor.d.ts +24 -1
  531. package/dist/apps/control-plane/supervisor/build-wave-executor.js +362 -150
  532. package/dist/apps/control-plane/supervisor/build-wave-executor.js.map +1 -1
  533. package/dist/apps/control-plane/supervisor/execution-enrollment-service.d.ts +41 -0
  534. package/dist/apps/control-plane/supervisor/execution-enrollment-service.js +311 -0
  535. package/dist/apps/control-plane/supervisor/execution-enrollment-service.js.map +1 -0
  536. package/dist/apps/control-plane/supervisor/organizer-enrollment-scheduler.d.ts +15 -0
  537. package/dist/apps/control-plane/supervisor/organizer-enrollment-scheduler.js +93 -0
  538. package/dist/apps/control-plane/supervisor/organizer-enrollment-scheduler.js.map +1 -0
  539. package/dist/apps/control-plane/supervisor/organizer-sidecar-service.d.ts +44 -0
  540. package/dist/apps/control-plane/supervisor/organizer-sidecar-service.js +311 -0
  541. package/dist/apps/control-plane/supervisor/organizer-sidecar-service.js.map +1 -0
  542. package/dist/apps/control-plane/supervisor/plan-conformance-scorer.js +2 -5
  543. package/dist/apps/control-plane/supervisor/plan-conformance-scorer.js.map +1 -1
  544. package/dist/apps/control-plane/supervisor/planner-phase.d.ts +3 -0
  545. package/dist/apps/control-plane/supervisor/planner-phase.js +70 -0
  546. package/dist/apps/control-plane/supervisor/planner-phase.js.map +1 -0
  547. package/dist/apps/control-plane/supervisor/planning-wave-executor.d.ts +42 -0
  548. package/dist/apps/control-plane/supervisor/planning-wave-executor.js +753 -55
  549. package/dist/apps/control-plane/supervisor/planning-wave-executor.js.map +1 -1
  550. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js +19 -1
  551. package/dist/apps/control-plane/supervisor/prompt-bundle-loader.js.map +1 -1
  552. package/dist/apps/control-plane/supervisor/qa-wave-executor.d.ts +21 -0
  553. package/dist/apps/control-plane/supervisor/qa-wave-executor.js +287 -156
  554. package/dist/apps/control-plane/supervisor/qa-wave-executor.js.map +1 -1
  555. package/dist/apps/control-plane/supervisor/run-coordinator.d.ts +30 -1
  556. package/dist/apps/control-plane/supervisor/run-coordinator.js +561 -17
  557. package/dist/apps/control-plane/supervisor/run-coordinator.js.map +1 -1
  558. package/dist/apps/control-plane/supervisor/runtime.d.ts +84 -0
  559. package/dist/apps/control-plane/supervisor/runtime.js +393 -3
  560. package/dist/apps/control-plane/supervisor/runtime.js.map +1 -1
  561. package/dist/apps/control-plane/supervisor/session-orchestrator.d.ts +54 -0
  562. package/dist/apps/control-plane/supervisor/session-orchestrator.js +176 -1
  563. package/dist/apps/control-plane/supervisor/session-orchestrator.js.map +1 -1
  564. package/dist/apps/control-plane/supervisor/types.d.ts +142 -1
  565. package/dist/apps/control-plane/supervisor/types.js.map +1 -1
  566. package/dist/apps/control-plane/supervisor/worker-decision-loop.d.ts +68 -2
  567. package/dist/apps/control-plane/supervisor/worker-decision-loop.js +723 -89
  568. package/dist/apps/control-plane/supervisor/worker-decision-loop.js.map +1 -1
  569. package/docs/core/ARCHITECTURE.md +227 -0
  570. package/docs/core/DECISIONS.md +94 -0
  571. package/docs/core/DOMAIN-LOGIC.md +60 -0
  572. package/docs/core/PATTERNS.md +201 -0
  573. package/docs/core/TROUBLESHOOTING.md +347 -0
  574. package/docs/core/intentgraph-dependencies.json +39860 -0
  575. package/docs/core/intentgraph.index.json +46580 -0
  576. package/docs/plans/2026-03-10-gate-failure-targeted-repair-design.md +224 -0
  577. package/docs/plans/2026-03-10-gate-failure-targeted-repair.md +1032 -0
  578. package/docs/superpowers/plans/2026-03-16-provider-cli-config.md +743 -0
  579. package/docs/superpowers/plans/2026-03-23-reconcile-divergence-fix.md +777 -0
  580. package/docs/superpowers/plans/2026-03-28-ordering-agent-implementation.md +1754 -0
  581. package/docs/superpowers/plans/2026-03-29-drop-zone-and-provider-optimization.md +1108 -0
  582. package/docs/superpowers/plans/2026-03-29-merge-target-feature-branch.md +685 -0
  583. package/docs/superpowers/plans/2026-03-29-organizer-sidecar-runtime-loop.md +1289 -0
  584. package/docs/superpowers/specs/2026-03-23-reconcile-divergence-fix-design.md +118 -0
  585. package/docs/superpowers/specs/2026-03-28-ordering-agent-spec-audit-design.md +50 -0
  586. package/docs/superpowers/specs/2026-03-29-drop-zone-and-provider-optimization-design.md +254 -0
  587. package/docs/superpowers/specs/2026-03-29-merge-target-feature-branch-design.md +152 -0
  588. package/docs/superpowers/specs/2026-03-29-organizer-sidecar-runtime-loop-design.md +225 -0
  589. package/package.json +3 -2
  590. package/packages/web-dashboard/package.json +2 -1
  591. package/packages/web-dashboard/src/app/analytics/page.tsx +36 -2
  592. package/packages/web-dashboard/src/app/api/actions/route.ts +274 -63
  593. package/packages/web-dashboard/src/app/api/actions/status/route.ts +35 -0
  594. package/packages/web-dashboard/src/app/api/analytics/provider/route.ts +18 -0
  595. package/packages/web-dashboard/src/app/api/collisions/approve/route.ts +58 -0
  596. package/packages/web-dashboard/src/app/api/features/[id]/checkpoint-diff/route.ts +36 -0
  597. package/packages/web-dashboard/src/app/api/features/[id]/checkpoints/route.ts +29 -0
  598. package/packages/web-dashboard/src/app/api/features/[id]/conflicts/abort/route.ts +29 -0
  599. package/packages/web-dashboard/src/app/api/features/[id]/conflicts/files/route.ts +30 -0
  600. package/packages/web-dashboard/src/app/api/features/[id]/conflicts/resolve/route.ts +51 -0
  601. package/packages/web-dashboard/src/app/api/features/[id]/conflicts/route.ts +75 -0
  602. package/packages/web-dashboard/src/app/api/features/[id]/diff/route.ts +16 -2
  603. package/packages/web-dashboard/src/app/api/features/[id]/files/route.ts +26 -0
  604. package/packages/web-dashboard/src/app/api/features/[id]/gate-history/route.ts +27 -0
  605. package/packages/web-dashboard/src/app/api/features/[id]/genealogy/route.ts +26 -0
  606. package/packages/web-dashboard/src/app/api/features/[id]/history/run/[runId]/route.ts +20 -0
  607. package/packages/web-dashboard/src/app/api/features/[id]/history/runs/route.ts +34 -0
  608. package/packages/web-dashboard/src/app/api/features/[id]/intake-workspace/route.ts +20 -0
  609. package/packages/web-dashboard/src/app/api/features/[id]/live-output/route.ts +74 -0
  610. package/packages/web-dashboard/src/app/api/features/[id]/plan/amend/route.ts +21 -0
  611. package/packages/web-dashboard/src/app/api/features/[id]/plan-progress/route.ts +20 -0
  612. package/packages/web-dashboard/src/app/api/features/[id]/planner-artifacts/[artifact]/route.ts +78 -0
  613. package/packages/web-dashboard/src/app/api/features/[id]/planner-lifecycle/route.ts +20 -0
  614. package/packages/web-dashboard/src/app/api/features/[id]/planning-workspace/route.ts +20 -0
  615. package/packages/web-dashboard/src/app/api/features/[id]/questions/[questionId]/answer/route.ts +27 -0
  616. package/packages/web-dashboard/src/app/api/features/[id]/questions/route.ts +18 -0
  617. package/packages/web-dashboard/src/app/api/features/[id]/review/route.ts +14 -7
  618. package/packages/web-dashboard/src/app/api/features/[id]/route.ts +57 -2
  619. package/packages/web-dashboard/src/app/api/features/[id]/spec/route.ts +30 -0
  620. package/packages/web-dashboard/src/app/api/features/[id]/triage/route.ts +83 -0
  621. package/packages/web-dashboard/src/app/api/features/[id]/worker-events/route.ts +40 -0
  622. package/packages/web-dashboard/src/app/api/launch/preview/route.ts +86 -0
  623. package/packages/web-dashboard/src/app/api/launch/submit/route.ts +180 -0
  624. package/packages/web-dashboard/src/app/api/mainline/status/route.ts +74 -0
  625. package/packages/web-dashboard/src/app/api/merge-queue/route.ts +13 -0
  626. package/packages/web-dashboard/src/app/api/policy/budget/route.ts +14 -0
  627. package/packages/web-dashboard/src/app/api/projects/route.ts +11 -7
  628. package/packages/web-dashboard/src/app/api/reconciler/queue/route.ts +47 -0
  629. package/packages/web-dashboard/src/app/api/run/route.ts +26 -2
  630. package/packages/web-dashboard/src/app/api/runtime/events/route.ts +227 -0
  631. package/packages/web-dashboard/src/app/api/runtime/operations/route.ts +269 -0
  632. package/packages/web-dashboard/src/app/api/runtime/questions/route.ts +11 -0
  633. package/packages/web-dashboard/src/app/api/runtime/runs/route.ts +80 -0
  634. package/packages/web-dashboard/src/app/api/status/route.ts +4 -2
  635. package/packages/web-dashboard/src/app/feature/[id]/page.tsx +32 -42
  636. package/packages/web-dashboard/src/app/globals.css +34 -3
  637. package/packages/web-dashboard/src/app/launch/page.tsx +357 -0
  638. package/packages/web-dashboard/src/app/layout.tsx +23 -1
  639. package/packages/web-dashboard/src/app/page.tsx +263 -272
  640. package/packages/web-dashboard/src/components/dashboard/attention-strip.tsx +52 -0
  641. package/packages/web-dashboard/src/components/dashboard/collision-approval-drawer.tsx +185 -0
  642. package/packages/web-dashboard/src/components/dashboard/command-center-header.tsx +102 -0
  643. package/packages/web-dashboard/src/components/dashboard/mainline-status-banner.tsx +84 -0
  644. package/packages/web-dashboard/src/components/dashboard/merged-archive.tsx +36 -0
  645. package/packages/web-dashboard/src/components/dashboard/prioritized-queues.tsx +98 -0
  646. package/packages/web-dashboard/src/components/dashboard/reconciler-queue-card.tsx +115 -0
  647. package/packages/web-dashboard/src/components/dashboard/secondary-diagnostics-rail.tsx +48 -0
  648. package/packages/web-dashboard/src/components/dashboard/task-filter-bar.tsx +74 -0
  649. package/packages/web-dashboard/src/components/dashboard/triage-drawer.tsx +455 -0
  650. package/packages/web-dashboard/src/components/diff-viewer.tsx +19 -3
  651. package/packages/web-dashboard/src/components/evidence-viewer.tsx +65 -51
  652. package/packages/web-dashboard/src/components/feature-card.tsx +90 -7
  653. package/packages/web-dashboard/src/components/feature-cost-panel.tsx +112 -11
  654. package/packages/web-dashboard/src/components/feature-list-view.tsx +25 -4
  655. package/packages/web-dashboard/src/components/features/runtime-inspector/EventsTimelineView.tsx +260 -0
  656. package/packages/web-dashboard/src/components/features/runtime-inspector/OperationsListView.tsx +172 -0
  657. package/packages/web-dashboard/src/components/features/runtime-inspector/RuntimeInspectorPanel.tsx +896 -0
  658. package/packages/web-dashboard/src/components/filter-bar.tsx +7 -39
  659. package/packages/web-dashboard/src/components/focus/ActionableRiskList.tsx +46 -0
  660. package/packages/web-dashboard/src/components/focus/AgentRolePerformanceCard.tsx +200 -0
  661. package/packages/web-dashboard/src/components/focus/BlockedGuidanceBanner.tsx +149 -0
  662. package/packages/web-dashboard/src/components/focus/CheckpointInspector.tsx +123 -0
  663. package/packages/web-dashboard/src/components/focus/CheckpointRail.tsx +118 -0
  664. package/packages/web-dashboard/src/components/focus/CheckpointScrubber.tsx +249 -0
  665. package/packages/web-dashboard/src/components/focus/CollisionApprovalBanner.tsx +192 -0
  666. package/packages/web-dashboard/src/components/focus/CollisionRadar.tsx +136 -0
  667. package/packages/web-dashboard/src/components/focus/ConflictStatusCard.tsx +52 -0
  668. package/packages/web-dashboard/src/components/focus/ContextSidebar.tsx +108 -0
  669. package/packages/web-dashboard/src/components/focus/DiagnosisPanel.tsx +68 -0
  670. package/packages/web-dashboard/src/components/focus/FeatureDecisionBanner.tsx +68 -0
  671. package/packages/web-dashboard/src/components/focus/FeatureQuestionAnswerPanel.tsx +167 -0
  672. package/packages/web-dashboard/src/components/focus/FocusHeader.tsx +54 -0
  673. package/packages/web-dashboard/src/components/focus/FocusLayout.tsx +283 -0
  674. package/packages/web-dashboard/src/components/focus/GateFlakinessSummary.tsx +144 -0
  675. package/packages/web-dashboard/src/components/focus/GenealogyTree.tsx +34 -0
  676. package/packages/web-dashboard/src/components/focus/HeroBlock.tsx +67 -0
  677. package/packages/web-dashboard/src/components/focus/LiveAgentConsole.tsx +277 -0
  678. package/packages/web-dashboard/src/components/focus/MergeQueueCard.tsx +78 -0
  679. package/packages/web-dashboard/src/components/focus/OperationalSummaryCard.tsx +227 -0
  680. package/packages/web-dashboard/src/components/focus/PinnedActions.tsx +96 -0
  681. package/packages/web-dashboard/src/components/focus/PlanAmendmentPanel.tsx +250 -0
  682. package/packages/web-dashboard/src/components/focus/PlanProgressPanel.tsx +133 -0
  683. package/packages/web-dashboard/src/components/focus/PlannerArtifactViewer.tsx +158 -0
  684. package/packages/web-dashboard/src/components/focus/PlannerLifecycleHeader.tsx +141 -0
  685. package/packages/web-dashboard/src/components/focus/ProgressSnapshotCard.tsx +113 -0
  686. package/packages/web-dashboard/src/components/focus/RecentMaterialChanges.tsx +69 -0
  687. package/packages/web-dashboard/src/components/focus/RoleLogViewer.tsx +436 -0
  688. package/packages/web-dashboard/src/components/focus/RunHistoryBrowser.tsx +62 -0
  689. package/packages/web-dashboard/src/components/focus/SpecViewer.tsx +172 -0
  690. package/packages/web-dashboard/src/components/focus/TabBar.tsx +33 -0
  691. package/packages/web-dashboard/src/components/focus/UsageBurnChart.tsx +212 -0
  692. package/packages/web-dashboard/src/components/focus/VerificationSummaryCard.tsx +122 -0
  693. package/packages/web-dashboard/src/components/focus/tabs/ChangesTab.tsx +325 -0
  694. package/packages/web-dashboard/src/components/focus/tabs/ConflictsTab.tsx +395 -0
  695. package/packages/web-dashboard/src/components/focus/tabs/GatesQaTab.tsx +38 -0
  696. package/packages/web-dashboard/src/components/focus/tabs/HistoryTab.tsx +213 -0
  697. package/packages/web-dashboard/src/components/focus/tabs/IntakeTab.tsx +429 -0
  698. package/packages/web-dashboard/src/components/focus/tabs/OverviewTab.tsx +217 -0
  699. package/packages/web-dashboard/src/components/focus/tabs/PlanningTab.tsx +390 -0
  700. package/packages/web-dashboard/src/components/focus/tabs/ReviewTab.tsx +497 -0
  701. package/packages/web-dashboard/src/components/focus/tabs/RuntimeTab.tsx +213 -0
  702. package/packages/web-dashboard/src/components/focus/tabs/TranscriptTab.tsx +315 -0
  703. package/packages/web-dashboard/src/components/gate-results.tsx +2 -2
  704. package/packages/web-dashboard/src/components/human-input-panel.tsx +33 -57
  705. package/packages/web-dashboard/src/components/kanban-board.tsx +4 -0
  706. package/packages/web-dashboard/src/components/launch/launch-draft-card.tsx +131 -0
  707. package/packages/web-dashboard/src/components/plan-viewer.tsx +147 -69
  708. package/packages/web-dashboard/src/components/quick-launch-panel.tsx +20 -47
  709. package/packages/web-dashboard/src/components/summary-bar.tsx +30 -76
  710. package/packages/web-dashboard/src/lib/aop-client.ts +2484 -36
  711. package/packages/web-dashboard/src/lib/blocked-state-guidance.ts +475 -0
  712. package/packages/web-dashboard/src/lib/collision-radar.ts +136 -0
  713. package/packages/web-dashboard/src/lib/dashboard-action-states.ts +204 -0
  714. package/packages/web-dashboard/src/lib/dashboard-runtime-client.ts +439 -0
  715. package/packages/web-dashboard/src/lib/dashboard-utils.ts +179 -18
  716. package/packages/web-dashboard/src/lib/drop-zone-utils.ts +92 -0
  717. package/packages/web-dashboard/src/lib/focus-detail-derivations.ts +958 -0
  718. package/packages/web-dashboard/src/lib/focus-view.ts +300 -0
  719. package/packages/web-dashboard/src/lib/health-diagnosis.ts +356 -0
  720. package/packages/web-dashboard/src/lib/launch-contracts.ts +77 -0
  721. package/packages/web-dashboard/src/lib/launch-markdown.ts +107 -0
  722. package/packages/web-dashboard/src/lib/launch-page-preview.ts +89 -0
  723. package/packages/web-dashboard/src/lib/live-feed.ts +1 -1
  724. package/packages/web-dashboard/src/lib/multi-project-config.ts +33 -0
  725. package/packages/web-dashboard/src/lib/orchestrator-tools.ts +845 -59
  726. package/packages/web-dashboard/src/lib/planner-workspace.ts +1285 -0
  727. package/packages/web-dashboard/src/lib/review-contracts.ts +5 -3
  728. package/packages/web-dashboard/src/lib/runtime-files.ts +285 -0
  729. package/packages/web-dashboard/src/lib/tool-catalog.ts +51 -0
  730. package/packages/web-dashboard/src/lib/types.ts +731 -3
  731. package/packages/web-dashboard/src/lib/usage-burn.ts +175 -0
  732. package/packages/web-dashboard/src/lib/worktree-diff.ts +128 -0
  733. package/packages/web-dashboard/src/styles/dashboard.module.css +1742 -459
  734. package/packages/web-dashboard/test/api/actions/route.spec.ts +675 -0
  735. package/packages/web-dashboard/test/api/features/diff.route.spec.ts +57 -0
  736. package/packages/web-dashboard/test/api/features/feature.route.spec.ts +99 -0
  737. package/packages/web-dashboard/test/api/features/live-output.route.spec.ts +123 -0
  738. package/packages/web-dashboard/test/api/features/plan-amend.route.spec.ts +95 -0
  739. package/packages/web-dashboard/test/api/features/planner-workspaces.route.spec.ts +162 -0
  740. package/packages/web-dashboard/test/api/features/question-answer.route.spec.ts +99 -0
  741. package/packages/web-dashboard/test/api/features/triage.route.spec.ts +195 -0
  742. package/packages/web-dashboard/test/api/launch/preview.route.spec.ts +149 -0
  743. package/packages/web-dashboard/test/api/launch/submit.route.spec.ts +382 -0
  744. package/packages/web-dashboard/test/api/runtime/events/route.spec.ts +164 -0
  745. package/packages/web-dashboard/test/api/runtime/operations/route.spec.ts +156 -0
  746. package/packages/web-dashboard/test/api/runtime/runs/route.spec.ts +112 -0
  747. package/packages/web-dashboard/test/components/changes-tab.spec.tsx +76 -0
  748. package/packages/web-dashboard/test/components/command-center-root.spec.tsx +87 -0
  749. package/packages/web-dashboard/test/components/diagnosis-panel.spec.tsx +59 -0
  750. package/packages/web-dashboard/test/components/feature-card.spec.tsx +45 -0
  751. package/packages/web-dashboard/test/components/focus-layout.spec.tsx +299 -0
  752. package/packages/web-dashboard/test/components/gate-results.spec.tsx +39 -0
  753. package/packages/web-dashboard/test/components/gates-qa-tab.spec.tsx +118 -0
  754. package/packages/web-dashboard/test/components/human-input-panel.spec.tsx +54 -0
  755. package/packages/web-dashboard/test/components/intake-tab.spec.tsx +210 -0
  756. package/packages/web-dashboard/test/components/kanban-board.spec.tsx +35 -0
  757. package/packages/web-dashboard/test/components/launch-draft-card.spec.tsx +54 -0
  758. package/packages/web-dashboard/test/components/launch-page.spec.tsx +79 -0
  759. package/packages/web-dashboard/test/components/overview-tab.spec.tsx +236 -0
  760. package/packages/web-dashboard/test/components/planning-tab.spec.tsx +202 -0
  761. package/packages/web-dashboard/test/components/review-tab.spec.tsx +169 -0
  762. package/packages/web-dashboard/test/components/role-log-viewer.spec.ts +42 -0
  763. package/packages/web-dashboard/test/components/runtime-inspector.spec.tsx +22 -0
  764. package/packages/web-dashboard/test/components/runtime-tab.spec.tsx +133 -0
  765. package/packages/web-dashboard/test/components/transcript-tab.spec.tsx +46 -0
  766. package/packages/web-dashboard/test/components/triage-drawer.spec.tsx +159 -0
  767. package/packages/web-dashboard/test/lib/aop-client.spec.ts +235 -0
  768. package/packages/web-dashboard/test/lib/dashboard-runtime-client.spec.ts +144 -0
  769. package/packages/web-dashboard/test/lib/focus-detail-derivations.spec.ts +314 -0
  770. package/packages/web-dashboard/test/lib/focus-view.spec.ts +248 -0
  771. package/packages/web-dashboard/test/lib/health-diagnosis.spec.ts +277 -0
  772. package/packages/web-dashboard/test/lib/launch-markdown.spec.ts +36 -0
  773. package/packages/web-dashboard/test/lib/multi-project-config.spec.ts +54 -0
  774. package/packages/web-dashboard/test/lib/orchestrator-tools.spec.ts +352 -0
  775. package/packages/web-dashboard/test/lib/planner-workspace.spec.ts +289 -0
  776. package/packages/web-dashboard/test/lib/worktree-diff.spec.ts +119 -0
  777. package/packages/web-dashboard/vitest.config.ts +2 -0
  778. package/spec-files/completed/agentic_orchestrator_add_feature_to_active_execution_spec.md +557 -0
  779. package/spec-files/completed/agentic_orchestrator_dashboard_command_center_redesign_spec.md +1147 -0
  780. package/spec-files/completed/agentic_orchestrator_execution_mode_spec.md +18 -16
  781. package/spec-files/completed/agentic_orchestrator_feature_focus_view_track_a_spec.md +672 -0
  782. package/spec-files/completed/agentic_orchestrator_feature_focus_view_track_b_spec.md +794 -0
  783. package/spec-files/completed/agentic_orchestrator_feature_focus_view_track_c_decision_centric_remediation_spec.md +1037 -0
  784. package/spec-files/completed/agentic_orchestrator_feature_focus_view_ux_redesign_spec.md +1432 -0
  785. package/spec-files/completed/agentic_orchestrator_focus_plan_tab_intake_planning_workspace_spec.md +921 -0
  786. package/spec-files/completed/agentic_orchestrator_intentional_collision_override_spec.md +584 -0
  787. package/spec-files/completed/agentic_orchestrator_interactive_planning_intake_and_requirements_verification_spec.md +1185 -0
  788. package/spec-files/completed/agentic_orchestrator_reactive_execution_enrollment_spec.md +864 -0
  789. package/spec-files/{outstanding → completed}/agentic_orchestrator_runtime_inspection_spec.md +92 -19
  790. package/spec-files/completed/agentic_orchestrator_scope_aware_run_lease_spec.md +408 -0
  791. package/spec-files/completed/git-reconciliation-engine.md +827 -0
  792. package/spec-files/outstanding/agentic_orchestrator_dashboard_quick_launch_and_control_surface_spec.md +331 -0
  793. package/spec-files/outstanding/agentic_orchestrator_enterprise_governance_dashboard_spec.md +16 -6
  794. package/spec-files/outstanding/agentic_orchestrator_evidence_integrity_doctor_spec.md +60 -9
  795. package/spec-files/outstanding/agentic_orchestrator_focus_plan_tab_execution_contract_workspace_spec.md +616 -0
  796. package/spec-files/outstanding/agentic_orchestrator_headless_standby_dashboard_runtime_spec.md +310 -0
  797. package/spec-files/outstanding/agentic_orchestrator_human_input_interaction_protocol_spec.md +175 -72
  798. package/spec-files/outstanding/agentic_orchestrator_interactive_rename_cleanup_spec.md +197 -0
  799. package/spec-files/outstanding/agentic_orchestrator_interactive_resume_and_reconciliation_disposition_spec.md +412 -0
  800. package/spec-files/outstanding/agentic_orchestrator_knowledge_canary_spec.md +166 -137
  801. package/spec-files/outstanding/agentic_orchestrator_observability_replay_spec.md +3 -3
  802. package/spec-files/outstanding/agentic_orchestrator_phase_specific_agent_profiles_and_token_telemetry_spec.md +303 -0
  803. package/spec-files/outstanding/agentic_orchestrator_planning_review_quality_spec.md +18 -5
  804. package/spec-files/outstanding/agentic_orchestrator_policy_stratification_spec.md +225 -0
  805. package/spec-files/outstanding/agentic_orchestrator_quality_adoption_execution_spec.md +77 -50
  806. package/spec-files/outstanding/agentic_orchestrator_ready_to_merge_branch_handoff_spec.md +724 -0
  807. package/spec-files/outstanding/agentic_orchestrator_remove_deterministic_mode_spec.md +263 -0
  808. package/spec-files/outstanding/agentic_orchestrator_request_more_context_and_dashboard_human_input_spec.md +456 -0
  809. package/spec-files/outstanding/agentic_orchestrator_spec_coverage_and_reconciliation_enforcement_spec.md +1411 -0
  810. package/spec-files/outstanding/agentic_orchestrator_spec_ordering_agent_spec.md +370 -0
  811. package/spec-files/outstanding/shadow_workspace_implementation_spec.md +1 -1
  812. package/spec-files/progress.md +2026 -120
  813. package/specs/001-runtime-inspection/checklists/requirements.md +35 -0
  814. package/specs/001-runtime-inspection/design.md +338 -0
  815. package/specs/001-runtime-inspection/spec.md +95 -0
  816. package/specs/002-scope-aware-lease/checklists/requirements.md +35 -0
  817. package/specs/002-scope-aware-lease/contracts/lease-registry.schema.json +101 -0
  818. package/specs/002-scope-aware-lease/data-model.md +236 -0
  819. package/specs/002-scope-aware-lease/plan.md +766 -0
  820. package/specs/002-scope-aware-lease/quickstart.md +150 -0
  821. package/specs/002-scope-aware-lease/research.md +135 -0
  822. package/specs/002-scope-aware-lease/spec.md +128 -0
  823. package/specs/002-scope-aware-lease/tasks.md +767 -0
  824. package/tsconfig.json +1 -1
  825. package/vitest.config.ts +28 -0
  826. package/ARCHITECTURE_ADHERENCE_ANALYSIS.md +0 -871
  827. package/packages/web-dashboard/next-env.d.ts +0 -6
  828. package/packages/web-dashboard/src/components/detail-panel.tsx +0 -1124
  829. package/packages/web-dashboard/src/components/review-workspace.tsx +0 -1162
  830. /package/spec-files/{outstanding → completed}/agentic_orchestrator_artifact_database_publishing_spec.md +0 -0
  831. /package/spec-files/{outstanding → completed}/agentic_orchestrator_cli_shell_tab_completion_spec.md +0 -0
  832. /package/spec-files/{outstanding → completed}/agentic_orchestrator_dashboard_diff_and_agent_console_spec.md +0 -0
  833. /package/spec-files/{outstanding → completed}/agentic_orchestrator_performance_improvements_spec.md +0 -0
  834. /package/spec-files/{outstanding → completed}/agentic_orchestrator_persistent_worker_runtime_spec.md +0 -0
  835. /package/spec-files/{outstanding → completed}/agentic_orchestrator_provider_auth_bootstrap_spec.md +0 -0
  836. /package/spec-files/{outstanding → completed}/agentic_orchestrator_real_worker_provider_execution_spec.md +0 -0
@@ -0,0 +1,1432 @@
1
+ # Feature Spec: Feature Focus View UX Redesign
2
+
3
+ > Purpose: Redesign the `/feature/{feature_id}` page to make live feature development status immediately scannable, drill-down accessible, and phase-aware — replacing the current single-column scroll with a structured two-pane, tabbed layout.
4
+
5
+ **Version:** 1.3
6
+ **Date:** 2026-03-14
7
+ **Status:** Outstanding
8
+ **Roadmap Mapping:** M46-A (Focus View Core Redesign), M46-B (Focus View Mission-Control Enhancements)
9
+ **Depends On:** M45 (dashboard advanced UX, complete)
10
+
11
+ ---
12
+
13
+ ## 0. Problem Statement
14
+
15
+ The current feature focus view (`/feature/{feature_id}`) has the following structural deficiencies:
16
+
17
+ | Problem | Root Cause | Impact |
18
+ | ----------------------------------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------------------------- |
19
+ | Single long vertical scroll | All sections stacked in one `<aside>` without layout separation | Users cannot scan at a glance — must scroll to understand state |
20
+ | Diff viewer embedded in same column as metadata | `DiffViewer` rendered inside the narrow `detailPanel` column | Wide diffs are squeezed; side-by-side diffs unusable |
21
+ | No visual hierarchy between sections | Every section is equal weight (same `.section` class) | Users cannot tell what is urgent vs. informational |
22
+ | Phase-agnostic layout | Layout does not change based on current phase | A `building` view and `ready_to_merge` view look identical in structure |
23
+ | Review actions buried at the bottom | `stickyReviewFooter` only sticky within the panel scroll | For long-diff features, reviewer must scroll past diff to reach approve/deny |
24
+ | Metadata repetition | Feature ID, phase, status appear in header AND panel header | Cognitive redundancy, wasted vertical space |
25
+ | `DetailPanel` component is 1130+ lines | All rendering logic collapsed into one component | Difficult to maintain, test, and extend |
26
+ | No "what is happening right now" signal | Activity state, current agent role, time-in-phase all buried in metadata list | Operators cannot triage at a glance |
27
+
28
+ ---
29
+
30
+ ## 1. Design Goals
31
+
32
+ ### 1.1 Primary Jobs
33
+
34
+ This redesign optimizes for three ordered jobs:
35
+
36
+ 1. **Operator job:** Understand the current state of a feature run in under 5 seconds without scrolling.
37
+ 2. **Reviewer job:** Make an approve/deny/request-changes decision with full context visible, without hunting for the action buttons.
38
+ 3. **Diagnostics job:** Drill down into plan, diff, gates, QA, runtime, and history in focused dedicated panels — not a scroll maze.
39
+
40
+ ### 1.2 UX Principles
41
+
42
+ 1. **Status first:** The hero block answers "what is this, what phase is it in, is it healthy?" before any detail is visible.
43
+ 2. **Phase-aware defaults:** The active tab defaults to the most relevant content for the current phase (e.g., Gates for `blocked`, Changes for `building`, Review for `ready_to_merge`).
44
+ 3. **Actions always reachable:** Review actions (approve / deny / request changes) are pinned — never buried below content.
45
+ 4. **Progressive disclosure:** Deep diagnostics (runtime inspector, history log, checkpoint comparison) are accessible but not in the primary viewport.
46
+ 5. **Content width matches content type:** Diffs, plan trees, and QA maps get the full viewport width. Metadata and actions stay in a fixed sidebar.
47
+
48
+ ### 1.3 Non-Goals
49
+
50
+ - Redesigning the Board view (`/`) — out of scope (except the Merge Queue card, which surfaces queue position on the focus view only).
51
+ - Changing any existing backend API response shape (additive new endpoints are in scope for Track B features, and additive metadata is allowed when required for Track A lazy-loading or tab visibility).
52
+ - Implementing drag-and-drop or resizable panes.
53
+
54
+ ### 1.4 Visual System Contract
55
+
56
+ The focus view must align with the current Aequitas-inspired dashboard styling already established in `packages/web-dashboard/src/app/globals.css` and `packages/web-dashboard/src/styles/dashboard.module.css`.
57
+
58
+ - Use the shared light-surface visual system: white and light-blue panels, slate text, soft borders, and the existing page background gradient.
59
+ - Use the existing semantic palette: teal as the primary brand/action color, gold/orange for emphasis and warnings, red for destructive or blocked states.
60
+ - Do not reintroduce the older dark "ops console" palette for new focus-view components unless a specific embedded tool requires it.
61
+ - Embedded tooling must visually match the page: Monaco diff/editor instances use the light theme; diff containers and overlays use the shared surface tokens.
62
+ - New focus-view CSS must consume shared dashboard tokens rather than defining page-local colors.
63
+
64
+ ### 1.5 Delivery Tracks
65
+
66
+ This spec is split into two delivery tracks to keep the core focus-view redesign from being blocked by optional analytics and mission-control features.
67
+
68
+ **Track A: Core Focus View Redesign**
69
+
70
+ - Two-pane layout, hero block, diagnosis panel, tabbed content, pinned actions
71
+ - Review/runtime/history/transcript capability preservation from the current `review-workspace.tsx`
72
+ - Lazy-load cleanup, responsive behavior, accessibility, and decomposition of `detail-panel.tsx`
73
+
74
+ **Track B: Mission-Control Enhancements**
75
+
76
+ - Transcript polish, code evolution scrubber, collision radar, token-usage burn analytics, genealogy, merge queue, role performance, flakiness summaries, annotations, and command palette
77
+ - New additive API endpoints required by those advanced features
78
+
79
+ Track A is the required deliverable for M46-A. Track B is a follow-on deliverable for M46-B.
80
+
81
+ ---
82
+
83
+ ## 2. Layout Architecture
84
+
85
+ ### 2.1 Top-Level Structure
86
+
87
+ The page uses a **two-zone layout**:
88
+
89
+ ```
90
+ ┌─────────────────────────────────────────────────────────────────┐
91
+ │ FOCUS HEADER (back nav, feature ID, breadcrumb) │
92
+ ├──────────────┬──────────────────────────────────────────────────┤
93
+ │ │ TAB BAR │
94
+ │ CONTEXT │──────────────────────────────────────────────────┤
95
+ │ SIDEBAR │ │
96
+ │ (fixed │ TAB CONTENT PANEL │
97
+ │ width, │ (scrollable, full remaining width) │
98
+ │ scrollable)│ │
99
+ │ │ │
100
+ │ ─────────── │ │
101
+ │ REVIEW │ │
102
+ │ ACTIONS │ │
103
+ │ (pinned │ │
104
+ │ bottom) │ │
105
+ └──────────────┴──────────────────────────────────────────────────┘
106
+ ```
107
+
108
+ **Context Sidebar** — 280px fixed width, `position: sticky`, full viewport height. Contains:
109
+
110
+ - Hero status block
111
+ - Agent pipeline stepper
112
+ - Phase metadata (branch, time-in-phase, activity state)
113
+ - Usage panel (collapsed by default)
114
+ - Unresolved dependencies list (if any)
115
+ - PR status card (if PR exists)
116
+ - Review actions (pinned to sidebar bottom for `ready_to_merge`, `building`, `qa` phases)
117
+
118
+ The sidebar is priority-ordered. The first viewport must fit, in order: hero block, diagnosis panel (if present), pinned actions or human input, and pipeline stepper. Lower-priority content such as usage, dependencies, and PR status may collapse behind summaries if vertical space is constrained.
119
+
120
+ **Tab Content Panel** — fills remaining width. Contains all deep-detail sections behind tabs.
121
+
122
+ ### 2.2 Hero Status Block
123
+
124
+ The top of the sidebar shows a compact, always-visible hero block:
125
+
126
+ ```
127
+ ┌────────────────────────────┐
128
+ │ feature-id-slug │ ← feature_id (truncated with tooltip)
129
+ │ ● BUILDING [active] │ ← phase badge + activity_state badge
130
+ │ In phase: 4m 32s │ ← time-in-phase, live updating
131
+ │ Builder running │ ← current active role
132
+ │ Branch: feat/my-feature │ ← branch name
133
+ └────────────────────────────┘
134
+ ```
135
+
136
+ - Phase badge uses the existing phase color variables (`--color-building`, etc.)
137
+ - Activity state badge (`active`, `waiting_input`, `blocked`, `idle`) uses existing badge classes
138
+ - Time-in-phase updates every 30 seconds (not every second — avoids unnecessary re-renders)
139
+ - "Live activity" pulse indicator (`.inlinePulse`) shown when `activity_state === 'active'`
140
+ - If `phase === 'blocked'`, the hero block renders in `--color-blocked` accent and shows `status_reason` inline
141
+
142
+ ### 2.3 Tab Definitions
143
+
144
+ | Tab Key | Label | Icon | Visible When | Default For Phases |
145
+ | ------------ | ---------- | ---- | ------------------------ | ------------------ |
146
+ | `overview` | Overview | `◎` | Always | `planning` |
147
+ | `plan` | Plan | `📋` | `plan !== null` | — |
148
+ | `changes` | Changes | `⌥` | `shouldShowDiff` | `building` |
149
+ | `gates` | Gates & QA | `✓` | `shouldShowGates` | `qa`, `blocked` |
150
+ | `review` | Review | `◈` | `ready_to_merge`, `qa` | `ready_to_merge` |
151
+ | `runtime` | Runtime | `⚡` | Always | — |
152
+ | `history` | History | `↺` | Always | `merged` |
153
+ | `transcript` | Transcript | `💬` | `log_entries.length > 0` | — |
154
+
155
+ Tab visibility is computed from the same conditions already used in `DetailPanel` (`shouldShowPlan`, `shouldShowDiff`, `shouldShowGates`). No new logic is required.
156
+
157
+ The active tab at page load is determined by the feature's current phase (see "Default For Phases" column). If a phase maps to no tab (e.g., `paused_budget`), fall back to `overview`.
158
+
159
+ ---
160
+
161
+ ## 3. Tab Content Specifications
162
+
163
+ ### 3.1 Overview Tab
164
+
165
+ Replaces the current fragmented metadata sections. Consolidates into scannable cards:
166
+
167
+ **Sections (stacked, no scroll needed for most features):**
168
+
169
+ 1. **Verification Signals** — `VerificationSignals` component, unchanged.
170
+ 2. **Plan Revision Timeline** — `PlanRevisionTimeline`, collapsed by default if no revisions.
171
+ 3. **Risk Annotations** — `PlanRiskAnnotations`, collapsed by default unless `ready_to_merge`.
172
+ 4. **Blocked State Banner** — visible only when `phase === 'blocked'`; shows `status_reason` and retry button inline.
173
+ 5. **Merged State Summary** — visible only when `phase === 'merged'`; shows PR link and merge commit.
174
+ 6. **Budget Banner** — visible only when `status === 'paused_budget'`.
175
+
176
+ ### 3.2 Plan Tab
177
+
178
+ Dedicated full-width view:
179
+
180
+ 1. **Plan Scope Tree** — `PlanScopeTree` at full content width.
181
+ 2. **Plan Viewer** — `PlanViewer` below the tree.
182
+
183
+ No other content competes for horizontal space. This is important because plan trees benefit from wide rendering.
184
+
185
+ ### 3.3 Changes Tab
186
+
187
+ Dedicated full-width diff view:
188
+
189
+ 1. **DiffViewer** — `DiffViewer` rendered at full content panel width.
190
+ 2. No sidebar competition. Wide diffs render correctly.
191
+
192
+ For `ready_to_merge` and `qa` phases, if the `ReviewWorkspace` is currently shown, the Changes tab hosts the Monaco diff editor component from `review-workspace.tsx` rather than the `diff2html` viewer. The tab-based layout replaces the current `showReviewWorkspace` boolean branch.
193
+
194
+ ### 3.4 Gates & QA Tab
195
+
196
+ 1. **Review Brief Panel** — `ReviewBriefPanel` at top (for `qa`, `ready_to_merge`).
197
+ 2. **Gate Results** — `GateResults`.
198
+ 3. **Gate Step Drilldown** — `GateStepDrilldown`.
199
+ 4. **QA Coverage Map** — `QaCoverageMap`.
200
+ 5. **Evidence Viewer** — `EvidenceViewer`.
201
+
202
+ All components already exist. Tab simply groups them.
203
+
204
+ ### 3.5 Review Tab
205
+
206
+ Visible only for `ready_to_merge` and `qa` phases. Consolidates the review actions form:
207
+
208
+ 1. **Review Brief Panel** (repeated from Gates & QA for convenient co-location with action form).
209
+ 2. **Review actions form** — review message textarea, approval token input, merge strategy select.
210
+ 3. **Action buttons** — Approve (green), Deny (red), Request Changes.
211
+
212
+ This tab is the default for `ready_to_merge`. The review actions are no longer buried at the bottom of a long scroll.
213
+
214
+ **Note:** The review actions are also pinned in the sidebar bottom for quick access without navigating to the Review tab. The sidebar version is a compact form (just the three action buttons); the full form with textarea/token/strategy is on the Review tab.
215
+
216
+ The compact sidebar actions and the full Review tab form share one source of truth for `reviewMessage`, `approvalToken`, and `mergeStrategy`. Navigating between the compact actions and the full form must not reset draft state.
217
+
218
+ ### 3.6 Runtime Tab
219
+
220
+ Replaces the runtime-oriented sections currently split across `DetailPanel` and `review-workspace.tsx`:
221
+
222
+ 1. **Execution Runtime Badge** — interactive execution pill, optionally paired with headless/attached runtime state when available.
223
+ 2. **Runtime Inspector Panel** — `RuntimeInspectorPanel` component (existing, unchanged).
224
+ 3. **Agent Session Status** — current role, per-role session IDs, active marker, copy affordances.
225
+ 4. **Directed Agent Console** — preserved from `review-workspace.tsx`; allows sending a message to the active runtime session when available.
226
+ 5. **Activity Timeline** — existing runtime/activity view and role/validity filtering preserved.
227
+ 6. **Checkpoints Section** — visible only when `showCheckpointTimeline`. Contains the tab-within-tab UI (Timeline / Snapshot Diff / Compare) from the current `DetailPanel`. This sub-navigation is preserved exactly.
228
+
229
+ By moving to a dedicated tab, the checkpoint compare grid (which uses a two-column layout) can render at full content width rather than being crammed into the detail panel.
230
+
231
+ ### 3.7 History Tab
232
+
233
+ 1. **Log List** — lazy-loaded, same as current `<details>` section.
234
+ 2. **Raw Agent Output** — preserved from `review-workspace.tsx`, including policy-disabled states and file selection.
235
+ 3. Default for `merged` phase so merge summary is the first thing visible.
236
+
237
+ ### 3.8 Transcript Tab
238
+
239
+ The transcript tab is part of Track A in its base form, because the current review workspace already exposes live role-tagged activity that would otherwise be lost in the redesign.
240
+
241
+ 1. **Role-grouped transcript view** — live or loaded entries grouped by consecutive role turns.
242
+ 2. **Follow / pause behavior** — preserve the current "Pause Follow / Resume Follow" interaction for actively streaming runs.
243
+ 3. **Actor and role identity** — preserve actor labels and timestamps.
244
+ 4. **Advanced markdown rendering, raw-log shortcuts, and enhanced syntax highlighting** are Track B polish, not Track A requirements.
245
+
246
+ ---
247
+
248
+ ## 4. Sidebar Review Actions (Pinned)
249
+
250
+ For phases `ready_to_merge`, `building`, and `qa`, the sidebar renders a pinned action strip at its bottom:
251
+
252
+ ```
253
+ ┌────────────────────────────┐
254
+ │ [Approve] [Deny] [⋯] │ ← ready_to_merge
255
+ └────────────────────────────┘
256
+
257
+ ┌────────────────────────────┐
258
+ │ [Request Changes] │ ← building / qa
259
+ └────────────────────────────┘
260
+ ```
261
+
262
+ - **`ready_to_merge`:** Three buttons: Approve (primary green), Deny (danger red), and an overflow menu (⋯) for Request Changes. Clicking Approve or Deny opens the existing `ConfirmationModal`.
263
+ - **`building` / `qa`:** Single "Request Changes" button that opens the same modal.
264
+ - Clicking any action button that requires the full form navigates to the Review tab and scrolls to the form.
265
+ - For `waiting_input`, the pinned strip shows the `HumanInputPanel` widget instead.
266
+ - For all other phases, the pinned strip is absent.
267
+
268
+ This ensures the most important action is always one click away regardless of which tab is active.
269
+
270
+ If an action requires inputs that are not currently satisfied in compact mode:
271
+
272
+ - `Approve` without an approval token navigates to the Review tab and focuses the approval-token input.
273
+ - `Deny` without a reason navigates to the Review tab and focuses the review-message textarea.
274
+ - `Request Changes` may execute from compact mode using the shared draft state or a default message, but its behavior must be defined consistently across phases.
275
+
276
+ ---
277
+
278
+ ## 5. Health Diagnosis System
279
+
280
+ A feature is not always simply "healthy" or "blocked." There is a spectrum: hard blocks, degraded runs, stalled activity, human-input waits, CI failures, and dependency blocks. The current page surfaces none of this proactively — `status_reason` is buried in the metadata list, gate failures require navigating to the Gates tab, and lock contention is invisible.
281
+
282
+ This section specifies a client-side health diagnosis layer that derives a structured diagnosis from available `FeatureDetail` and `FeaturesIndex` data, and surfaces it in a `DiagnosisPanel` placed in the sidebar immediately below the hero block.
283
+
284
+ ### 5.1 Taxonomy of Unhealthy States
285
+
286
+ | Severity | Label | Definition |
287
+ | ---------- | -------- | ---------------------------------------------------------------------------------------- |
288
+ | `blocked` | BLOCKED | Hard stop — feature cannot progress without intervention |
289
+ | `degraded` | DEGRADED | Feature is running but has active failures or warnings that may prevent phase completion |
290
+ | `stalled` | STALLED | Feature is not progressing; no recent activity detected |
291
+ | `waiting` | WAITING | Feature is paused pending human input (not an error, but requires action) |
292
+ | `healthy` | — | No diagnosis panel rendered |
293
+
294
+ Severity is exclusive and priority-ordered. If multiple signals apply, the highest-severity wins for the `primary_cause`. All other signals are `secondary_causes`.
295
+
296
+ ### 5.2 Signal-to-Diagnosis Mapping
297
+
298
+ The following signals from `FeatureSummary`, `GateRunEvidence`, `FeaturesIndex`, and `FeatureCheckpoint[]` drive the diagnosis:
299
+
300
+ | Signal | Severity | Cause Code | Human Label | Suggested Action | Links To |
301
+ | --------------------------------------------------------------------- | ---------- | ------------------------ | -------------------------------------- | ---------------------------------------------------------- | ------------------------- |
302
+ | `phase === 'blocked'` | `blocked` | `PHASE_BLOCKED` | "Feature is blocked" | Review the block reason below; use Retry or send a message | Overview tab |
303
+ | `activity_state === 'blocked'` | `blocked` | `ACTIVITY_BLOCKED` | "Agent process blocked" | Check runtime logs for deadlock or error | Runtime tab |
304
+ | `activity_state === 'exited'` AND phase not `merged` | `blocked` | `AGENT_EXITED` | "Agent exited unexpectedly" | Review history for last known state; consider retry | History tab |
305
+ | `status === 'paused_budget'` | `blocked` | `BUDGET_EXHAUSTED` | "Token budget exhausted" | Increase budget in policy or request manual continuation | Overview tab |
306
+ | `FeaturesIndex.dep_blocked` contains this feature_id | `blocked` | `DEPENDENCY_BLOCK` | "Blocked on unresolved dependencies" | List shown inline; navigate to dependent feature | Overview tab |
307
+ | `gate_evidence.overall !== 'pass'` | `degraded` | `GATE_FAILURE` | "Gate checks failing" | Review failing steps below | Gates & QA tab |
308
+ | `gate_retry_count >= 2` | `degraded` | `REPEATED_GATE_FAILURES` | "Gates failing repeatedly (N retries)" | Check for flaky tests or systemic issue | Gates & QA tab |
309
+ | `pr.ci_status === 'failed'` | `degraded` | `CI_FAILURE` | "CI pipeline failing" | Review CI logs on PR | Review tab |
310
+ | `pr.has_conflicts === true` | `degraded` | `MERGE_CONFLICTS` | "PR has merge conflicts" | Manual conflict resolution required | Review tab |
311
+ | `pr.pending_review_threads > 0` | `degraded` | `OPEN_REVIEW_THREADS` | "N unresolved review threads" | Address reviewer comments | Review tab |
312
+ | `review_brief.unresolved_questions.length > 0` | `degraded` | `UNRESOLVED_QUESTIONS` | "N open questions identified by QA" | Review questions in Gates & QA | Gates & QA tab |
313
+ | `checkpoints` contains entries where `validation_status !== 'valid'` | `degraded` | `CHECKPOINT_VIOLATIONS` | "Checkpoint validation failures" | Review violations in Runtime tab | Runtime tab |
314
+ | `activity_state === 'idle'` AND `activity_last_event_at` > 10 min ago | `stalled` | `ACTIVITY_STALLED` | "No activity detected for N minutes" | Check if agent is still running; consider retry | Runtime tab |
315
+ | `FeaturesIndex.lock_leases` has stale lease for this feature | `stalled` | `STALE_LOCK` | "Stale lock detected" | Lock may be preventing progress; may auto-expire | Overview tab |
316
+ | `activity_state === 'waiting_input'` | `waiting` | `WAITING_INPUT` | "Waiting for human input" | Respond to the agent prompt below | Sidebar (HumanInputPanel) |
317
+
318
+ ### 5.3 `deriveHealthDiagnosis()` Function
319
+
320
+ A pure function, no side effects, no async. Lives in `lib/health-diagnosis.ts`.
321
+
322
+ ```typescript
323
+ export type DiagnosisSeverity = 'blocked' | 'degraded' | 'stalled' | 'waiting' | 'healthy';
324
+
325
+ export interface DiagnosisCause {
326
+ code: string;
327
+ label: string;
328
+ detail?: string; // e.g. status_reason text, retry count, dep list
329
+ link_tab?: TabKey; // tab to navigate to for details
330
+ action_hint?: string; // one-sentence suggested action
331
+ }
332
+
333
+ export interface HealthDiagnosis {
334
+ severity: DiagnosisSeverity;
335
+ primary: DiagnosisCause;
336
+ secondary: DiagnosisCause[];
337
+ }
338
+
339
+ export function deriveHealthDiagnosis(
340
+ feature: FeatureSummary,
341
+ gateEvidence: GateRunEvidence | null | undefined,
342
+ featuresIndex: FeaturesIndex | null,
343
+ checkpoints: FeatureCheckpoint[],
344
+ ): HealthDiagnosis | null; // returns null when healthy
345
+ ```
346
+
347
+ **Evaluation order** (first match wins for `primary`):
348
+
349
+ 1. `BUDGET_EXHAUSTED` — `feature.status === 'paused_budget'`
350
+ 2. `PHASE_BLOCKED` — `feature.phase === 'blocked'`
351
+ 3. `AGENT_EXITED` — `feature.activity_state === 'exited'` AND phase not `merged`
352
+ 4. `ACTIVITY_BLOCKED` — `feature.activity_state === 'blocked'`
353
+ 5. `DEPENDENCY_BLOCK` — `featuresIndex.dep_blocked` contains this feature_id
354
+ 6. `GATE_FAILURE` — `gateEvidence?.overall` is not `'pass'` and not null
355
+ 7. `CI_FAILURE` — `feature.pr?.ci_status === 'failed'`
356
+ 8. `MERGE_CONFLICTS` — `feature.pr?.has_conflicts === true`
357
+ 9. `REPEATED_GATE_FAILURES` — `feature.gate_retry_count >= 2`
358
+ 10. `CHECKPOINT_VIOLATIONS` — any checkpoint has `validation_status !== 'valid'`
359
+ 11. `OPEN_REVIEW_THREADS` — `feature.pr?.pending_review_threads > 0`
360
+ 12. `UNRESOLVED_QUESTIONS` — checked only if `review_brief` is passed; treated as secondary unless it is the only signal
361
+ 13. `ACTIVITY_STALLED` — `activity_state === 'idle'` AND `activity_last_event_at` is > 10 minutes ago (configurable constant)
362
+ 14. `STALE_LOCK` — `featuresIndex.lock_leases` has entry for this feature with `stale: true`
363
+ 15. `WAITING_INPUT` — `feature.activity_state === 'waiting_input'`
364
+
365
+ All matching signals below the first are collected as `secondary`. The function returns `null` (healthy) if no signals match.
366
+
367
+ The 10-minute idle threshold is a named constant `STALL_THRESHOLD_MS = 10 * 60 * 1000` in the same file.
368
+
369
+ ### 5.4 `DiagnosisPanel` Component
370
+
371
+ **Location in layout:** Sidebar, between `HeroBlock` and `AgentPipelineStepper`. Rendered only when `deriveHealthDiagnosis()` returns non-null.
372
+
373
+ ```
374
+ ┌────────────────────────────────────────┐
375
+ │ ⛔ BLOCKED │ ← severity icon + label, phase-severity color
376
+ │ │
377
+ │ Feature is blocked │ ← primary.label
378
+ │ "Planner rejected: schema mismatch │ ← primary.detail (status_reason, truncated)
379
+ │ in plan step 3" │ with expand toggle for long text
380
+ │ │
381
+ │ → See Overview │ ← link_tab navigation (tab switch, not href)
382
+ │ │
383
+ │ Also: │ ← secondary causes (collapsed by default,
384
+ │ · Gates failing (2 retries) │ expandable with "Also: N more" toggle)
385
+ │ · CI pipeline failing │
386
+ └────────────────────────────────────────┘
387
+ ```
388
+
389
+ **Visual design:**
390
+
391
+ - Border-left 3px in severity color (`--color-blocked` for blocked, `--color-building` orange for degraded, muted yellow for stalled, muted blue for waiting)
392
+ - Background: subtle tint of severity color at 8% opacity
393
+ - Icon: `⛔` blocked, `⚠` degraded, `⏸` stalled, `⏳` waiting
394
+ - `primary.detail` is truncated at 120 characters with an inline expand toggle ("show more / show less")
395
+ - `link_tab` renders as a small text link that calls `setActiveTab(link_tab)` — no page navigation
396
+ - Secondary causes are collapsed by default behind a "Also: N more issues" toggle; expanded as a bullet list
397
+
398
+ **Gate failure detail enrichment:**
399
+ When `code === 'GATE_FAILURE'`, the panel additionally renders the first failing gate step inline:
400
+
401
+ ```
402
+ Gates failing (1 of 3 steps failed)
403
+ Step: "npm run test:coverage"
404
+ Last output: "Error: Coverage threshold not met…" ← output_tail[last]
405
+ → See Gates & QA
406
+ ```
407
+
408
+ This is the most critical diagnostic data for a blocked build — surfacing the actual error output from `GateStepResult.output_tail` in the sidebar means the operator does not have to navigate to the Gates tab just to see why the gate failed.
409
+
410
+ **Dependency block detail:**
411
+ When `code === 'DEPENDENCY_BLOCK'`, the panel lists the unresolved dependency feature IDs inline as links:
412
+
413
+ ```
414
+ Blocked on unresolved dependencies:
415
+ · feat/auth-tokens → (link to /feature/feat/auth-tokens)
416
+ · feat/db-schema → (link to /feature/feat/db-schema)
417
+ ```
418
+
419
+ ### 5.5 Hero Block Integration
420
+
421
+ When `diagnosis.severity` is not `healthy`, the hero block's phase badge gains a secondary indicator:
422
+
423
+ ```
424
+ ● BUILDING ⚠ ← phase badge + severity icon inline
425
+ ```
426
+
427
+ This is a single character addition to the existing badge — no layout change. The severity color applies to the warning icon, not the phase badge (phase badge color is always phase-based, not health-based, to preserve the existing color-coding convention).
428
+
429
+ ### 5.6 Data Availability and Lazy Loading
430
+
431
+ `deriveHealthDiagnosis()` is called whenever `FeatureDetail` loads. It does not require any additional API calls beyond what is already fetched on page load. The `FeaturesIndex` data comes from the existing `/api/status` call. `GateRunEvidence` is part of `FeatureDetail.gate_evidence`.
432
+
433
+ `review_brief.unresolved_questions` is a lazy-loaded field (fetched on Gates & QA tab activation). If not yet loaded, the `UNRESOLVED_QUESTIONS` signal is simply absent from the diagnosis — the panel re-evaluates when the field becomes available.
434
+
435
+ The diagnosis panel must degrade gracefully when optional fields are unavailable. "Healthy" must never be inferred from missing lazy data; it means "no active signals from currently-available data."
436
+
437
+ ---
438
+
439
+ ## 6. Component Decomposition
440
+
441
+ The current `detail-panel.tsx` (~1130 lines) must be split. The new structure:
442
+
443
+ | New File | Responsibility | Approx. Lines |
444
+ | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | ------------- |
445
+ | `components/focus/FocusLayout.tsx` | Two-zone layout shell, tab state management | ~120 |
446
+ | `components/focus/FocusHeader.tsx` | Back nav + feature ID breadcrumb | ~40 |
447
+ | `components/focus/ContextSidebar.tsx` | Hero block + pipeline stepper + metadata + pinned actions | ~220 |
448
+ | `components/focus/HeroBlock.tsx` | Feature ID, phase badge, activity state, time-in-phase | ~80 |
449
+ | `components/focus/TabBar.tsx` | Tab definitions, active tab, visibility logic | ~90 |
450
+ | `components/focus/tabs/OverviewTab.tsx` | Verification signals, timeline, risk, blocked/merged banners | ~100 |
451
+ | `components/focus/tabs/PlanTab.tsx` | Scope tree + plan viewer | ~40 |
452
+ | `components/focus/tabs/ChangesTab.tsx` | DiffViewer or Monaco diff by phase | ~60 |
453
+ | `components/focus/tabs/GatesQaTab.tsx` | Review brief + gate results + coverage + evidence | ~80 |
454
+ | `components/focus/tabs/ReviewTab.tsx` | Full review form + actions | ~120 |
455
+ | `components/focus/tabs/RuntimeTab.tsx` | Runtime inspector + session status + directed console + checkpoints section | ~140 |
456
+ | `components/focus/tabs/HistoryTab.tsx` | Log list + raw provider output | ~90 |
457
+ | `components/focus/PinnedActions.tsx` | Phase-aware pinned action strip | ~100 |
458
+ | `components/focus/DiagnosisPanel.tsx` | Health diagnosis panel with primary/secondary causes and gate step detail | ~150 |
459
+ | `lib/health-diagnosis.ts` | `deriveHealthDiagnosis()` pure function + all types | ~120 |
460
+ | `components/focus/tabs/TranscriptTab.tsx` | Agent transcript preserving live role-tagged activity; advanced rendering is Track B | ~120 |
461
+ | `components/focus/CheckpointScrubber.tsx` | Timeline slider for scrubbing through checkpoint diffs chronologically | ~140 |
462
+ | `components/focus/CollisionRadar.tsx` | Directory treemap showing cross-feature file collision risk | ~200 |
463
+ | `components/focus/UsageBurnChart.tsx` | Token-usage-over-time sparkline with projected final usage and optional derived dollar overlay | ~130 |
464
+ | `components/focus/GenealogyTree.tsx` | Revision ancestry tree with reason labels | ~120 |
465
+ | `components/focus/GateFlakinessSummary.tsx` | Per-gate-step sparkline of pass/fail history with flakiness score | ~150 |
466
+ | `components/focus/AnnotatableDiffViewer.tsx` | Monaco-based diff with click-to-annotate hunk comments | ~200 |
467
+ | `components/CommandPalette.tsx` | Global Cmd+K overlay with fuzzy feature search and action dispatch | ~220 |
468
+ | `components/focus/AgentRolePerformanceCard.tsx` | Per-role metrics card comparing this run to historical provider averages | ~100 |
469
+ | `components/focus/MergeQueueCard.tsx` | This feature's position in the merge queue with dependency blockers | ~110 |
470
+ | `lib/collision-radar.ts` | `deriveCollisionRisk()` pure function mapping file paths to risk scores across active features | ~80 |
471
+ | `lib/usage-burn.ts` | `projectUsageBurnRate()` pure function extrapolating token usage/time from current spend and provider averages | ~80 |
472
+
473
+ The existing component files (`plan-viewer.tsx`, `diff-viewer.tsx`, `gate-results.tsx`, etc.) are **not changed** where practical — they are consumed by the new tab components. `detail-panel.tsx` is retired and replaced by `FocusLayout.tsx`.
474
+
475
+ `review-workspace.tsx` is retired only after all of its operator-critical capabilities are preserved:
476
+
477
+ - Monaco diff inspector
478
+ - Review action form
479
+ - Live agent log stream / transcript
480
+ - Directed agent console
481
+ - Session status panel
482
+ - Runtime activity timeline filters
483
+ - Raw provider output access
484
+ - Mobile inspector flow
485
+
486
+ The `showReviewWorkspace` boolean branch in `page.tsx` is eliminated only after feature parity is achieved.
487
+
488
+ ---
489
+
490
+ ## 7. Page Route Changes (`app/feature/[id]/page.tsx`)
491
+
492
+ The page component currently renders either `<ReviewWorkspace>` or `<aside className={styles.detailPanel}>` based on a boolean. This branch is replaced:
493
+
494
+ ```tsx
495
+ // Before (two separate rendering paths)
496
+ {showReviewWorkspace ? <ReviewWorkspace ... /> : <aside><DetailPanel .../></aside>}
497
+
498
+ // After (single path, phase-aware via tab defaults)
499
+ <FocusLayout
500
+ detail={detail}
501
+ project={project}
502
+ statusPayload={payload}
503
+ hasActiveRuntimeSession={hasActiveRuntimeSession}
504
+ />
505
+ ```
506
+
507
+ `FocusLayout` reads the phase and selects the correct default tab internally. No branching at the page level.
508
+
509
+ ---
510
+
511
+ ## 8. CSS Changes
512
+
513
+ New CSS classes needed in `dashboard.module.css`:
514
+
515
+ | Class | Purpose |
516
+ | ----------------- | ------------------------------------------------------------------------------------------ |
517
+ | `.focusTwoPane` | Two-zone grid layout: `grid-template-columns: 280px 1fr` |
518
+ | `.contextSidebar` | Fixed-width sidebar: `position: sticky; top: 0; height: 100vh; overflow-y: auto` |
519
+ | `.heroBlock` | Hero status container: padding, border-bottom |
520
+ | `.heroPhaseBadge` | Large phase badge in hero: 0.85rem, phase color variable |
521
+ | `.heroFeatureId` | Feature ID in hero: 1rem bold, truncation with tooltip |
522
+ | `.heroMeta` | Secondary metadata lines in hero: 0.75rem muted |
523
+ | `.sidebarDivider` | Horizontal rule between sidebar sections |
524
+ | `.pinnedActions` | Sticky bottom strip in sidebar: `position: sticky; bottom: 0; background: var(--bg-panel)` |
525
+ | `.tabBar` | Horizontal tab row: flex, border-bottom |
526
+ | `.tabItem` | Individual tab button: 0.78rem, uppercase, padding |
527
+ | `.tabItemActive` | Active tab: bottom border 2px phase-colored, primary text color |
528
+ | `.tabContent` | Tab content area: `overflow-y: auto; padding: 1rem 1.5rem` |
529
+
530
+ | `.diagnosisPanel` | Diagnosis container: border-left 3px severity color, 8% tint background, padding |
531
+ | `.diagnosisSeverityLabel` | "BLOCKED / DEGRADED / STALLED / WAITING" label: 0.7rem uppercase, severity color |
532
+ | `.diagnosisPrimary` | Primary cause text: 0.82rem, primary text color |
533
+ | `.diagnosisDetail` | Detail/reason text: 0.78rem muted, truncated with expand toggle |
534
+ | `.diagnosisLink` | Tab-switch link: 0.75rem, underline, phase-accent color |
535
+ | `.diagnosisSecondary` | Secondary causes list: 0.75rem muted, bullet list |
536
+ | `.diagnosisGateStep` | Gate step failure inline block: monospace, 0.72rem, slightly indented |
537
+
538
+ Responsive behavior:
539
+
540
+ - At viewports < 900px: sidebar collapses to a horizontal strip above the tab bar (phase badge, activity state, and pinned actions only). Metadata moves into the Overview tab.
541
+ - At viewports < 600px: sidebar strip becomes a single-line status bar. Tab bar becomes horizontally scrollable.
542
+
543
+ Visual token requirements:
544
+
545
+ - New focus-view classes must use the shared dashboard light-theme tokens already defined in `globals.css` and `dashboard.module.css`.
546
+ - `--bg-panel`, `--bg-card`, `--bg-elevated`, `--text-primary`, `--text-muted`, `--border-weak`, `--border-strong`, and the phase color variables are the default inputs for new components.
547
+ - Primary action buttons use the shared teal CTA treatment. Destructive actions use the shared red semantic styling. Warning/attention surfaces use the shared gold treatment.
548
+ - New diagnosis and phase badges must pass contrast checks against light surfaces.
549
+ - Monaco and diff containers must remain on the light theme to match the page.
550
+
551
+ This section supersedes the earlier assumption that "existing CSS variables and component-level classes are unchanged." The visual system has already moved to the Aequitas-aligned light palette and the focus view must follow it.
552
+
553
+ ---
554
+
555
+ ## 9. Data Fetching
556
+
557
+ No required backend contract changes for Track A beyond additive support where noted. The loading model is clarified to separate first-paint data from tab-lazy data.
558
+
559
+ ### 9.1 First-Paint vs Lazy-Load Contract
560
+
561
+ **Required for first paint:**
562
+
563
+ - `FeatureDetail`
564
+ - `DashboardStatusPayload`
565
+ - Phase/status/activity/role metadata needed for hero + diagnosis
566
+
567
+ **Sidebar-lazy or expansion-lazy:**
568
+
569
+ - Usage details and budget/conversion policy, unless usage is promoted into the hero summary
570
+ - PR details beyond a compact summary
571
+
572
+ **Tab-lazy:**
573
+
574
+ - Review brief
575
+ - QA test index
576
+ - History log
577
+ - Raw provider output
578
+ - Checkpoint diff/compare payloads
579
+ - Runtime event timeline details
580
+
581
+ The focus view must not eagerly fetch every optional dataset on mount.
582
+
583
+ Specifically:
584
+
585
+ - `OverviewTab` triggers no additional fetches (all data available in `FeatureDetail`).
586
+ - `GatesQaTab` triggers the `review-brief` fetch on first activation.
587
+ - `HistoryTab` triggers the `log` fetch on first activation.
588
+ - `RuntimeTab` triggers the runtime/activity fetch on first activation; SSE stream for checkpoints starts only when Runtime tab is active and `execution_mode === 'interactive'`.
589
+ - `HistoryTab` and `TranscriptTab` may share a common underlying log source, but must not double-fetch it.
590
+ - If transcript visibility requires a cheap presence signal, an additive `has_transcript` or equivalent metadata field may be introduced.
591
+
592
+ This is a behavioral improvement over the current implementation where all lazy fetches fire simultaneously on mount.
593
+
594
+ New endpoints required by Track B features are listed in §9.2 below.
595
+
596
+ ### 9.2 New API Endpoints (Track B Features)
597
+
598
+ | Method | Path | Returns | Required By |
599
+ | ------ | ---------------------------------- | ------------------------------------------------------- | -------------------------------------------- |
600
+ | GET | `/api/features/[id]/files` | `string[]` (touched file paths) | Collision Radar |
601
+ | GET | `/api/features/[id]/gate-history` | `GateRunEvidence[]` (all past retry runs) | Gate Flakiness Analyzer |
602
+ | GET | `/api/features/[id]/genealogy` | `{ feature_id, revision_of, revision_reason, phase }[]` | Genealogy Tree |
603
+ | GET | `/api/features/[id]/worker-events` | `WorkerEventEntry[]` | Per-Role Performance Cards |
604
+ | GET | `/api/analytics/provider` | `ProviderAnalytics[]` | Usage Burn Chart, Per-Role Performance Cards |
605
+ | GET | `/api/merge-queue` | `MergeQueueEntry[]` | Merge Queue Card |
606
+
607
+ All new endpoints follow the existing `{ ok, data/error }` envelope. They are additive — no existing endpoint shape changes.
608
+
609
+ ---
610
+
611
+ ## 10. Accessibility Requirements
612
+
613
+ - All tabs are keyboard navigable: arrow keys move between tabs, Enter activates.
614
+ - Tab panels have `role="tabpanel"` and `aria-labelledby` pointing to the corresponding tab.
615
+ - The pinned action strip buttons have descriptive `aria-label` attributes (e.g., `aria-label="Approve feature for merge"`).
616
+ - Phase badges use `role="status"` and `aria-label="Phase: building"` (text, not color alone).
617
+ - Hero time-in-phase uses `aria-live="polite"` for 30-second updates.
618
+ - All interactive elements are reachable and operable with keyboard alone.
619
+ - Sticky sidebars, sticky action regions, and mobile overlays must not create keyboard traps or hidden focus targets.
620
+ - Long transcript/log content, diagnosis expanders, and command surfaces must preserve visible focus treatment in the light theme.
621
+
622
+ ---
623
+
624
+ ## 11. Risks, Side Effects, and Tradeoffs
625
+
626
+ ### 11.1 Known Side Effects To Manage
627
+
628
+ - Tabs improve scanability but reduce "single-scroll discoverability." Default-tab selection and in-page cross-links matter more.
629
+ - Lazy loading reduces first-paint cost but introduces first-open latency and asynchronous content pop-in.
630
+ - A sticky sidebar plus sticky pinned actions plus mobile inspector overlays can create nested-scroll and viewport-height bugs on small screens.
631
+ - Moving from the old dark ops-console look to the shared light Aequitas styling improves consistency but reduces some of the ambient severity/high-contrast feel of the previous interface.
632
+ - Advanced transcript rendering increases trust and security risk if raw agent content is treated as safe HTML or safe Markdown without sanitization.
633
+
634
+ ### 11.2 Tradeoffs To Call Out Explicitly
635
+
636
+ - Full replacement of `detail-panel.tsx` and `review-workspace.tsx` is cleaner architecturally, but higher risk than incremental extraction unless parity is tested aggressively.
637
+ - "Existing components unchanged" is aspirational. Several existing panels were designed for the old narrow-column layout and may need adaptation once placed into full-width tabs.
638
+ - A fixed 280px sidebar is simple, but information density must be managed with explicit collapse rules or the "5 second scan" goal will fail.
639
+ - Track B features are valuable, but must not be allowed to delay Track A completion.
640
+
641
+ ---
642
+
643
+ ## 12. Success Criteria
644
+
645
+ | Criterion | How Verified |
646
+ | -------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
647
+ | Operator can determine phase, activity state, and current agent role without scrolling | Manual review of `building` phase screenshot at 1440px |
648
+ | Reviewer can reach Approve/Deny buttons without scrolling for any diff length | Manual review with a 500-line diff feature at 1440px |
649
+ | Wide diff renders without horizontal scrollbar at > 900px viewport | Automated: render DiffViewer in ChangesTab with 120-char lines, assert no overflow |
650
+ | Default tab matches current phase | Unit test: `getDefaultTab(phase)` for all 7 phases |
651
+ | All existing components unchanged (no regressions) | `npm run test` passes at ≥90% thresholds |
652
+ | Lazy fetches fire on tab activation, not page mount | Unit test: mock API calls, assert call counts per tab activation sequence |
653
+ | Responsive: primary flow usable at 360px | Manual check + Vitest snapshot at 360px breakpoint |
654
+ | `deriveHealthDiagnosis()` returns correct severity for all 15 signal types | Unit tests: one test per signal, plus priority-ordering tests (higher severity wins) |
655
+ | `DiagnosisPanel` hidden when feature is healthy | Unit test: render with healthy feature, assert panel absent from DOM |
656
+ | `DiagnosisPanel` shows `output_tail` for GATE_FAILURE primary | Unit test: render with failed gate evidence, assert step name and last output line visible |
657
+ | `DiagnosisPanel` link_tab calls `setActiveTab`, not page navigation | Unit test: click "See Gates & QA", assert tab state updated, no `window.location` change |
658
+ | Secondary causes collapsed by default, expandable | Unit test: render with 3 signals, assert secondary list hidden; click toggle, assert visible |
659
+ | Hero badge severity icon present when diagnosis non-null | Unit test: render blocked feature, assert warning icon in hero badge |
660
+ | STALL_THRESHOLD_MS constant exported and used in diagnosis | Static: import check ensures threshold is not hardcoded inline |
661
+ | Focus view uses shared Aequitas light-theme tokens | Visual regression / snapshot: no dark-panel fallback classes used in new focus components |
662
+ | Track A preserves current review workspace capabilities before retirement | Regression tests cover live log stream, send-message flow, session status, raw output access, and mobile inspector availability |
663
+ | Zero ESLint warnings | `npm run lint` |
664
+ | TypeScript strict mode passes | `npm run typecheck` |
665
+
666
+ ---
667
+
668
+ ## 13. Migration Path
669
+
670
+ ### Track A: Core Focus View Redesign
671
+
672
+ 1. Create `lib/health-diagnosis.ts` with `deriveHealthDiagnosis()` and all types. Write unit tests first.
673
+ 2. Create `components/focus/` directory with the Track A component files.
674
+ 3. Build `DiagnosisPanel` consuming `deriveHealthDiagnosis()`.
675
+ 4. Build `FocusLayout`, `ContextSidebar`, `HeroBlock`, `TabBar`, and the core tab components.
676
+ 5. Preserve current `review-workspace.tsx` capabilities inside the new tab model before deleting anything.
677
+ 6. Add new CSS classes to `dashboard.module.css` using the shared Aequitas-aligned tokens.
678
+ 7. Update `app/feature/[id]/page.tsx` to render `<FocusLayout>` instead of the current branch.
679
+ 8. Add unit tests for tab logic, pinned action rendering, capability preservation, and lazy fetch gating.
680
+ 9. Delete `detail-panel.tsx` and `review-workspace.tsx` only after parity tests pass.
681
+ 10. Run `npm run build`, `npm run test`, and visual checks at desktop/mobile breakpoints.
682
+
683
+ Do **not** modify `detail-panel.tsx` incrementally. The decomposition is a full replacement. Incremental edits to a 1130-line component introduce more risk than a clean cut.
684
+
685
+ ### Track B: Mission-Control Enhancements
686
+
687
+ 11. Implement new API endpoints (§9.2) in the Next.js route handlers.
688
+ 12. Build Track B pure lib functions first (`collision-radar.ts`, `usage-burn.ts`), then leaf components, then tab integrations.
689
+ 13. Add `CommandPalette` to the root layout (`app/layout.tsx`) so it is available on all pages.
690
+ 14. Wire `CollisionRadar`, `BurnRateChart`, `GenealogyTree`, `AgentRolePerformanceCard`, `MergeQueueCard`, and Track B transcript/scrubber enhancements into the appropriate tabs and sidebar locations.
691
+ 15. Run full test suite and `npm run build`.
692
+
693
+ ---
694
+
695
+ ## 14. Out of Scope
696
+
697
+ - Animated tab transitions.
698
+ - Persisting the user's active tab across navigation (could be added later via localStorage).
699
+ - Redesigning the Board (`/`) view (Merge Queue card appears on focus view only).
700
+ - Changes to the control-plane backend or MCP tool contracts — new endpoints are in the Next.js API layer only.
701
+ - Real-time multi-user collaboration beyond presence indicators.
702
+
703
+ ---
704
+
705
+ ---
706
+
707
+ # Track B: Mission-Control Enhancements
708
+
709
+ The following features extend the focus view beyond its current data surface. They are explicitly Track B deliverables and must not block Track A completion.
710
+
711
+ ---
712
+
713
+ ## §A: Agent Transcript View
714
+
715
+ ### Purpose
716
+
717
+ Surface the actual text output of each agent role (planner, builder, QA) as a readable conversation transcript, not a flat log. This answers the question developers most want answered when watching an AI agent: "what was it thinking?"
718
+
719
+ ### User Job
720
+
721
+ Operator/reviewer wants to understand why the builder agent wrote specific code, why the planner chose a particular approach, or why QA flagged a test — without reading raw log files.
722
+
723
+ ### Data Sources
724
+
725
+ `FeatureDetail.log_entries: AgentLogEntry[]` is already fetched on page load. Each entry has:
726
+
727
+ - `actor` — the agent instance identifier
728
+ - `role` — `'planner' | 'builder' | 'qa' | 'orchestrator'`
729
+ - `text` — the raw text output of that agent turn
730
+ - `timestamp` — ISO string
731
+
732
+ `RawLogFileMeta[]` (new lazy endpoint `GET /api/features/[id]/log-files`) provides metadata for raw log files per role, enabling a "download raw log" link per role group. This fetch is on-demand, not on tab activation.
733
+
734
+ ### Component: `TranscriptTab.tsx`
735
+
736
+ ````
737
+ ┌──────────────────────────────────────────────────────┐
738
+ │ TRANSCRIPT │
739
+ │ │
740
+ │ [All] [Planner] [Builder] [QA] [Orchestrator] │ ← role filter pills
741
+ │ │
742
+ │ ┌──────────────────────────────────────┐ │
743
+ │ │ 🟦 PLANNER · 14:03:21 │ ↓ raw log │
744
+ │ │ │ │
745
+ │ │ I'll break this into 3 steps: │ │
746
+ │ │ 1. Add the route handler │ │
747
+ │ │ 2. Update the schema │ │
748
+ │ │ 3. Write tests for edge cases │ │
749
+ │ └──────────────────────────────────────┘ │
750
+ │ │
751
+ │ ┌──────────────────────────────────────┐ │
752
+ │ │ 🟧 BUILDER · 14:05:44 │ ↓ raw log │
753
+ │ │ │ │
754
+ │ │ ```typescript │ │
755
+ │ │ export async function handler() { │ ← syntax │
756
+ │ │ ... │ highlighted│
757
+ │ │ } │ │
758
+ │ │ ``` │ │
759
+ │ └──────────────────────────────────────┘ │
760
+ └──────────────────────────────────────────────────────┘
761
+ ````
762
+
763
+ **Rendering rules:**
764
+
765
+ - Entries are grouped into consecutive same-role "turns." A new bubble starts when the role changes.
766
+ - Each bubble has a role-colored left border (using phase color variables: planner=blue, builder=orange, qa=gold, orchestrator=muted).
767
+ - Text is rendered as Markdown. Code fences (` ``` `) are syntax-highlighted using the same Monaco tokenizer already available in the project (no additional dependency).
768
+ - Long turns (> 40 lines) are collapsed to 20 lines with a "Show N more lines" inline toggle.
769
+ - Role filter pills filter the visible turns by role. Default: All.
770
+ - Each role group header has a "↓ raw log" link that triggers a lazy fetch of `RawLogFileMeta` for that role and initiates a file download.
771
+ - If `log_entries` is empty, a placeholder is shown: "No transcript available — logs are written once the agent completes its first turn."
772
+
773
+ ### Tab Placement
774
+
775
+ `transcript` tab. Visible when `log_entries.length > 0`. Not a default tab for any phase — users navigate to it deliberately.
776
+
777
+ ### Implementation Notes
778
+
779
+ - No new API endpoint required for the transcript itself. `log_entries` is in `FeatureDetail`.
780
+ - The `RawLogFileMeta` endpoint is optional and fetched only on "↓ raw log" click, never eagerly.
781
+ - Markdown rendering: use an existing lightweight parser (e.g., `marked` or similar) — check if one is already in `package.json` before adding a dependency.
782
+
783
+ ---
784
+
785
+ ## §B: Code Evolution Scrubber ("Time Machine")
786
+
787
+ ### Purpose
788
+
789
+ Let the user scrub through the evolution of the codebase checkpoint-by-checkpoint, watching the diff update as they move through time. Transforms the static diff into an interactive story of how the code was written.
790
+
791
+ ### User Job
792
+
793
+ Operator wants to understand the sequence of decisions the builder made, or find the exact checkpoint where a specific change was introduced. Currently requires manually selecting from a dropdown and waiting for a fetch each time.
794
+
795
+ ### Data Sources
796
+
797
+ `FeatureDetail.checkpoints: FeatureCheckpoint[]` — already available. Each checkpoint has `diff_snapshot: string` (the full diff at that point in time), `timestamp`, `files_changed[]`, `validation_status`, and `violations[]`.
798
+
799
+ No new API endpoint required for the basic scrubber. `diff_snapshot` is already on the checkpoint object.
800
+
801
+ For the advanced "Play" mode, diffs are pre-loaded from `checkpoint.diff_snapshot` — no per-step network requests needed.
802
+
803
+ ### Component: `CheckpointScrubber.tsx`
804
+
805
+ Placed inside `RuntimeTab.tsx`, replacing the current dropdown-based checkpoint selector.
806
+
807
+ ```
808
+ ┌──────────────────────────────────────────────────────────┐
809
+ │ CODE EVOLUTION · 12 checkpoints │
810
+ │ │
811
+ │ ◀ ▶ ●━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━○ [Play ▷] │
812
+ │ cp-001 cp-006 cp-012 │
813
+ │ 14:01 14:22 15:03 │
814
+ │ │
815
+ │ Checkpoint 6 of 12 · 14:22:18 │
816
+ │ ✓ valid · 4 files changed │
817
+ │ │
818
+ │ ┌────────────────────────────────────────────────────┐ │
819
+ │ │ [Diff content renders here at full width] │ │
820
+ │ └────────────────────────────────────────────────────┘ │
821
+ │ │
822
+ │ File filter: [All files ▾] │
823
+ └──────────────────────────────────────────────────────────┘
824
+ ```
825
+
826
+ **Interaction:**
827
+
828
+ - **Scrubber slider:** `<input type="range">` mapped to checkpoint index. Moving it updates the displayed diff instantly (all diffs are already in memory from `checkpoints[]`).
829
+ - **◀ / ▶ buttons:** Step one checkpoint backward/forward.
830
+ - **Play ▷:** Auto-advances one checkpoint per 1.2 seconds. Button toggles to "Pause ⏸" while playing.
831
+ - **Checkpoint metadata strip:** Shows checkpoint ID, timestamp, validation status badge, files-changed count for the currently-selected checkpoint.
832
+ - **Violations inline:** If `violations.length > 0`, a red banner appears below the metadata strip listing them.
833
+ - **File filter dropdown:** Filters the rendered diff to a single file path from `files_changed[]`. "All files" is the default.
834
+ - Diff is rendered by `DiffViewer` (existing component), passed the `diff_snapshot` of the selected checkpoint.
835
+
836
+ **Threshold:** Only rendered when `checkpoints.length >= 2`. With 0–1 checkpoints, the existing single-snapshot view is shown (no scrubber).
837
+
838
+ ---
839
+
840
+ ## §C: File Collision Radar
841
+
842
+ ### Purpose
843
+
844
+ Show the operator which files this feature is touching and highlight where other concurrently-active features are editing the same paths — before a merge conflict actually occurs. This is an early warning system unique to a multi-agent orchestrator dashboard.
845
+
846
+ ### User Job
847
+
848
+ Operator running multiple parallel features wants to know which ones are on a collision course before they hit a merge conflict that blocks the queue.
849
+
850
+ ### Data Sources
851
+
852
+ - `GET /api/features/[id]/files` → `string[]` — list of file paths touched by this feature (derived server-side from the feature's diff; trivial to compute).
853
+ - `DashboardStatusPayload.features: FeatureSummary[]` — already fetched on page load; provides the list of all active feature IDs.
854
+ - For each other active feature: `GET /api/features/[otherId]/files` → `string[]` — fetched lazily on Collision Radar tab activation, in parallel for all active features. Results are cached in component state for the session.
855
+
856
+ ### Pure Function: `lib/collision-radar.ts`
857
+
858
+ ```typescript
859
+ export interface CollisionEntry {
860
+ path: string;
861
+ depth: number; // directory depth (0 = root, 1 = src/, etc.)
862
+ competing_features: string[]; // other feature IDs touching this path
863
+ risk: 'high' | 'medium' | 'low';
864
+ }
865
+
866
+ export function deriveCollisionRisk(
867
+ thisFeatureFiles: string[],
868
+ otherFeatures: Record<string, string[]>, // featureId → file list
869
+ ): CollisionEntry[];
870
+ ```
871
+
872
+ Risk scoring:
873
+
874
+ - `high` — exact file match with ≥1 other active feature
875
+ - `medium` — same directory (one level up) with ≥1 other active feature
876
+ - `low` — same top-level package/module with ≥1 other active feature
877
+
878
+ ### Component: `CollisionRadar.tsx`
879
+
880
+ Placed in the **Overview tab**, below Verification Signals. Hidden when no collisions are detected (returns empty array from `deriveCollisionRisk()`).
881
+
882
+ ```
883
+ ┌───────────────────────────────────────────────────────────┐
884
+ │ FILE COLLISION RADAR │
885
+ │ 2 high-risk · 3 medium-risk conflicts detected │
886
+ │ │
887
+ │ src/ │
888
+ │ auth/ │
889
+ │ ▓▓▓▓ login.ts HIGH · feat/auth-tokens │ ← red
890
+ │ ▒▒▒▒ session.ts MED · feat/db-schema │ ← amber
891
+ │ api/ │
892
+ │ ░░░░ routes.ts LOW · feat/route-cleanup │ ← muted
893
+ │ │
894
+ │ [Show all N files ▾] │
895
+ └───────────────────────────────────────────────────────────┘
896
+ ```
897
+
898
+ - Renders as an indented file tree (not a treemap — simpler, more readable at typical file counts).
899
+ - Each file shows: path, risk badge, competing feature IDs as links to `/feature/{id}`.
900
+ - Only `high` and `medium` entries shown by default. "Show all N files" toggle reveals `low`.
901
+ - If no active features share files: panel is hidden entirely.
902
+ - Loading state: shows skeleton rows while parallel file-list fetches complete.
903
+
904
+ ---
905
+
906
+ ## §D: Predictive Token Usage Burn Chart
907
+
908
+ ### Purpose
909
+
910
+ Answer "how much token usage will this feature consume in total, and is it on track?" Dollar cost is secondary and only shown when an optional token-to-dollar conversion is configured in `policy.yaml`.
911
+
912
+ ### User Job
913
+
914
+ Operator managing a token budget wants to know before a feature exceeds its limit. Team lead wants to understand usage variance across features. If a dollar conversion is configured, the same panel may also show estimated dollar impact as a derived secondary metric.
915
+
916
+ ### Data Sources
917
+
918
+ - `FeatureDetail.cost: CostSummary` — current usage (`tokens_used`, optional `estimated_cost_usd`, `recorded_at`)
919
+ - `WorkerEventEntry[]` from `GET /api/features/[id]/worker-events` — per-iteration timing and request counts, enabling a usage-over-time curve
920
+ - `ProviderAnalytics[]` from `GET /api/analytics/provider` — historical `avg_tokens_used` and `avg_duration_ms` per provider/model, used as the projection baseline
921
+ - Budget policy from existing `GET /api/policy/budget`, which should expose `per_feature_limit_tokens` and optional `token_cost_conversion`
922
+ - Optional token-to-dollar conversion from `policy.yaml`, exposed via the policy endpoint when configured
923
+
924
+ ### Policy Configuration
925
+
926
+ Primary budgeting is token-based.
927
+
928
+ `policy.yaml` may optionally define:
929
+
930
+ ```yaml
931
+ budget:
932
+ per_feature_limit_tokens: 250000
933
+ token_cost_conversion:
934
+ usd_per_1k_tokens: 0.35
935
+ ```
936
+
937
+ Rules:
938
+
939
+ - `per_feature_limit_tokens` is the primary budget threshold used by the focus view.
940
+ - `token_cost_conversion` is optional.
941
+ - If `token_cost_conversion` is absent, the UI shows token usage only and does not invent or require dollar estimates.
942
+ - If `token_cost_conversion` is present, the UI may show derived USD as a secondary line or tooltip.
943
+ - If both token and dollar limits are present, token limit remains the primary budget bar and enforcement visualization; dollar values remain informational unless policy explicitly says otherwise.
944
+
945
+ ### Pure Function: `lib/usage-burn.ts`
946
+
947
+ ```typescript
948
+ export interface UsageBurnProjection {
949
+ current_tokens_used: number;
950
+ projected_final_tokens: number;
951
+ projected_completion_at: string | null; // ISO timestamp estimate
952
+ budget_limit_tokens: number | null;
953
+ will_exceed_budget: boolean;
954
+ confidence: 'high' | 'medium' | 'low'; // based on data availability
955
+ usage_points: { timestamp: string; tokens_used: number }[]; // historical curve
956
+ derived_usd?: {
957
+ current_estimated_usd: number;
958
+ projected_final_estimated_usd: number;
959
+ usd_per_1k_tokens: number;
960
+ } | null;
961
+ }
962
+
963
+ export function projectUsageBurnRate(
964
+ cost: CostSummary,
965
+ workerEvents: WorkerEventEntry[],
966
+ providerBaseline: ProviderAnalytics | null,
967
+ budgetLimitTokens: number | null,
968
+ tokenCostConversion: { usd_per_1k_tokens: number } | null,
969
+ phase: string,
970
+ ): UsageBurnProjection;
971
+ ```
972
+
973
+ Confidence is `high` when `workerEvents.length >= 5`, `medium` when 2–4, `low` when < 2 (falls back to provider baseline only).
974
+
975
+ ### Component: `UsageBurnChart.tsx`
976
+
977
+ Placed in the **sidebar usage panel** — replaces the existing `FeatureCostPanel` with an expanded version. Basic token totals remain; derived dollar values are secondary and only rendered when conversion is configured. The chart appears below them, collapsed by default.
978
+
979
+ ```
980
+ ┌────────────────────────────────┐
981
+ │ USAGE │
982
+ │ 42k of 200k tokens (21%) │
983
+ │ ████░░░░░░░░░░░░ budget bar │
984
+ │ ≈ $0.42 of ≈ $2.00 est. │ ← optional, only if conversion configured
985
+ │ │
986
+ │ ▼ Projection │ ← expand toggle
987
+ │ ····· ────────────────────── │
988
+ │ ↑ now ↑ projected │
989
+ │ Projected final: ~180k tokens │
990
+ │ Projected est.: ~$1.80 │ ← optional, only if conversion configured
991
+ │ Est. completion: ~47 min │
992
+ │ ⚠ Trending 1.4× historical avg│
993
+ └────────────────────────────────┘
994
+ ```
995
+
996
+ - Sparkline chart: x-axis = time (from `usage_points`), y-axis = cumulative tokens used. A dashed projection line extends from the current point to the estimated final usage.
997
+ - Budget threshold rendered against token usage.
998
+ - `will_exceed_budget === true` → budget bar turns red, warning badge shown.
999
+ - If `confidence === 'low'`: projection shown with a disclaimer: "Estimate based on provider average — insufficient data for this run."
1000
+ - If token-to-dollar conversion exists, render derived USD as a secondary label only. It must never replace the token metric as the primary budget visualization.
1001
+ - Chart rendered with a minimal SVG (no chart library dependency; simple polyline).
1002
+
1003
+ ---
1004
+
1005
+ ## §E: Feature Genealogy Tree
1006
+
1007
+ ### Purpose
1008
+
1009
+ Show the complete revision history of a feature — parent revisions, the reasons they were abandoned, and which succeeded — as a visual lineage tree. This is a novel artifact of AI-driven development with no human-workflow equivalent.
1010
+
1011
+ ### User Job
1012
+
1013
+ Reviewer or team lead wants to understand how many attempts it took to produce this feature and why previous versions failed, without reading through a flat history log.
1014
+
1015
+ ### Data Sources
1016
+
1017
+ `GET /api/features/[id]/genealogy` → `GenealogyNode[]`:
1018
+
1019
+ ```typescript
1020
+ interface GenealogyNode {
1021
+ feature_id: string;
1022
+ phase: string;
1023
+ status: string;
1024
+ revision_of: string | null;
1025
+ revision_reason: string | null;
1026
+ plan_version: number;
1027
+ last_updated: string;
1028
+ }
1029
+ ```
1030
+
1031
+ Server derives this by traversing `revision_of` links across the features index. The response is a flat array; the client builds the tree structure.
1032
+
1033
+ ### Component: `GenealogyTree.tsx`
1034
+
1035
+ Placed in **Overview tab**, collapsed by default. Not shown when `revision_of === null` and no other features reference this feature's ID as their `revision_of`.
1036
+
1037
+ ```
1038
+ ┌───────────────────────────────────────────────────────────┐
1039
+ │ REVISION HISTORY · 3 attempts │
1040
+ │ │
1041
+ │ feat/my-feature [v1] ──(blocked: schema mismatch)──┐ │
1042
+ │ ↓ │
1043
+ │ feat/my-feature [v2] ──(blocked: gate failure)─────┐ │
1044
+ │ ↓ │
1045
+ │ feat/my-feature [v3] ← YOU ARE HERE │
1046
+ │ [ready_to_merge] │
1047
+ └───────────────────────────────────────────────────────────┘
1048
+ ```
1049
+
1050
+ - Each node is a pill: feature ID + plan version + phase badge.
1051
+ - Edges are labeled with `revision_reason` (truncated to 40 chars with tooltip).
1052
+ - Current feature is highlighted.
1053
+ - Clicking a past-revision node navigates to `/feature/{revision_id}`.
1054
+ - If `revision_of === null` and no children: component not rendered (hidden).
1055
+
1056
+ ---
1057
+
1058
+ ## §F: Gate Flakiness Analyzer
1059
+
1060
+ ### Purpose
1061
+
1062
+ Distinguish between tests that consistently fail (systemic code problem) and tests that flip between pass/fail across retries (flaky infrastructure). Currently impossible to see from a single gate run snapshot.
1063
+
1064
+ ### User Job
1065
+
1066
+ Operator sees `gate_retry_count = 4` and needs to know: should I fix the code or fix the test infrastructure?
1067
+
1068
+ ### Data Sources
1069
+
1070
+ `GET /api/features/[id]/gate-history` → `GateRunEvidence[]` — all past gate run attempts for this feature in chronological order. Server reads all gate evidence files from `.aop/features/{id}/evidence/`.
1071
+
1072
+ ### Component: `GateFlakinessSummary.tsx`
1073
+
1074
+ Placed in **Gates & QA tab**, above `GateResults`. Visible only when `gate_retry_count >= 1`.
1075
+
1076
+ ```
1077
+ ┌───────────────────────────────────────────────────────────┐
1078
+ │ GATE HISTORY · 4 attempts │
1079
+ │ │
1080
+ │ Step Runs Pass Flakiness │
1081
+ │ ─────────────────────────────────────────────────────── │
1082
+ │ npm run lint ●●●● 4/4 0% ✓ stable │
1083
+ │ npm run typecheck ●●●● 4/4 0% ✓ stable │
1084
+ │ npm run test:coverage ●✗●✗ 2/4 50% ⚠ flaky │
1085
+ │ npm run validate:arch ✗✗✗✗ 0/4 0% ✗ failing │
1086
+ │ │
1087
+ │ ● = pass ✗ = fail (chronological, left to right) │
1088
+ └───────────────────────────────────────────────────────────┘
1089
+ ```
1090
+
1091
+ - Each row shows: step name, mini pass/fail sparkline (colored dots, chronological), pass count/total, flakiness percentage.
1092
+ - Flakiness % = (number of outcome flips / total runs − 1). A step that goes ●✗●✗ flips 3 times out of 3 transitions = 100% flaky.
1093
+ - Labels: `✓ stable` (0% flaky, all pass), `⚠ flaky` (> 25% flaky), `✗ failing` (0% pass across all runs), `⚡ recovering` (last run passes, earlier runs fail).
1094
+ - Clicking a step row expands `output_tail` from that step's most recent failure inline.
1095
+
1096
+ ---
1097
+
1098
+ ## §G: Diff Annotation for Reviewers
1099
+
1100
+ ### Purpose
1101
+
1102
+ Allow reviewers to leave inline comments on specific diff hunks, exactly as in GitHub code review. Eliminates the current constraint of writing all review feedback into a single textarea with no connection to the code being discussed.
1103
+
1104
+ ### User Job
1105
+
1106
+ Reviewer at `ready_to_merge` wants to say "this line specifically needs to handle the null case" — attached to the actual line, not floating in a text box.
1107
+
1108
+ ### Data Sources
1109
+
1110
+ Client-side only: annotations are accumulated in component state as the reviewer comments on hunks, then bundled with the `review.request_changes` action payload.
1111
+
1112
+ New type (client-side only):
1113
+
1114
+ ```typescript
1115
+ interface DiffAnnotation {
1116
+ file_path: string;
1117
+ hunk_header: string; // diff hunk header line (e.g., "@@ -12,4 +12,6 @@")
1118
+ line_number: number; // line number in the modified file
1119
+ comment: string;
1120
+ }
1121
+ ```
1122
+
1123
+ The `review.request_changes` action body gains an optional `annotations: DiffAnnotation[]` field. The control-plane receives this as part of the existing review action tool call — no schema changes are needed if the annotations are embedded in the review message as structured text (see implementation note below).
1124
+
1125
+ ### Component: `AnnotatableDiffViewer.tsx`
1126
+
1127
+ Replaces `DiffViewer` in `ChangesTab.tsx` for `ready_to_merge` and `qa` phases. For other phases, `DiffViewer` continues to be used unchanged.
1128
+
1129
+ ```
1130
+ ┌──────────────────────────────────────────────────────────┐
1131
+ │ src/auth/login.ts │
1132
+ │ ─────────────────────────────────────────────────────── │
1133
+ │ @@ -12,4 +12,6 @@ [+ Comment] │ ← hover reveals
1134
+ │ function login(user: string) { │
1135
+ │ + if (!user) throw new Error('missing user'); [+] │ ← line-level button
1136
+ │ return db.find(user); │
1137
+ │ } │
1138
+ │ │
1139
+ │ ┌─────────────────────────────────────┐ │
1140
+ │ │ 💬 Your comment on line 14: │ │
1141
+ │ │ [What happens if user is empty str?]│ │
1142
+ │ │ [Save] [Cancel] │ │
1143
+ │ └─────────────────────────────────────┘ │
1144
+ │ │
1145
+ │ 📎 3 annotations attached to this review │
1146
+ └──────────────────────────────────────────────────────────┘
1147
+ ```
1148
+
1149
+ - Each diff line gains a `[+]` comment button on hover (not shown by default to avoid visual noise).
1150
+ - Clicking `[+]` opens an inline comment popover below that line.
1151
+ - Saved annotations accumulate in state and are shown as a count badge at the top of the diff: "📎 N annotations."
1152
+ - When the reviewer submits via `RequestChanges`, the annotations are serialized and prepended to the review message in a structured format:
1153
+
1154
+ ```
1155
+ [ANNOTATIONS]
1156
+ src/auth/login.ts:14 — What happens if user is empty str?
1157
+ src/auth/login.ts:22 — This should be async
1158
+ [/ANNOTATIONS]
1159
+
1160
+ {reviewer's free-text message}
1161
+ ```
1162
+
1163
+ This requires no backend schema changes — the control-plane receives it as message text.
1164
+
1165
+ **Implementation note:** The `AnnotatableDiffViewer` uses `diff2html` for rendering (same as existing `DiffViewer`) with a thin React overlay for the comment buttons. Monaco Editor is not required for this feature.
1166
+
1167
+ ---
1168
+
1169
+ ## §H: Command Palette
1170
+
1171
+ ### Purpose
1172
+
1173
+ A keyboard-driven global overlay (Cmd+K / Ctrl+K) that lets power operators navigate between features, switch tabs, and trigger actions without using the mouse.
1174
+
1175
+ ### User Job
1176
+
1177
+ Operator managing 15 concurrent features wants to jump to a specific feature, check its gate status, and approve it — without clicking through the board each time.
1178
+
1179
+ ### Data Sources
1180
+
1181
+ - `DashboardStatusPayload.features: FeatureSummary[]` — all active feature IDs and phases (already fetched).
1182
+ - Current tab state (from `FocusLayout` context) — for "Switch to [tab]" commands.
1183
+
1184
+ No new API endpoints required.
1185
+
1186
+ ### Component: `CommandPalette.tsx`
1187
+
1188
+ Mounted at the root layout level (`app/layout.tsx`) so it is available on every page in the dashboard.
1189
+
1190
+ ```
1191
+ ┌─────────────────────────────────────────────────────┐
1192
+ │ ⌘K > feat/my-feature_ │ ← fuzzy search input
1193
+ │ ─────────────────────────────────────────────────── │
1194
+ │ FEATURES │
1195
+ │ ● feat/auth-tokens building → Open │
1196
+ │ ● feat/db-schema qa → Open │
1197
+ │ ◎ feat/my-feature ready → Open │
1198
+ │ │
1199
+ │ ACTIONS (current feature) │
1200
+ │ Approve feature ↵ │
1201
+ │ Deny feature │
1202
+ │ Request Changes │
1203
+ │ │
1204
+ │ NAVIGATION │
1205
+ │ Switch to Changes tab │
1206
+ │ Switch to Gates & QA tab │
1207
+ │ Go to Board │
1208
+ └─────────────────────────────────────────────────────┘
1209
+ ```
1210
+
1211
+ **Keyboard behaviour:**
1212
+
1213
+ - `Cmd+K` / `Ctrl+K` — open palette
1214
+ - `Escape` — close
1215
+ - `↑` / `↓` — move selection
1216
+ - `Enter` — execute selected command
1217
+ - Typing filters all sections by fuzzy match against feature IDs, command names, and tab labels
1218
+
1219
+ **Command categories:**
1220
+
1221
+ 1. **Features** — all active features from `DashboardStatusPayload.features`, fuzzy-matched against input. Selecting navigates to `/feature/{id}`.
1222
+ 2. **Actions** — phase-appropriate actions for the currently-viewed feature (Approve, Deny, Request Changes, Retry, Send Message). Only shown when on a `/feature/{id}` page. Executing an action calls the same handler as the button in the sidebar.
1223
+ 3. **Navigation** — Switch to [tab name] for each visible tab on the current feature; Go to Board.
1224
+
1225
+ **Implementation:**
1226
+
1227
+ - Global `keydown` listener registered in `useEffect` at layout level, cleaned up on unmount.
1228
+ - Fuzzy matching: simple substring scoring (no dependency — implement inline, < 30 lines).
1229
+ - Palette is a `position: fixed` overlay with a backdrop. Focus is trapped inside while open (`Tab` cycles through results).
1230
+ - `aria-role="combobox"` with `aria-expanded`, `aria-activedescendant` for screen reader compatibility.
1231
+
1232
+ ---
1233
+
1234
+ ## §I: Per-Role Agent Performance Cards
1235
+
1236
+ ### Purpose
1237
+
1238
+ Show how each agent role (planner, builder, QA) performed in this run compared to historical averages for the same provider/model — catching anomalous runs before they become failures.
1239
+
1240
+ ### User Job
1241
+
1242
+ Operator sees a feature that has been in the `building` phase for 40 minutes and wants to know: is this normal for this provider, or is the builder stuck?
1243
+
1244
+ ### Data Sources
1245
+
1246
+ - `GET /api/features/[id]/worker-events` → `WorkerEventEntry[]` — per-iteration timing and counts, filterable by `role`.
1247
+ - `GET /api/analytics/provider` → `ProviderAnalytics[]` — historical averages by provider + model.
1248
+ - `FeatureSummary.cluster: AgentSessionCluster` — session IDs per role.
1249
+
1250
+ ### Component: `AgentRolePerformanceCard.tsx`
1251
+
1252
+ Three instances rendered in **Overview tab** (one per role: planner, builder, qa). Each card is compact — collapsed by default, expandable.
1253
+
1254
+ ```
1255
+ ┌────────────────────────────────────────────────────────┐
1256
+ │ 🟧 BUILDER · claude-sonnet-4-6 │
1257
+ │ ───────────────────────────────────────────────────── │
1258
+ │ Runtime: 12m 04s (avg: 8m 22s) ↑ 1.4× │
1259
+ │ Requests: 47 (avg: 31) ↑ 1.5× │
1260
+ │ Patches: 8 (avg: 4) ↑ 2.0× │
1261
+ │ │
1262
+ │ ████░░░ vs historical average │
1263
+ │ ⚠ Running slower and making more requests than average│
1264
+ └────────────────────────────────────────────────────────┘
1265
+ ```
1266
+
1267
+ - Metrics shown: total elapsed time, total request count, patch count, plan submission count (where relevant per role).
1268
+ - Each metric shows actual value, historical average in parentheses, and a ratio badge.
1269
+ - Ratio badges: `↑ Nx` in amber if > 1.5× average, `↑ Nx` in red if > 2.5× average, `✓` in green if within 0.75–1.25× average.
1270
+ - A subtle horizontal bar chart compares this run to the historical average visually.
1271
+ - Summary sentence: "Running slower and making more requests than average" / "On track" / "Ahead of historical average."
1272
+ - Card is hidden for roles that have not yet started (`role_status === 'ready'`).
1273
+
1274
+ ---
1275
+
1276
+ ## §J: Merge Queue Position
1277
+
1278
+ ### Purpose
1279
+
1280
+ Show where this feature sits in the merge sequence, what is blocking it from merging ahead of other features, and what it is blocking — without navigating to the board.
1281
+
1282
+ ### User Job
1283
+
1284
+ Reviewer approving a `ready_to_merge` feature wants to know: "If I approve this now, when will it actually merge? What's ahead of it?"
1285
+
1286
+ ### Data Sources
1287
+
1288
+ `GET /api/merge-queue` → `MergeQueueEntry[]`:
1289
+
1290
+ ```typescript
1291
+ interface MergeQueueEntry {
1292
+ feature_id: string;
1293
+ position: number; // 1-indexed position in the queue
1294
+ phase: string;
1295
+ estimated_merge_at: string | null;
1296
+ blocked_by: string[]; // feature IDs that must merge first
1297
+ blocks: string[]; // feature IDs waiting on this one
1298
+ lock_holder: boolean; // whether this feature currently holds the merge lock
1299
+ }
1300
+ ```
1301
+
1302
+ Server derives this from `FeaturesIndex.dep_blocked`, `lock_leases`, and the ordered `active` feature list.
1303
+
1304
+ ### Component: `MergeQueueCard.tsx`
1305
+
1306
+ Placed in the **sidebar**, below the PR status card. Visible for all non-`merged` phases. Hidden if queue has only one entry and no dependencies.
1307
+
1308
+ ```
1309
+ ┌────────────────────────────────┐
1310
+ │ MERGE QUEUE · Position #3 │
1311
+ │ │
1312
+ │ ① feat/auth-tokens [rtm] │ ← ahead (links)
1313
+ │ ② feat/db-schema [qa] │
1314
+ │ ③ YOU ARE HERE [rtm] │ ← current feature highlighted
1315
+ │ ④ feat/route-fix [bldg] │ ← behind (dimmed)
1316
+ │ │
1317
+ │ Waiting on: feat/auth-tokens │ ← dep-block if applicable
1318
+ │ Est. merge window: ~2h 15m │ ← based on avg phase durations
1319
+ └────────────────────────────────┘
1320
+ ```
1321
+
1322
+ - Queue positions are rendered as a compact vertical list (max 5 shown; "N more" collapse for longer queues).
1323
+ - Features ahead of current are shown normally; features behind are dimmed.
1324
+ - Current feature is bold with a `YOU ARE HERE` label.
1325
+ - `Waiting on` row appears when `blocked_by` is non-empty.
1326
+ - `Est. merge window` is omitted when `confidence` is too low (insufficient historical data).
1327
+ - Each feature ID in the list is a link to `/feature/{id}`.
1328
+
1329
+ ---
1330
+
1331
+ ## Track B: New API Endpoint Contracts
1332
+
1333
+ All new endpoints follow the existing Next.js API route pattern in `packages/web-dashboard/src/app/api/`. Response envelope: `{ ok: true, data: T } | { ok: false, error: string }`.
1334
+
1335
+ ### `GET /api/features/[id]/files`
1336
+
1337
+ Returns the sorted list of file paths modified by this feature's current diff.
1338
+
1339
+ ```typescript
1340
+ // Response: string[]
1341
+ // e.g. ["src/auth/login.ts", "src/auth/session.ts", "test/auth.spec.ts"]
1342
+ ```
1343
+
1344
+ Implementation: parse the diff from `FeatureDetail.diff` using the same diff parser already used in `aop-client.ts`. Extract `+++ b/<path>` lines. No filesystem access required beyond what already exists.
1345
+
1346
+ ### `GET /api/features/[id]/gate-history`
1347
+
1348
+ Returns all past gate run evidence for this feature, in chronological order.
1349
+
1350
+ ```typescript
1351
+ // Response: GateRunEvidence[]
1352
+ ```
1353
+
1354
+ Implementation: reads all `evidence/gate_run_*.json` files from `.aop/features/{id}/evidence/` and returns them sorted by `finished_at`.
1355
+
1356
+ ### `GET /api/features/[id]/genealogy`
1357
+
1358
+ Returns the revision chain for this feature (ancestors and descendants).
1359
+
1360
+ ```typescript
1361
+ // Response: GenealogyNode[]
1362
+ interface GenealogyNode {
1363
+ feature_id: string;
1364
+ phase: string;
1365
+ status: string;
1366
+ revision_of: string | null;
1367
+ revision_reason: string | null;
1368
+ plan_version: number;
1369
+ last_updated: string;
1370
+ }
1371
+ ```
1372
+
1373
+ Implementation: traverse `revision_of` links from the features index. Maximum depth: 20 (guard against cycles).
1374
+
1375
+ ### `GET /api/features/[id]/worker-events`
1376
+
1377
+ Returns the worker event ledger for this feature.
1378
+
1379
+ ```typescript
1380
+ // Response: WorkerEventEntry[]
1381
+ ```
1382
+
1383
+ Implementation: reads from the existing worker event ledger file (same source as the runtime inspector). Filtered to entries with `feature_id === id`.
1384
+
1385
+ ### `GET /api/analytics/provider`
1386
+
1387
+ Returns historical performance analytics aggregated by provider + model.
1388
+
1389
+ ```typescript
1390
+ // Response: ProviderAnalytics[]
1391
+ ```
1392
+
1393
+ Implementation: aggregates `WorkerEventEntry` data across all features in the index. Can be cached with a 5-minute TTL since this is aggregate historical data.
1394
+
1395
+ ### `GET /api/merge-queue`
1396
+
1397
+ Returns the ordered merge queue with dependency information.
1398
+
1399
+ ```typescript
1400
+ // Response: MergeQueueEntry[]
1401
+ ```
1402
+
1403
+ Implementation: derived from `FeaturesIndex.active`, `dep_blocked`, and `lock_leases`. Order: lock holder first, then dep-unblocked features in index order, then dep-blocked features last.
1404
+
1405
+ ---
1406
+
1407
+ ## Track B: Success Criteria
1408
+
1409
+ | Feature | Criterion | How Verified |
1410
+ | ----------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
1411
+ | Agent Transcript | Entries grouped by role into turns; code fences syntax-highlighted | Unit test: render 10 entries alternating planner/builder, assert 5 bubbles; assert `<code>` block in builder turn |
1412
+ | Agent Transcript | Role filter pills hide turns from other roles | Unit test: select "Planner" filter, assert builder turns absent from DOM |
1413
+ | Code Evolution Scrubber | Slider position updates displayed diff without network request | Unit test: render scrubber with 5 checkpoints, change slider to index 3, assert `DiffViewer` receives `checkpoints[3].diff_snapshot`, assert 0 fetch calls |
1414
+ | Code Evolution Scrubber | Play mode advances one checkpoint per 1.2s | Unit test: mock timers, click Play, advance 2.4s, assert index incremented by 2 |
1415
+ | File Collision Radar | Hidden when no files overlap with other active features | Unit test: `deriveCollisionRisk(thisFiles, {})` returns `[]`; assert panel absent from DOM |
1416
+ | File Collision Radar | High-risk files shown first; low-risk collapsed by default | Unit test: render with 1 high + 2 low risk entries, assert low hidden; click toggle, assert visible |
1417
+ | Usage Burn Chart | `will_exceed_budget === true` turns token budget bar red | Unit test: `projectUsageBurnRate` with projected tokens > token budget, assert red class on bar |
1418
+ | Usage Burn Chart | `confidence === 'low'` shows disclaimer | Unit test: render with 0 worker events, assert disclaimer text present |
1419
+ | Usage Burn Chart | Derived USD hidden when token-to-dollar conversion is not configured | Unit test: render with `tokenCostConversion = null`, assert no dollar labels shown |
1420
+ | Genealogy Tree | Hidden when `revision_of === null` and no children | Unit test: render with isolated feature, assert tree absent |
1421
+ | Genealogy Tree | Nodes link to correct `/feature/{id}` paths | Unit test: click ancestor node, assert navigation to correct URL |
1422
+ | Gate Flakiness | Flakiness % correct for alternating pass/fail pattern | Unit test: 4 runs [pass, fail, pass, fail] = 3 flips / 3 transitions = 100% |
1423
+ | Gate Flakiness | Stable steps labeled `✓ stable`, flaky labeled `⚠ flaky` | Unit test: assert label class for each pattern |
1424
+ | Diff Annotation | Annotations serialized as structured text in review message | Unit test: submit request_changes with 2 annotations, assert message contains `[ANNOTATIONS]` block |
1425
+ | Diff Annotation | `[+]` button only visible on hover | Snapshot test: assert button has `opacity: 0` by default, `opacity: 1` on hover (CSS class) |
1426
+ | Command Palette | Opens on Cmd+K, closes on Escape | Unit test: dispatch `keydown` with metaKey+k, assert palette visible; dispatch Escape, assert hidden |
1427
+ | Command Palette | Feature list filtered by fuzzy match | Unit test: type "auth", assert only features containing "auth" in ID are shown |
1428
+ | Command Palette | Action commands only shown on `/feature/{id}` pages | Unit test: render palette on board page, assert ACTIONS section absent |
1429
+ | Per-Role Cards | Cards hidden for roles with `role_status === 'ready'` | Unit test: render with all roles ready, assert no cards rendered |
1430
+ | Per-Role Cards | Ratio > 2.5× shows red badge | Unit test: `elapsed_ms` = 3× provider average, assert red ratio badge |
1431
+ | Merge Queue | `YOU ARE HERE` label on current feature | Unit test: render queue with current feature at position 3, assert label at index 2 |
1432
+ | Merge Queue | Hidden when queue has one entry and no dependencies | Unit test: render with single-entry queue and `blocked_by: []`, assert card absent |