@yemi33/minions 0.1.2447 → 0.1.2449

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 (315) hide show
  1. package/bin/cli-api-client.js +1 -1
  2. package/bin/install-internal-minions.js +1382 -44
  3. package/bin/install-layout.js +150 -0
  4. package/bin/minions.js +460 -167
  5. package/dashboard/docs/typography.md +65 -12
  6. package/dashboard/js/command-center.js +66 -7
  7. package/dashboard/js/detail-panel.js +36 -0
  8. package/dashboard/js/memory-panel.js +59 -12
  9. package/dashboard/js/qa.js +186 -45
  10. package/dashboard/js/refresh.js +148 -12
  11. package/dashboard/js/render-dispatch.js +3 -4
  12. package/dashboard/js/render-inbox.js +2 -2
  13. package/dashboard/js/render-other.js +3 -3
  14. package/dashboard/js/render-pipelines.js +14 -0
  15. package/dashboard/js/render-plans.js +57 -9
  16. package/dashboard/js/render-prd.js +132 -23
  17. package/dashboard/js/render-prs.js +195 -166
  18. package/dashboard/js/render-schedules.js +63 -3
  19. package/dashboard/js/render-utils.js +3 -3
  20. package/dashboard/js/render-watches.js +19 -3
  21. package/dashboard/js/render-work-items.js +238 -30
  22. package/dashboard/js/settings.js +205 -54
  23. package/dashboard/js/utils.js +51 -1
  24. package/dashboard/pages/home.html +1 -1
  25. package/dashboard/pages/qa.html +1 -16
  26. package/dashboard/pages/work.html +40 -0
  27. package/dashboard/shared/cc-limits.js +79 -0
  28. package/dashboard/shared/pr-filters.js +21 -38
  29. package/dashboard/shared/project-git-summary.js +1 -1
  30. package/dashboard/shared/record-filters.js +169 -0
  31. package/dashboard/shared/watches-source.js +1 -1
  32. package/dashboard/shared/welcome-popup.js +1 -1
  33. package/dashboard/shared/wi-filters.js +302 -0
  34. package/dashboard/slim/body.html +1 -0
  35. package/dashboard/slim/js/command-send.js +26 -0
  36. package/dashboard/slim/js/modals-tiles.js +380 -39
  37. package/dashboard/slim/js/status.js +13 -21
  38. package/dashboard/slim/layout.html +1 -0
  39. package/dashboard/slim/panel-bootstrap.js +6 -2
  40. package/dashboard/slim/styles.css +38 -0
  41. package/dashboard/styles.css +159 -55
  42. package/dashboard-build.js +52 -6
  43. package/dashboard.js +956 -423
  44. package/docs/README.md +11 -6
  45. package/docs/api-errors.md +2 -2
  46. package/docs/architecture-review-2026-07-09.md +1 -1
  47. package/docs/architecture.excalidraw +2 -2
  48. package/docs/auto-discovery.md +18 -9
  49. package/docs/branch-derivation.md +4 -4
  50. package/docs/capture-demos.js +39 -2
  51. package/docs/ci-runner-canary.md +123 -0
  52. package/docs/claude-md-propagation.md +2 -2
  53. package/docs/cloud-agent-dispatch.md +204 -0
  54. package/docs/command-center.md +7 -7
  55. package/docs/completion-reports.md +43 -20
  56. package/docs/constants.md +10 -3
  57. package/docs/constellation-bridge.md +134 -6
  58. package/docs/constellation-style-telemetry.md +4 -4
  59. package/docs/contracts/capability-protocol.v1.json +165 -0
  60. package/docs/cooldown-merge-semantics.md +12 -12
  61. package/docs/copilot-cli-schema.md +7 -7
  62. package/docs/cross-repo-plans.md +10 -10
  63. package/docs/dead-code-audit-retractions.md +5 -5
  64. package/docs/default-branch-ci.md +173 -0
  65. package/docs/deprecated.json +31 -31
  66. package/docs/design-inbox-entries-schema.md +3 -3
  67. package/docs/design-language.md +1051 -0
  68. package/docs/design-state-storage.md +11 -11
  69. package/docs/diagnostics-crash-reports.md +9 -9
  70. package/docs/diagnostics-memory.md +5 -5
  71. package/docs/documentation-audit-2026-07-09.md +7 -7
  72. package/docs/engine-restart.md +90 -5
  73. package/docs/harness-mode.md +1 -1
  74. package/docs/internal-install.md +338 -39
  75. package/docs/kb-dedup-duplicate-pair-investigation.md +5 -5
  76. package/docs/kb-pr3223-cascade-archiving.md +1 -1
  77. package/docs/kb-pr696-merge-conflict-docs.md +6 -6
  78. package/docs/kb-sweep.md +35 -35
  79. package/docs/keep-processes.md +1 -1
  80. package/docs/live-checkout-mode.md +30 -30
  81. package/docs/managed-spawn.md +18 -14
  82. package/docs/named-agents.md +7 -7
  83. package/docs/plan-lifecycle.md +69 -2
  84. package/docs/pr-author-identity.md +114 -0
  85. package/docs/pr-auto-fix-dispatch.md +19 -4
  86. package/docs/pr-comment-followup.md +6 -6
  87. package/docs/pr-review-fix-loop.md +59 -10
  88. package/docs/process-termination.md +40 -0
  89. package/docs/proposals/repo-pool-for-live-checkout.md +13 -13
  90. package/docs/qa-runbook-lifecycle.md +367 -17
  91. package/docs/qa-runbooks.md +3 -3
  92. package/docs/rfc-completion-json.md +18 -18
  93. package/docs/runtime-adapters.md +26 -21
  94. package/docs/security.md +6 -6
  95. package/docs/self-improvement.md +4 -4
  96. package/docs/shared-lifecycle-module-map.md +473 -472
  97. package/docs/skills.md +52 -3
  98. package/docs/slim-ux/concepts.md +121 -116
  99. package/docs/specs/agent-configurability.md +18 -18
  100. package/docs/specs/agent-rename.md +18 -18
  101. package/docs/team-memory.md +38 -21
  102. package/docs/timeouts-and-liveness.md +118 -10
  103. package/docs/tutorials/01-install-and-connect.md +1 -1
  104. package/docs/watches.md +40 -39
  105. package/docs/workspace-manifests.md +4 -4
  106. package/docs/worktree-lifecycle.md +293 -14
  107. package/engine/README.md +46 -0
  108. package/engine/{ado-comment.js → ado/comment.js} +8 -8
  109. package/engine/{ado-git-auth.js → ado/git-auth.js} +4 -4
  110. package/engine/{ado.js → ado/index.js} +417 -63
  111. package/engine/{ado-status.js → ado/status.js} +6 -8
  112. package/engine/{ado-token.js → ado/token.js} +1 -1
  113. package/engine/{acp-transport.js → agents/acp-transport.js} +62 -22
  114. package/engine/{agent-worker-pool.js → agents/agent-worker-pool.js} +17 -8
  115. package/engine/{cc-worker-pool.js → agents/cc-worker-pool.js} +16 -6
  116. package/engine/{claude-md-context.js → agents/claude-md-context.js} +5 -5
  117. package/engine/{harness-context.js → agents/harness-context.js} +5 -5
  118. package/engine/{harness.js → agents/harness.js} +3 -3
  119. package/engine/{llm.js → agents/llm.js} +18 -14
  120. package/engine/{model-discovery.js → agents/model-discovery.js} +2 -2
  121. package/engine/{playbook.js → agents/playbook.js} +155 -22
  122. package/engine/{pooled-agent-process.js → agents/pooled-agent-process.js} +14 -12
  123. package/engine/{preflight.js → agents/preflight.js} +29 -10
  124. package/engine/{spawn-agent.js → agents/spawn-agent.js} +25 -14
  125. package/engine/{spawn-phase-watchdog.js → agents/spawn-phase-watchdog.js} +16 -7
  126. package/engine/{steering.js → agents/steering.js} +5 -5
  127. package/engine/{tools-inventory.js → agents/tools-inventory.js} +2 -2
  128. package/engine/{agent-api-validation.js → api/agent-api-validation.js} +2 -2
  129. package/engine/{api-validation.js → api/api-validation.js} +1 -1
  130. package/engine/api/bridge.js +787 -0
  131. package/engine/{cc-api-validation.js → api/cc-api-validation.js} +1 -1
  132. package/engine/api/companion.js +560 -0
  133. package/engine/{content-api-validation.js → api/content-api-validation.js} +2 -2
  134. package/engine/{pr-issue-validation.js → api/pr-issue-validation.js} +33 -6
  135. package/engine/{settings-validation.js → api/settings-validation.js} +32 -4
  136. package/engine/api-contracts/agent-content.js +4 -4
  137. package/engine/api-contracts/capability-manifest.js +236 -0
  138. package/engine/api-contracts/capability-protocol.js +333 -0
  139. package/engine/api-contracts/cc-ops.js +1 -1
  140. package/engine/api-contracts/config-runtime.js +5 -0
  141. package/engine/api-contracts/core.js +28 -1
  142. package/engine/api-contracts/index.js +100 -0
  143. package/engine/api-contracts/orchestration.js +18 -5
  144. package/engine/api-contracts/pull-requests.js +37 -6
  145. package/engine/api-contracts/qa-process.js +29 -6
  146. package/engine/api-contracts/work-plan-prd.js +21 -1
  147. package/engine/cloud/contract.js +212 -0
  148. package/engine/cloud/index.js +159 -0
  149. package/engine/{execution-model.js → core/execution-model.js} +1 -1
  150. package/engine/{features.js → core/features.js} +4 -4
  151. package/engine/{operator-identity.js → core/operator-identity.js} +1 -1
  152. package/engine/{queries.js → core/queries.js} +201 -36
  153. package/engine/{safe-expr.js → core/safe-expr.js} +1 -1
  154. package/engine/{shared.js → core/shared.js} +1637 -175
  155. package/engine/{stdio-timestamps.js → core/stdio-timestamps.js} +1 -1
  156. package/engine/{untrusted-fence.js → core/untrusted-fence.js} +3 -3
  157. package/engine/db/index.js +11 -2
  158. package/engine/db/migrations/002-dispatches.js +3 -3
  159. package/engine/db/migrations/003-work-items.js +1 -1
  160. package/engine/db/migrations/004-pull-requests.js +1 -1
  161. package/engine/db/migrations/006-metrics.js +1 -1
  162. package/engine/db/migrations/007-watches.js +2 -2
  163. package/engine/db/migrations/008-small-state.js +1 -1
  164. package/engine/db/migrations/009-qa.js +1 -1
  165. package/engine/db/migrations/010-pr-links.js +1 -1
  166. package/engine/db/migrations/011-remaining-state.js +1 -1
  167. package/engine/db/migrations/012-steering-deliveries.js +2 -2
  168. package/engine/db/migrations/013-backfill-broken-note-links.js +1 -1
  169. package/engine/db/migrations/014-pr-fix-target-prefs.js +2 -2
  170. package/engine/db/migrations/015-plans-prds.js +0 -0
  171. package/engine/db/migrations/018-sql-only-cutover.js +2 -2
  172. package/engine/db/migrations/021-archived-work-items.js +1 -1
  173. package/engine/db/migrations/022-global-cc-session.js +1 -1
  174. package/engine/db/migrations/023-engine-state.js +1 -1
  175. package/engine/db/migrations/025-malformed-work-item-phantoms.js +1 -1
  176. package/engine/db/migrations/027-review-learning-lifecycle.js +1 -1
  177. package/engine/db/migrations/029-repair-reused-versions.js +20 -0
  178. package/engine/db/migrations/031-pr-author-identity.js +137 -0
  179. package/engine/{consolidation.js → memory/consolidation.js} +6 -6
  180. package/engine/{kb-sweep-runner.js → memory/kb-sweep-runner.js} +2 -2
  181. package/engine/{kb-sweep.js → memory/kb-sweep.js} +9 -7
  182. package/engine/{memory-retrieval.js → memory/memory-retrieval.js} +46 -4
  183. package/engine/{memory-store.js → memory/memory-store.js} +3 -3
  184. package/engine/{promotion.js → memory/promotion.js} +3 -3
  185. package/engine/{review-learning-backfill.js → memory/review-learning-backfill.js} +6 -6
  186. package/engine/{review-learning.js → memory/review-learning.js} +10 -5
  187. package/engine/{diagnostics-memory.js → observability/diagnostics-memory.js} +1 -1
  188. package/engine/{logs-store.js → observability/logs-store.js} +5 -5
  189. package/engine/{metrics-store.js → observability/metrics-store.js} +4 -4
  190. package/engine/{check-status.js → operations/check-status.js} +3 -3
  191. package/engine/{cli.js → operations/cli.js} +271 -113
  192. package/engine/{distribution.js → operations/distribution.js} +5 -6
  193. package/engine/{cleanup.js → orchestration/cleanup.js} +72 -45
  194. package/engine/{cooldown.js → orchestration/cooldown.js} +5 -5
  195. package/engine/{dispatch-events.js → orchestration/dispatch-events.js} +2 -2
  196. package/engine/{dispatch.js → orchestration/dispatch.js} +129 -36
  197. package/engine/orchestration/failed-scheduled-cleanup.js +274 -0
  198. package/engine/{lifecycle.js → orchestration/lifecycle.js} +198 -90
  199. package/engine/{meeting.js → orchestration/meeting.js} +6 -16
  200. package/engine/{pipeline.js → orchestration/pipeline.js} +12 -12
  201. package/engine/{pre-dispatch-eval.js → orchestration/pre-dispatch-eval.js} +10 -9
  202. package/engine/{routing.js → orchestration/routing.js} +3 -3
  203. package/engine/{schedule-bootstrap.js → orchestration/schedule-bootstrap.js} +4 -4
  204. package/engine/{scheduler.js → orchestration/scheduler.js} +38 -8
  205. package/engine/{timeout.js → orchestration/timeout.js} +158 -109
  206. package/engine/{db-events.js → persistence/db-events.js} +2 -2
  207. package/engine/{dispatch-store.js → persistence/dispatch-store.js} +7 -7
  208. package/engine/{inbox-store.js → persistence/inbox-store.js} +2 -2
  209. package/engine/{note-link-backfill.js → persistence/note-link-backfill.js} +4 -4
  210. package/engine/{pr-fix-target-store.js → persistence/pr-fix-target-store.js} +8 -8
  211. package/engine/{pull-requests-store.js → persistence/pull-requests-store.js} +21 -7
  212. package/engine/{small-state-store.js → persistence/small-state-store.js} +31 -31
  213. package/engine/persistence/state-operations.js +350 -0
  214. package/engine/{steering-store.js → persistence/steering-store.js} +6 -6
  215. package/engine/{issues.js → planning/issues.js} +2 -2
  216. package/engine/{plan-prd-validation.js → planning/plan-prd-validation.js} +8 -2
  217. package/engine/planning/prd-result-sidecar.js +190 -0
  218. package/engine/{prd-store.js → planning/prd-store.js} +17 -17
  219. package/engine/{project-discovery.js → planning/project-discovery.js} +5 -5
  220. package/engine/{projects.js → planning/projects.js} +10 -10
  221. package/engine/{resolve-area.js → planning/resolve-area.js} +1 -1
  222. package/engine/{work-item-validation.js → planning/work-item-validation.js} +39 -3
  223. package/engine/{work-items-store.js → planning/work-items-store.js} +29 -21
  224. package/engine/{keep-process-sweep.js → processes/keep-process-sweep.js} +57 -17
  225. package/engine/{managed-spawn-launcher.js → processes/managed-spawn-launcher.js} +3 -3
  226. package/engine/{managed-spawn.js → processes/managed-spawn.js} +97 -46
  227. package/engine/{process-utils.js → processes/process-utils.js} +599 -55
  228. package/engine/{abandoned-pr-reconciliation.js → providers/abandoned-pr-reconciliation.js} +17 -7
  229. package/engine/{comment-classifier.js → providers/comment-classifier.js} +85 -17
  230. package/engine/{comment-format.js → providers/comment-format.js} +5 -5
  231. package/engine/{gh-comment.js → providers/gh-comment.js} +15 -15
  232. package/engine/{gh-token.js → providers/gh-token.js} +4 -4
  233. package/engine/{github.js → providers/github.js} +131 -54
  234. package/engine/{pr-action.js → providers/pr-action.js} +13 -12
  235. package/engine/{pr-clone-keep.js → providers/pr-clone-keep.js} +7 -7
  236. package/engine/{pr-devbox.js → providers/pr-devbox.js} +6 -6
  237. package/engine/{pr-fix-target.js → providers/pr-fix-target.js} +13 -13
  238. package/engine/{pr-remote-patch.js → providers/pr-remote-patch.js} +4 -4
  239. package/engine/{pr-resolve.js → providers/pr-resolve.js} +7 -7
  240. package/engine/{pr-temp-clone.js → providers/pr-temp-clone.js} +5 -5
  241. package/engine/{pr-track.js → providers/pr-track.js} +11 -13
  242. package/engine/{shared-branch-pr-reconcile.js → providers/shared-branch-pr-reconcile.js} +4 -4
  243. package/engine/qa/auto-prd-qa.js +313 -0
  244. package/engine/{qa-from-prd.js → qa/from-prd.js} +42 -12
  245. package/engine/qa/prd-session.js +240 -0
  246. package/engine/{qa-process-validation.js → qa/process-validation.js} +14 -9
  247. package/engine/{qa-runbooks.js → qa/runbooks.js} +1 -1
  248. package/engine/{qa-runs.js → qa/runs.js} +286 -15
  249. package/engine/{qa-sessions.js → qa/sessions.js} +595 -49
  250. package/engine/qa/visual-journey.js +654 -0
  251. package/engine/{qa-runners.js → qa-runners/index.js} +7 -7
  252. package/engine/qa-runners/maestro.js +3 -3
  253. package/engine/qa-runners/playwright.js +2 -2
  254. package/engine/{restart-health.js → recovery/restart-health.js} +48 -4
  255. package/engine/recovery/stop-stack.js +607 -0
  256. package/engine/{supervisor.js → recovery/supervisor.js} +105 -175
  257. package/engine/{watchdog.js → recovery/watchdog.js} +136 -13
  258. package/engine/runtimes/claude.js +14 -12
  259. package/engine/runtimes/codex.js +8 -6
  260. package/engine/runtimes/copilot.js +17 -16
  261. package/engine/{watch-actions.js → watches/actions.js} +13 -13
  262. package/engine/{watches.js → watches/index.js} +43 -32
  263. package/engine/{watches-store.js → watches/store.js} +4 -4
  264. package/engine/{create-pr-worktree.js → worktrees/create-pr.js} +1 -1
  265. package/engine/{worktree-gc.js → worktrees/gc.js} +70 -22
  266. package/engine/worktrees/inventory.js +671 -0
  267. package/engine/{live-checkout.js → worktrees/live-checkout.js} +4 -4
  268. package/engine/{worktree-pool.js → worktrees/pool.js} +2 -2
  269. package/engine/{worktree-preflight.js → worktrees/preflight.js} +1 -0
  270. package/engine/worktrees/quarantine-refs.js +173 -0
  271. package/engine.js +1137 -208
  272. package/minions.js +147 -77
  273. package/package.json +10 -6
  274. package/playbooks/_pr-description-audit.md +110 -78
  275. package/playbooks/build-fix-complex.md +2 -0
  276. package/playbooks/fix.md +16 -12
  277. package/playbooks/implement-shared.md +2 -0
  278. package/playbooks/implement.md +19 -20
  279. package/playbooks/plan-to-prd.md +18 -3
  280. package/playbooks/qa-session-draft.md +136 -1
  281. package/playbooks/qa-session-execute.md +80 -2
  282. package/playbooks/qa-session-setup.md +17 -1
  283. package/playbooks/qa-validate.md +1 -1
  284. package/playbooks/setup.md +2 -0
  285. package/playbooks/shared-rules.md +25 -32
  286. package/playbooks/templates/followup-dispatch.md +4 -3
  287. package/playbooks/verify.md +1 -1
  288. package/prompts/cc-system.md +19 -27
  289. package/watch-plugins/README.md +92 -0
  290. package/watch-plugins/ado-author-prs.js +336 -0
  291. package/watch-plugins/gh-author-prs.js +375 -0
  292. package/watch-plugins/http.js +474 -0
  293. package/watch-plugins/teams-channel.js +869 -0
  294. package/docs/dev-composite-workflow.md +0 -101
  295. package/docs/pr-screenshots/pr-886/after-single-header.png +0 -0
  296. package/docs/pr-screenshots/pr-886/before-duplicate-header.png +0 -0
  297. package/docs/pr-screenshots/pr-895/01-cancellation-reason-detail.png +0 -0
  298. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-AFTER.png +0 -0
  299. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-BEFORE.png +0 -0
  300. package/docs/pr-screenshots/pr-901/projects-tab-default.png +0 -0
  301. package/docs/pr-screenshots/pr-901/projects-tab-fmf-selected.png +0 -0
  302. package/docs/pr-screenshots/pr-916/model-picker-AFTER-crop.png +0 -0
  303. package/docs/pr-screenshots/pr-916/model-picker-AFTER.png +0 -0
  304. package/docs/pr-screenshots/pr-916/model-picker-BEFORE-crop.png +0 -0
  305. package/docs/pr-screenshots/pr-916/model-picker-BEFORE.png +0 -0
  306. package/docs/pr-screenshots/pr-916/model-picker-dropdown-AFTER.png +0 -0
  307. package/docs/pr-screenshots/pr-979/auto-fix-pane-AFTER.png +0 -0
  308. package/docs/pr-screenshots/pr-979/auto-fix-pane-BEFORE.png +0 -0
  309. package/docs/pr-screenshots/pr-985/pr-column-em-dash-AFTER.png +0 -0
  310. package/docs/pr-screenshots/pr-985/pr-column-em-dash-BEFORE.png +0 -0
  311. package/docs/visual-evidence-ci.md +0 -103
  312. package/engine/bridge.js +0 -379
  313. package/engine/quarantine-refs.js +0 -103
  314. package/engine/state-operations.js +0 -178
  315. /package/engine/{steering-constraints.js → agents/steering-constraints.js} +0 -0
@@ -1,8 +1,8 @@
1
1
  /**
2
- * engine/qa-runners.js — P-b8e1d4a6
2
+ * engine/qa-runners/index.js — P-b8e1d4a6
3
3
  *
4
4
  * Pluggable test-runner registry for QA Sessions. Mirrors the
5
- * engine/watches.js target-type registry pattern (registerTargetType /
5
+ * engine/watches/index.js target-type registry pattern (registerTargetType /
6
6
  * getTargetType / listTargetTypes / plugin folder discovery).
7
7
  *
8
8
  * A runner adapter teaches QA Sessions how to translate a natural-language
@@ -52,10 +52,10 @@
52
52
  * or an array of those objects for multi-runner plugins. Bad plugin files
53
53
  * log WARN with the file path and do NOT block sibling plugins or built-in
54
54
  * runners from registering. A missing qa-runners.d/ directory is a silent
55
- * no-op (matches watches.d/ behaviour).
55
+ * no-op (matches watch-plugins/ behaviour).
56
56
  *
57
57
  * Security: plugins are user-trusted JS (same trust level as `playbooks/`
58
- * and `watches.d/`); no sandboxing. Hot-reload is not supported at module
58
+ * and `watch-plugins/`); no sandboxing. Hot-reload is not supported at module
59
59
  * level — restart the engine to pick up new plugin files, or POST
60
60
  * /api/qa/runners/reload (implemented in P-d2f5a8c9) which re-invokes
61
61
  * loadRunnerPlugins().
@@ -65,7 +65,7 @@
65
65
 
66
66
  const fs = require('fs');
67
67
  const path = require('path');
68
- const shared = require('./shared');
68
+ const shared = require('../core/shared');
69
69
  const { log } = shared;
70
70
 
71
71
  const _KEBAB_RE = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
@@ -227,7 +227,7 @@ function detectRunner(target, project, explicitRunner) {
227
227
  }
228
228
 
229
229
  // ── Plugin folder discovery (qa-runners.d/) ─────────────────────────────────
230
- // Mirrors engine/watches.js:_loadPluginTargetTypes (W-mp7hg58e000b5212).
230
+ // Mirrors engine/watches/index.js:_loadPluginTargetTypes.
231
231
  // Auto-loaded at module load time below. Tests bust the require cache via
232
232
  // test/_helpers.js ISOLATED_MODULES so MINIONS_TEST_DIR/qa-runners.d/ takes
233
233
  // effect on every createTestMinionsDir() boundary.
@@ -282,7 +282,7 @@ function _clearRunners() {
282
282
  // disk plugins. Built-ins are required relative to this file (not
283
283
  // MINIONS_DIR) so test isolation can't strand them on a stale module path.
284
284
  function _registerBuiltins() {
285
- const BUILTIN_FILES = ['./qa-runners/maestro', './qa-runners/playwright'];
285
+ const BUILTIN_FILES = ['./maestro', './playwright'];
286
286
  for (const rel of BUILTIN_FILES) {
287
287
  try {
288
288
  const resolved = require.resolve(rel);
@@ -2,15 +2,15 @@
2
2
  * engine/qa-runners/maestro.js — P-c4a9e7f3
3
3
  *
4
4
  * Maestro built-in runner adapter for QA Sessions. Registered at boot by
5
- * engine/qa-runners.js (_registerBuiltins). Priority 80 — higher than the
5
+ * engine/qa-runners/index.js (_registerBuiltins). Priority 80 — higher than the
6
6
  * Playwright safe default so a project with `.maestro/` wins on tie.
7
7
  *
8
8
  * Detection: project.localPath (or target.worktree for kind='current') has
9
9
  * a `.maestro/` directory. Explicit `runner: 'maestro'` is honoured directly
10
- * by qa-runners.js#detectRunner before detect() runs, so it does not need
10
+ * by qa-runners/index.js#detectRunner before detect() runs, so it does not need
11
11
  * a branch here.
12
12
  *
13
- * Hooks: see engine/qa-runners.js header for the contract. We return
13
+ * Hooks: see engine/qa-runners/index.js for the contract. We return
14
14
  * markdown strings from generateBrief / executeBrief — those flow into the
15
15
  * qa-session-draft.md / qa-session-execute.md playbooks as {{runner_brief}}
16
16
  * and {{runner_execute_brief}} (wired in P-f9a2e1b4).
@@ -2,7 +2,7 @@
2
2
  * engine/qa-runners/playwright.js — P-c4a9e7f3
3
3
  *
4
4
  * Playwright built-in runner adapter for QA Sessions. Registered at boot by
5
- * engine/qa-runners.js (_registerBuiltins). Priority 50 — the safe default
5
+ * engine/qa-runners/index.js (_registerBuiltins). Priority 50 — the safe default
6
6
  * for any HTTP target. Maestro (priority 80) wins on detect tie when the
7
7
  * project has `.maestro/`.
8
8
  *
@@ -12,7 +12,7 @@
12
12
  * priority gate above lets Maestro win when present; explicit
13
13
  * `runner: '...'` overrides win before detect() runs at all.
14
14
  *
15
- * Hooks: see engine/qa-runners.js header for the contract.
15
+ * Hooks: see engine/qa-runners/index.js for the contract.
16
16
  */
17
17
 
18
18
  const fs = require('fs');
@@ -3,7 +3,7 @@ const path = require('path');
3
3
  const http = require('http');
4
4
  const https = require('https');
5
5
  const { execSync } = require('child_process');
6
- const shared = require('./shared');
6
+ const shared = require('../core/shared');
7
7
 
8
8
  // W-mqpx0tpi — single source of truth for the cold-start health budget. The
9
9
  // old fixed 15s was too short for a post-`npm install` dashboard boot on a
@@ -15,6 +15,7 @@ const shared = require('./shared');
15
15
  // the literal is only a fallback if shared somehow failed to load.
16
16
  const DEFAULT_RESTART_HEALTH_TIMEOUT_MS =
17
17
  (shared.ENGINE_DEFAULTS && shared.ENGINE_DEFAULTS.restartHealthTimeoutMs) || 60000;
18
+ const RESTART_HEALTH_FRESH_HEARTBEAT_MS = 30000;
18
19
  const DEFAULT_RESTART_HEALTH_INTERVAL_MS = 100;
19
20
  const DEFAULT_DIAGNOSTIC_LOG_MAX_BYTES = 8192;
20
21
  // Consecutive dead-PID reads tolerated before fail-fast. A small guard avoids
@@ -192,8 +193,13 @@ async function checkRestartHealth(options = {}) {
192
193
  const control = readControl(minionsHome);
193
194
  const pid = normalizePid(control && control.pid);
194
195
  const expectedEngine = normalizePid(expectedEnginePid);
195
- const engineAlive = pid ? isAlive(pid) : false;
196
196
  const engineOwned = expectedEngine == null || pid === expectedEngine;
197
+ const heartbeat = Number(control?.heartbeat);
198
+ const heartbeatFresh = Number.isFinite(heartbeat)
199
+ && heartbeat > 0
200
+ && Date.now() - heartbeat <= RESTART_HEALTH_FRESH_HEARTBEAT_MS;
201
+ const engineProbeAlive = pid ? isAlive(pid) : false;
202
+ const engineAlive = engineProbeAlive || (engineOwned && heartbeatFresh);
197
203
  const engineOk = control && control.state === 'running' && engineAlive && engineOwned;
198
204
 
199
205
  // Two strategies for the dashboard check:
@@ -214,7 +220,7 @@ async function checkRestartHealth(options = {}) {
214
220
  if (dashboardPid != null && !dashboardUrl) {
215
221
  dashboardKind = 'process';
216
222
  const dpid = normalizePid(dashboardPid);
217
- const dashAlive = dpid ? isAlive(dpid) : false;
223
+ const dashProbeAlive = dpid ? isAlive(dpid) : false;
218
224
  // Ownership gate (opt-in via requireBeaconOwner). "PID alive + port
219
225
  // listening" is NOT sufficient: a stale pre-restart dashboard still holding
220
226
  // the port satisfies the listening probe, so the verifier used to report
@@ -240,6 +246,7 @@ async function checkRestartHealth(options = {}) {
240
246
  // netstat — the dashboard writes dashboard-port.json in its listen() callback,
241
247
  // so beacon.pid === dpid IS the port-bind signal.
242
248
  const portOpen = (options.requireBeaconOwner && beaconOwned) ? true : portCheck(dashboardPort);
249
+ const dashAlive = dashProbeAlive || !!(options.requireBeaconOwner && beaconOwned && portOpen);
243
250
  dashboardOk = !!(dashAlive && portOpen && beaconOwned);
244
251
  dashboardDetail = `pid=${dpid || 'none'} alive=${dashAlive ? 'yes' : 'no'} port=${dashboardPort} listening=${portOpen ? 'yes' : 'no'}`
245
252
  + (options.requireBeaconOwner ? ` beaconPid=${beaconPid || 'none'} owned=${beaconOwned ? 'yes' : 'no'}` : '');
@@ -323,7 +330,14 @@ async function checkRestartHealth(options = {}) {
323
330
 
324
331
  return {
325
332
  ok: engineOk && dashboardOk && supervisorOk && topologyOk,
326
- engine: { state: control && control.state, pid, alive: engineAlive, owned: engineOwned },
333
+ engine: {
334
+ state: control && control.state,
335
+ pid,
336
+ alive: engineAlive,
337
+ probeAlive: engineProbeAlive,
338
+ heartbeatFresh,
339
+ owned: engineOwned,
340
+ },
327
341
  dashboard: dashboardSnapshot,
328
342
  supervisor: supervisorSnapshot,
329
343
  topology: topologySnapshot,
@@ -331,6 +345,35 @@ async function checkRestartHealth(options = {}) {
331
345
  };
332
346
  }
333
347
 
348
+ async function confirmRestartHealthBeforeCleanup(options = {}) {
349
+ const ownership = await checkRestartHealth({
350
+ ...options,
351
+ // Exclusive process enumeration is a useful restart invariant, but it is
352
+ // not strong enough to justify killing an otherwise healthy owned stack.
353
+ // Re-prove the expected PIDs, beacon, heartbeat, and supervisor immediately
354
+ // before destructive cleanup.
355
+ requireExactTopology: false,
356
+ listProcessPids: undefined,
357
+ topologyScripts: undefined,
358
+ });
359
+ if (!ownership.ok) return ownership;
360
+
361
+ const http = await checkRestartHealth({
362
+ ...options,
363
+ dashboardPid: null,
364
+ requireBeaconOwner: false,
365
+ requireExactTopology: false,
366
+ listProcessPids: undefined,
367
+ topologyScripts: undefined,
368
+ });
369
+ return {
370
+ ...ownership,
371
+ ok: http.ok,
372
+ dashboardHttp: http.dashboard,
373
+ errors: http.ok ? [] : http.errors,
374
+ };
375
+ }
376
+
334
377
  async function waitForRestartHealth(options = {}) {
335
378
  const timeoutMs = options.timeoutMs ?? DEFAULT_RESTART_HEALTH_TIMEOUT_MS;
336
379
  const intervalMs = options.intervalMs ?? DEFAULT_RESTART_HEALTH_INTERVAL_MS;
@@ -431,6 +474,7 @@ module.exports = {
431
474
  DEFAULT_RESTART_HEALTH_TIMEOUT_MS,
432
475
  DEFAULT_RESTART_HEALTH_INTERVAL_MS,
433
476
  checkRestartHealth,
477
+ confirmRestartHealthBeforeCleanup,
434
478
  waitForRestartHealth,
435
479
  formatRestartHealthError,
436
480
  _private: {