@yemi33/minions 0.1.2424 → 0.1.2426

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 (185) hide show
  1. package/bin/install-internal-minions.js +1209 -0
  2. package/bin/minions.js +75 -9
  3. package/dashboard/docs/typography.md +27 -12
  4. package/dashboard/js/command-center.js +13 -11
  5. package/dashboard/js/live-stream.js +1 -1
  6. package/dashboard/js/memory-search.js +388 -43
  7. package/dashboard/js/modal-qa.js +5 -5
  8. package/dashboard/js/qa.js +39 -26
  9. package/dashboard/js/refresh.js +37 -18
  10. package/dashboard/js/render-agents.js +14 -18
  11. package/dashboard/js/render-dispatch.js +14 -74
  12. package/dashboard/js/render-inbox.js +3 -3
  13. package/dashboard/js/render-meetings.js +8 -8
  14. package/dashboard/js/render-other.js +45 -20
  15. package/dashboard/js/render-pipelines.js +6 -6
  16. package/dashboard/js/render-plans.js +14 -14
  17. package/dashboard/js/render-prd.js +46 -46
  18. package/dashboard/js/render-prs.js +9 -65
  19. package/dashboard/js/render-schedules.js +5 -5
  20. package/dashboard/js/render-skills.js +6 -6
  21. package/dashboard/js/render-utils.js +4 -4
  22. package/dashboard/js/render-watches.js +4 -16
  23. package/dashboard/js/render-work-items.js +95 -107
  24. package/dashboard/js/settings.js +175 -74
  25. package/dashboard/layout.html +3 -2
  26. package/dashboard/pages/inbox.html +1 -1
  27. package/dashboard/pages/work.html +1 -1
  28. package/dashboard/shared/model-display.js +9 -0
  29. package/dashboard/shared/watches-source.js +43 -0
  30. package/dashboard/shared/welcome-popup.js +259 -0
  31. package/dashboard/slim/body.html +6 -6
  32. package/dashboard/slim/js/chat.js +4 -2
  33. package/dashboard/slim/js/history.js +10 -3
  34. package/dashboard/slim/js/modals-tiles.js +85 -16
  35. package/dashboard/slim/js/status.js +12 -16
  36. package/dashboard/slim/styles.css +24 -4
  37. package/dashboard/styles.css +62 -27
  38. package/dashboard-build.js +8 -2
  39. package/dashboard.js +3854 -2514
  40. package/docs/README.md +7 -5
  41. package/docs/api-errors.md +144 -0
  42. package/docs/auto-discovery.md +83 -61
  43. package/docs/capture-demos.js +173 -30
  44. package/docs/command-center.md +5 -1
  45. package/docs/completion-reports.md +127 -11
  46. package/docs/constants.md +15 -3
  47. package/docs/constellation-style-telemetry.md +2 -2
  48. package/docs/copilot-cli-schema.md +32 -22
  49. package/docs/cross-repo-plans.md +30 -30
  50. package/docs/demo/memory-system.html +1 -1
  51. package/docs/deprecated.json +132 -18
  52. package/docs/diagnostics-memory.md +8 -4
  53. package/docs/human-vs-automated.md +2 -2
  54. package/docs/index.html +9 -2
  55. package/docs/internal-install.md +212 -0
  56. package/docs/kb-pr3223-cascade-archiving.md +16 -0
  57. package/docs/kb-pr696-merge-conflict-docs.md +23 -0
  58. package/docs/kb-sweep.md +2 -2
  59. package/docs/keep-processes.md +8 -1
  60. package/docs/live-checkout-mode.md +1 -1
  61. package/docs/managed-spawn.md +21 -3
  62. package/docs/named-agents.md +3 -2
  63. package/docs/onboarding.md +26 -0
  64. package/docs/plan-lifecycle.md +32 -32
  65. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-AFTER.png +0 -0
  66. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-BEFORE.png +0 -0
  67. package/docs/pr-screenshots/pr-979/auto-fix-pane-AFTER.png +0 -0
  68. package/docs/pr-screenshots/pr-979/auto-fix-pane-BEFORE.png +0 -0
  69. package/docs/pr-screenshots/pr-985/pr-column-em-dash-AFTER.png +0 -0
  70. package/docs/pr-screenshots/pr-985/pr-column-em-dash-BEFORE.png +0 -0
  71. package/docs/qa-runbook-lifecycle.md +67 -51
  72. package/docs/qa-runbooks.md +2 -2
  73. package/docs/runtime-adapters.md +101 -50
  74. package/docs/security.md +28 -0
  75. package/docs/self-improvement.md +47 -13
  76. package/docs/skills.md +29 -0
  77. package/docs/slim-ux/concepts.md +2 -2
  78. package/docs/specs/agent-configurability.md +43 -41
  79. package/docs/specs/agent-rename.md +13 -13
  80. package/docs/team-memory.md +283 -14
  81. package/docs/tutorials/01-install-and-connect.md +23 -0
  82. package/docs/tutorials/03-plan-driven-feature.md +3 -3
  83. package/docs/tutorials/04-runtimes-and-harness.md +18 -21
  84. package/docs/tutorials/08-operations-and-recovery.md +3 -2
  85. package/docs/tutorials/README.md +4 -3
  86. package/docs/visual-evidence-ci.md +103 -0
  87. package/docs/watches.md +35 -30
  88. package/docs/worktree-lifecycle.md +151 -13
  89. package/engine/acp-transport.js +1 -0
  90. package/engine/ado.js +80 -33
  91. package/engine/agent-api-validation.js +571 -0
  92. package/engine/agent-worker-pool.js +7 -6
  93. package/engine/api-contracts/agent-content.js +761 -0
  94. package/engine/api-contracts/cc-ops.js +219 -0
  95. package/engine/api-contracts/config-runtime.js +419 -0
  96. package/engine/api-contracts/core.js +138 -0
  97. package/engine/api-contracts/index.js +506 -0
  98. package/engine/api-contracts/orchestration.js +602 -0
  99. package/engine/api-contracts/pull-requests.js +323 -0
  100. package/engine/api-contracts/qa-process.js +764 -0
  101. package/engine/api-contracts/work-plan-prd.js +494 -0
  102. package/engine/api-validation.js +543 -0
  103. package/engine/cc-api-validation.js +586 -0
  104. package/engine/cc-worker-pool.js +9 -1
  105. package/engine/cleanup.js +393 -271
  106. package/engine/cli.js +65 -7
  107. package/engine/comment-classifier.js +70 -5
  108. package/engine/consolidation.js +123 -5
  109. package/engine/content-api-validation.js +606 -0
  110. package/engine/create-pr-worktree.js +22 -1
  111. package/engine/db/migrations/027-review-learning-lifecycle.js +162 -0
  112. package/engine/dispatch.js +33 -0
  113. package/engine/distribution.js +189 -0
  114. package/engine/execution-model.js +59 -0
  115. package/engine/features.js +12 -0
  116. package/engine/github.js +67 -25
  117. package/engine/harness-context.js +313 -0
  118. package/engine/inbox-store.js +1 -1
  119. package/engine/kb-sweep.js +161 -38
  120. package/engine/keep-process-sweep.js +43 -3
  121. package/engine/lifecycle.js +1066 -165
  122. package/engine/llm.js +4 -0
  123. package/engine/managed-spawn.js +463 -48
  124. package/engine/meeting.js +197 -34
  125. package/engine/memory-retrieval.js +280 -0
  126. package/engine/memory-store.js +821 -38
  127. package/engine/model-discovery.js +17 -3
  128. package/engine/pipeline.js +802 -14
  129. package/engine/plan-prd-validation.js +745 -0
  130. package/engine/playbook.js +206 -17
  131. package/engine/pooled-agent-process.js +6 -1
  132. package/engine/pr-action.js +1 -1
  133. package/engine/pr-issue-validation.js +653 -0
  134. package/engine/pr-resolve.js +75 -13
  135. package/engine/prd-store.js +39 -6
  136. package/engine/preflight.js +7 -2
  137. package/engine/process-utils.js +79 -31
  138. package/engine/projects.js +198 -12
  139. package/engine/promotion.js +371 -0
  140. package/engine/qa-from-prd.js +3 -0
  141. package/engine/qa-process-validation.js +572 -0
  142. package/engine/qa-runbooks.js +41 -37
  143. package/engine/qa-runners/maestro.js +11 -7
  144. package/engine/qa-runners/playwright.js +37 -14
  145. package/engine/qa-runners.js +9 -10
  146. package/engine/qa-runs.js +124 -11
  147. package/engine/qa-sessions.js +139 -40
  148. package/engine/quarantine-refs.js +81 -11
  149. package/engine/queries.js +163 -9
  150. package/engine/review-learning-backfill.js +482 -0
  151. package/engine/review-learning.js +1236 -0
  152. package/engine/runtimes/claude.js +60 -2
  153. package/engine/runtimes/codex.js +57 -16
  154. package/engine/runtimes/contract.js +21 -0
  155. package/engine/runtimes/copilot.js +51 -3
  156. package/engine/runtimes/index.js +1 -0
  157. package/engine/scheduler.js +201 -32
  158. package/engine/settings-validation.js +909 -0
  159. package/engine/shared.js +705 -208
  160. package/engine/spawn-agent.js +48 -21
  161. package/engine/steering-constraints.js +31 -0
  162. package/engine/steering-store.js +10 -2
  163. package/engine/steering.js +14 -2
  164. package/engine/timeout.js +404 -111
  165. package/engine/untrusted-fence.js +24 -10
  166. package/engine/watch-actions.js +7 -2
  167. package/engine/watches.js +353 -51
  168. package/engine/work-item-validation.js +561 -0
  169. package/engine/work-items-store.js +61 -1
  170. package/engine/worktree-gc.js +656 -37
  171. package/engine/worktree-preflight.js +154 -0
  172. package/engine.js +2068 -342
  173. package/package.json +1 -1
  174. package/playbooks/_pr-description-audit.md +88 -41
  175. package/playbooks/build-fix-complex.md +3 -3
  176. package/playbooks/docs.md +2 -2
  177. package/playbooks/fix.md +18 -18
  178. package/playbooks/implement.md +18 -18
  179. package/playbooks/qa-session-draft.md +10 -12
  180. package/playbooks/qa-session-execute.md +16 -12
  181. package/playbooks/qa-validate.md +8 -7
  182. package/playbooks/shared-rules.md +45 -0
  183. package/playbooks/test.md +4 -0
  184. package/prompts/cc-system.md +1 -1
  185. package/skills/check-self-authored-review-comment/SKILL.md +2 -2
package/docs/README.md CHANGED
@@ -9,7 +9,8 @@ Hands-on stories and distribution guides for people running or evaluating Minion
9
9
  - [blog-first-successful-dispatch.md](blog-first-successful-dispatch.md) — Narrative walkthrough of the first end-to-end agent dispatch and the seven failed spawn attempts that preceded it.
10
10
  - [architecture-review-2026-07-09.md](architecture-review-2026-07-09.md) — Architecture review covering engine orchestration, SQL/JSON state boundaries, runtime/process recovery, worktree lifecycle, pipelines/schedules, and prompt assembly, verified against `origin/main` at `b1b83dd2`.
11
11
  - [documentation-audit-2026-07-09.md](documentation-audit-2026-07-09.md) — Verified user-facing documentation audit covering runtime, CLI, storage, routing, and broken-link corrections.
12
- - [distribution.md](distribution.md) — How Minions is published (this repo: `@opg-microsoft/minions` to GitHub Packages; paired peer `@yemi33/minions` to npm) and the bidirectional sync contract automated opg yemi33 backport workflow + manual yemi33 opg sync PRs.
12
+ - [internal-install.md](internal-install.md) — **Start here to install.** One-command internal install/upgrade of `@opg-microsoft/minions` from the ISS `ProjectFeed-ISS` Azure Artifacts feed using the caller's `az` login: the ordered migration plan, consistent state backup, temporary-token handling, active-agent deferral, and idempotency.
13
+ - [distribution.md](distribution.md) — How Minions is published: the internal `@opg-microsoft/minions` customer channel consumed from ISS `ProjectFeed-ISS`, the public/legacy `@yemi33/minions` npm channel, and the bidirectional sync contract — automated opg → yemi33 backport workflow + manual yemi33 → opg sync PRs.
13
14
  - [onboarding.md](onboarding.md) — Condensed first-30-minutes walkthrough for a new operator.
14
15
  - [tutorials/README.md](tutorials/README.md) — Progressive tutorial track from installation through advanced automation and operations.
15
16
 
@@ -18,7 +19,7 @@ Hands-on stories and distribution guides for people running or evaluating Minion
18
19
  - [tutorials/01-install-and-connect.md](tutorials/01-install-and-connect.md) — Install Minions, verify a runtime, link a project, and start the dashboard.
19
20
  - [tutorials/02-first-task.md](tutorials/02-first-task.md) — Dispatch and inspect a bounded first task.
20
21
  - [tutorials/03-plan-driven-feature.md](tutorials/03-plan-driven-feature.md) — Review, approve, execute, and verify a dependency-aware plan.
21
- - [tutorials/04-runtimes-and-harness.md](tutorials/04-runtimes-and-harness.md) — Select runtimes and verify project skill, command, and MCP propagation.
22
+ - [tutorials/04-runtimes-and-harness.md](tutorials/04-runtimes-and-harness.md) — Select runtimes and verify native project skill, command, and MCP discovery.
22
23
  - [tutorials/05-schedules-and-watches.md](tutorials/05-schedules-and-watches.md) — Combine time-based schedules with state-based watches.
23
24
  - [tutorials/06-managed-services.md](tutorials/06-managed-services.md) — Leave an engine-owned development service running with health checks.
24
25
  - [tutorials/07-cross-repo-plan.md](tutorials/07-cross-repo-plan.md) — Coordinate one plan across multiple linked repositories.
@@ -28,6 +29,7 @@ Hands-on stories and distribution guides for people running or evaluating Minion
28
29
 
29
30
  Architecture, design proposals, and lifecycle references for people working on the engine, dashboard, or playbooks.
30
31
 
32
+ - [api-errors.md](api-errors.md) — Dashboard API error contract: the stable `{error, code, field, …}` envelope, the 400/404/409/422/5xx status taxonomy, the safe (bounded + secret-redacted) rejected-value policy, alias/enum compatibility rules, and the self-correct-4xx / don't-blindly-retry-5xx behavior. Contracts are discoverable via `GET /api/routes` and the `engine/api-contracts` route-to-validation matrix.
31
33
  - [branch-derivation.md](branch-derivation.md) — Engine-side branch fallback (`work/<wi-id>`) vs. agent-authored long form, the structured-vs-loose PR-pointer extractors, and the canonical PR-fix duplication incident.
32
34
  - [claude-md-propagation.md](claude-md-propagation.md) — Propagating repo-authored `CLAUDE.md` instructions to runtimes that don't auto-load it (Copilot/Codex): the `claudeMdNativeDiscovery` capability flag, the bounded nearest-applicable walk-up discovery, the `propagateClaudeMdForNonClaudeRuntimes` config knob, and why it's orthogonal to each runtime's native `AGENTS.md` discovery.
33
35
  - [command-center.md](command-center.md) — Command Center (CC) chat panel: configured-runtime sessions, resume semantics, system-prompt invalidation, and per-tab session storage.
@@ -51,7 +53,6 @@ Architecture, design proposals, and lifecycle references for people working on t
51
53
  - [kb-dedup-duplicate-pair-investigation.md](kb-dedup-duplicate-pair-investigation.md) — Investigation-only pass diffing suspected duplicate KB filename groups (content-hash dedup for agent-authored reviews/build-reports) to confirm true full-body duplication before any fix is proposed.
52
54
  - [kb-pr3223-cascade-archiving.md](kb-pr3223-cascade-archiving.md) — Findings from PR #3223: cascade-archiving PRDs when their linked markdown plan is archived, including the per-concern try/catch pattern and `source_plan` basename-matching invariant in `handlePlansArchive` (`dashboard.js`).
53
55
  - [kb-pr696-merge-conflict-docs.md](kb-pr696-merge-conflict-docs.md) — Findings from PR #696: resolving a merge conflict in `docs/kb-sweep.md` with stale line-number citations to `engine/kb-sweep.js`.
54
- - [kb-sweep.md](kb-sweep.md) — Knowledge-base consolidation sweep (hash dedup → LLM batch dedup/reclassify → per-entry compress) and the detached runner that keeps it alive across `minions restart`.
55
56
  - [keep-processes.md](keep-processes.md) — `meta.keep_processes` sidecar contract: when to use it vs managed-spawn, sidecar schema, caps, and the [`engine/keep-process-sweep.js`](../engine/keep-process-sweep.js) lifecycle.
56
57
  - [live-checkout-mode.md](live-checkout-mode.md) — Per-project opt-in `checkoutMode: 'live'`: skips `git worktree add` and dispatches in-place inside `project.localPath` for `repo`-managed trees, submodule-heavy repos, deep Windows paths, and native build state. Includes the refuse-on-dirty contract and the per-project mutating-concurrency cap of 1.
57
58
  - [managed-spawn.md](managed-spawn.md) — Engine-owned long-running services (managed-spawn primitive): sidecar schema, healthcheck examples, lifecycle, dashboard API, and the WI 1 (build) → WI 2 (test) chained-validation pattern.
@@ -65,13 +66,14 @@ Architecture, design proposals, and lifecycle references for people working on t
65
66
  - [qa-runbooks.md](qa-runbooks.md) — Per-project QA runbook schema, storage layout (`projects/<name>/runbooks/<id>.json`), CRUD endpoints, run-record lifecycle, and the `qa-validate` agent sidecar contract.
66
67
  - [rfc-completion-json.md](rfc-completion-json.md) — RFC for replacing stdout regex-scraping with a structured `completion.json` control-plane protocol.
67
68
  - [runtime-adapters.md](runtime-adapters.md) — Runtime adapter contract (`engine/runtimes/*`): how the engine talks to Claude Code, Copilot CLI, and future CLIs through a single capability-flagged interface.
68
- - [self-improvement.md](self-improvement.md) — The six self-improvement mechanisms (learnings inbox, per-agent history, review feedback, quality metrics, etc.) that form Minions' continuous feedback loop.
69
+ - [self-improvement.md](self-improvement.md) — The six self-improvement mechanisms (learnings inbox, per-agent history, review feedback, quality metrics, etc.) that form Minions' continuous feedback loop, including structured review learning (durable, opt-in lessons from verified review findings).
69
70
  - [shared-lifecycle-module-map.md](shared-lifecycle-module-map.md) — Documentation-only module-boundary audit of `engine/shared.js` / `engine/lifecycle.js`: function inventory, cross-file call graph, and a proposed split map (no code moved).
70
71
  - [skills.md](skills.md) — Skill block format: how agents emit reusable `\`\`\`skill` blocks and how the engine extracts them into native personal-skill directories.
71
72
  - [slim-ux/concepts.md](slim-ux/concepts.md) — Slim-UX design notes: simplified surface concepts driving the project picker, inline project link, and decoupled folder picker.
72
73
  - [slim-ux/architecture-suggestions.md](slim-ux/architecture-suggestions.md) — Slim-UX follow-up architecture suggestions paired with `concepts.md`.
73
- - [team-memory.md](team-memory.md) — End-to-end hybrid memory system: file-backed inputs and consolidation, SQL/FTS5 records, retrieval and fallback, prompt bounds, episodic capture, security, APIs, and operations.
74
+ - [team-memory.md](team-memory.md) — End-to-end hybrid memory system: file-backed inputs and consolidation, SQL/FTS5 records, retrieval and fallback, prompt bounds, episodic capture, the review-learning lifecycle (capture/recall/promotion/contradiction/diagnostics) and its staged rollout + rollback, security, APIs, and operations.
74
75
  - [timeouts-and-liveness.md](timeouts-and-liveness.md) — What kills (or doesn't kill) a live tracked agent: the wall-clock vs steering kill invariants, spawn-phase watchdog gates, steering safety nets, and stale-orphan detection ladder.
76
+ - [visual-evidence-ci.md](visual-evidence-ci.md) — GitHub Actions before/after dashboard capture: path and label triggers, deterministic base/head fixtures, artifact/comment lifecycle, trust boundary, and local reproduction.
75
77
  - [watches.md](watches.md) — Persistent monitoring jobs: target-type registry, conditions, follow-up actions, and the `watches.d/` plugin folder.
76
78
  - [workspace-manifests.md](workspace-manifests.md) — Declarative per-agent permission scoping: `allowed_tools` / `allowed_repos` / `allowed_external_urls` / `memory_scope`, dispatch-time repo gate, and runtime `--allowedTools` narrowing.
77
79
  - [worktree-lifecycle.md](worktree-lifecycle.md) — Worktree pool recycling, the live-dispatch guard that prevents wiping an agent's unpushed work, the dirty/divergent quarantine path, and the Windows EPERM/EBUSY file-lock retry footgun.
@@ -0,0 +1,144 @@
1
+ # Dashboard API errors, validation contracts, and safe retries
2
+
3
+ The Minions dashboard (`dashboard.js`, port 7331) validates every request against
4
+ a versioned route contract before it touches state. This document is the stable
5
+ reference for the **error envelope**, the **status taxonomy**, the **safe
6
+ rejected-value policy**, the **compatibility rules**, and the **retry /
7
+ self-correction behavior** that callers — humans, agents, and Command Center —
8
+ should rely on.
9
+
10
+ The machine-readable source of truth is the route contract catalog in
11
+ `engine/api-contracts/` (surfaced live at `GET /api/routes`). Never hard-code a
12
+ route's accepted inputs from prose; discover them from the contract.
13
+
14
+ ## Discoverable contracts (`GET /api/routes`)
15
+
16
+ `GET /api/routes` returns one entry per live route. Each entry carries the
17
+ contract metadata built by `engine/api-contracts` — `owner`, `audit`,
18
+ `request.{body,path,query,headers}` (each with a `policy` and typed `fields`),
19
+ `request.aliases`, `request.constraints`, and `negativeTests`.
20
+
21
+ - **`policy`** is one of `none`, `optional`, `required`. A closed release never
22
+ ships a `pending-audit` surface — the audited-route closure gate
23
+ (`assertAuditedRouteClosure`) rejects any route whose input surface has not
24
+ been described, and the dashboard refuses to boot if one slips through.
25
+ - **`fields[].allowedValuesSource`** names the live source of a field's accepted
26
+ values (e.g. `config.projects[].name`, `shared.WORK_ITEM_PRIORITY_VALUES`,
27
+ `runtimes.listRuntimes()`). Prefer reading the source over guessing an enum.
28
+ - **`negativeTests`** enumerate the rejection strategies with their expected
29
+ status, so you can predict a 400/404/409/422 before you send a bad request.
30
+
31
+ The route-to-validation matrix (`engine/api-contracts` →
32
+ `buildRouteValidationMatrix()`) derives, at call time, a row per route recording
33
+ method/path, owner, accepted inputs, contract source, negative cases, status
34
+ mapping, and side-effect assertion. Counts come from
35
+ `summarizeRouteContracts()` and are never cached — a regressed route is visible
36
+ immediately in the plan verification guide.
37
+
38
+ ## Stable error envelope
39
+
40
+ Every rejected request returns a JSON body with a stable shape (built by
41
+ `engine/api-validation.js#toApiErrorResponse` / `exposedEnvelope`):
42
+
43
+ ```json
44
+ {
45
+ "error": "human-readable message (bounded to 500 chars)",
46
+ "code": "machine-stable-code",
47
+ "field": "offendingField",
48
+ "path": "body.nested.field",
49
+ "expected": "integer",
50
+ "rejectedValue": "<safely summarized>",
51
+ "allowedValues": ["...bounded list..."],
52
+ "min": 1,
53
+ "max": 6,
54
+ "minLength": 1,
55
+ "maxLength": 4096,
56
+ "details": [ { "code": "...", "message": "...", "field": "...", "path": "..." } ]
57
+ }
58
+ ```
59
+
60
+ - `error` and `code` are **always** present. `code` defaults to `invalid-input`
61
+ for 4xx validation failures.
62
+ - The inline `field` / `path` / `expected` / `rejectedValue` / `allowedValues` /
63
+ bound keys mirror the **first** entry of `details`; `details` may list multiple
64
+ field-level failures (capped) for a single request.
65
+ - Programmatic callers should branch on `code` (stable) and, when present,
66
+ `field` / `path`; treat `error` as display text only.
67
+
68
+ ## Status taxonomy
69
+
70
+ | Status | Meaning | Caller action |
71
+ |--------|---------|---------------|
72
+ | `400 Bad Request` | Malformed/invalid input: wrong type, out-of-range, unknown enum, failed cross-field constraint, encoded path separator. | **Self-correctable.** Read `code`/`field`/`expected`/`allowedValues`, fix the payload, resend. |
73
+ | `404 Not Found` | A well-formed identifier addresses no existing resource (unknown project, missing meeting/watch/lesson id). | **Self-correctable.** Use a valid id (discover via the relevant list endpoint). |
74
+ | `409 Conflict` | The resource exists but is in the wrong state for the action (terminal meeting, duplicate follow-up, ambiguous `?source`). | Reconcile state or dedupe; do not blindly retry the identical request. |
75
+ | `422 Unprocessable Entity` | The request is syntactically valid but semantically rejected as a whole (atomic settings candidate mixing valid + invalid fields, non-string routing content). | **Self-correctable.** Fix the flagged field(s) and resubmit the whole candidate. |
76
+ | `5xx` | A dependency or the engine failed (`code: internal-error`), or a runtime/discovery dependency is unavailable (`503`). The body is deliberately generic and leaks no internal detail. | **Not self-correctable from the payload.** See retry policy below. |
77
+
78
+ `4xx` bodies always use the exposed envelope. `5xx` bodies collapse to
79
+ `{ "error": "Internal server error", "code": "internal-error" }` (or the
80
+ route's typed `503` envelope) so internal error text and stack context never
81
+ reach the client.
82
+
83
+ ## Safe rejected-value policy
84
+
85
+ Echoing back the value that was rejected is convenient for debugging but is a
86
+ data-exfiltration and log-poisoning risk. `engine/api-validation.js` enforces a
87
+ uniform **safe rejected-value policy**:
88
+
89
+ - **Strings** are bounded (default cap) before being echoed.
90
+ - **Objects / arrays / buffers** are never echoed verbatim — they are summarized
91
+ to `{ type, keyCount }` / `{ type, length }`.
92
+ - **Non-finite numbers, symbols, functions** are replaced with a bracketed tag.
93
+ - **Secret-like fields and paths** (tokens, credentials, secret-shaped keys —
94
+ `isSecretLikePath`) suppress `rejectedValue` entirely and drop
95
+ `allowedValues`.
96
+ - `allowedValues` is capped in count and each entry is bounded in length, so a
97
+ large dynamic source (project names, agent keys) can be advertised safely.
98
+
99
+ Callers must not assume `rejectedValue` is a faithful round-trip of what they
100
+ sent; it is a bounded, redacted summary for diagnosis only.
101
+
102
+ ## Compatibility rules
103
+
104
+ - **Codes are stable; messages are not.** Match on `code` (and `field`/`path`).
105
+ Prose in `error` may be reworded without notice.
106
+ - **Aliases are documented, not silent.** A route that accepts a legacy field
107
+ name declares it in `request.aliases` (`{ name, canonical }`, e.g.
108
+ `worktreeMode → checkoutMode`, `observe → contextOnly`). New code should send
109
+ the canonical field; the alias remains read-compatible.
110
+ - **Additive fields.** New optional request fields and new response fields may be
111
+ added; unknown request fields are ignored unless a route's contract explicitly
112
+ rejects them. Do not depend on a field being absent.
113
+ - **Priority and other enums come from one source.** Caller-controlled priority
114
+ boundaries validate against `shared.WORK_ITEM_PRIORITY_VALUES`
115
+ (`shared.validateWorkItemPriority`) — there is no duplicated allowed-values
116
+ list to drift. Enum surfaces advertise their `allowedValuesSource` instead of
117
+ freezing a copy.
118
+
119
+ ## Retry and self-correction behavior
120
+
121
+ - **`4xx` (400/404/409/422): self-correct, do not retry blindly.** The failure is
122
+ in your request. Read `code`, `field`, `expected`, and `allowedValues`, fix the
123
+ payload, and resend once. Retrying the identical request will fail identically.
124
+ - **`5xx` (including `503` dependency-unavailable): a dependency failed, not your
125
+ payload.** Do **not** immediately resend the same request in a tight loop —
126
+ that amplifies load on an already-failing dependency. If a retry is warranted,
127
+ back off (and prefer the engine's own retry/reconciliation paths for
128
+ state-changing operations, which are idempotency-aware). A `503` from model
129
+ discovery or a runtime dependency means the dependency is down, not that your
130
+ request was wrong.
131
+ - **State-changing routes reject before side effects.** Every audited mutating
132
+ route validates the full request and returns its `4xx` before persisting
133
+ anything (see each route's `negativeTests` and the matrix's side-effect
134
+ assertion), so a rejected mutation leaves state untouched and is safe to
135
+ correct and resend.
136
+
137
+ ## See also
138
+
139
+ - [command-center.md](command-center.md) — Command Center request/response
140
+ contract and the `X-CC-Turn-Id` correlation header.
141
+ - [design-state-storage.md](design-state-storage.md) — where the state a mutating
142
+ route touches actually lives.
143
+ - `engine/api-contracts/` — the contract catalog, coverage gate, and matrix
144
+ generator that back this document.
@@ -1,6 +1,6 @@
1
1
  # Auto-Discovery & Execution Pipeline
2
2
 
3
- > Last verified: 2026-07-10 against `engine.js` `tickInner()` and `routing.md`.
3
+ > Last verified: 2026-07-21 against `engine.js` `tickInner()`, `engine/shared.js`, and `routing.md`.
4
4
 
5
5
  How the minions engine finds work and dispatches agents automatically.
6
6
 
@@ -16,7 +16,8 @@ tick()
16
16
  1b. checkIdleThreshold() Notify on excessive agent idleness
17
17
  1c. checkMeetingTimeouts() Advance round-based meetings whose timer fired
18
18
  2. consolidateInbox() Merge learnings into notes.md (Haiku-powered)
19
- 2.1 shouldAutoSweep() spawnSweepRunnerDetached() Periodic KB sweep (opt-in via engine.autoConsolidateMemory, 4h cadence)
19
+ 2.05 bootstrapDefaultSchedules() Reconcile generated schedules once per engine process; while enabled, retry every tick until reconciliation succeeds
20
+ 2.1 shouldAutoSweep() → spawnSweepRunnerDetached() Periodic KB sweep (default-on via engine.autoConsolidateMemory, 4h cadence)
20
21
  2.5 runCleanup() Periodic cleanup (every 60 ticks ≈ 10min)
21
22
  2.52 sweepKeepProcesses() keep_processes TTL/dead-PID sweep (every 180 ticks)
22
23
  2.53 sweepManagedSpawn() managed_spawn TTL/dead-PID/log-rotate sweep (every 180 ticks)
@@ -25,7 +26,7 @@ tick()
25
26
  2.6 pollPrStatus() Poll ADO + GitHub for build, review, merge status (wall-clock cadence from prPollStatusEvery × tickInterval, default ≈ 12min)
26
27
  processPendingRebases() Run any rebase work queued from the previous tick
27
28
  syncPrdFromPrs() Backfill PRD item status from active PRs
28
- checkPlanCompletion() Mark plans completed when all features done/in-pr
29
+ checkPlanCompletion() Mark plans completed when all features are terminal (done/failed/cancelled)
29
30
  2.7 pollPrHumanComments() Poll PR threads for human comments (wall-clock cadence from prPollCommentsEvery × tickInterval, default ≈ 12min)
30
31
  reconcilePrs() (ADO+GH) Reconciliation sweep (runs regardless of poll flags)
31
32
  reconcileSharedBranchPrs() Backfill the PR store for shared-branch plans whose aggregate remote PR is untracked/under-linked (runs unconditionally, like the other recovery sweeps)
@@ -42,11 +43,19 @@ tick()
42
43
  >
43
44
  > Dispatch of already-pending work runs before `discoverWork()`, not after (`engine.js` comment: "Process pending dispatches before discovery. discoverWork() runs pre-dispatch LLM validation for newly found work; a slow validator must not starve runnable entries that are already durable in dispatch.pending.").
44
45
 
46
+ **Tick-overlap protection.** A hard timeout or five-minute lock force-release
47
+ increments `tickGeneration`. Before worktree preparation, each pending item
48
+ acquires a persisted `_spawnLeaseId` tied to that generation; leased pending
49
+ rows count against `maxConcurrent`, and activation occurs only at runtime
50
+ handoff. Worktree setup and quarantine repeatedly revalidate the lease, so an
51
+ older tick aborts instead of spawning the same dispatch twice or quarantining a
52
+ successor attempt's worktree.
53
+
45
54
  ## Work Discovery
46
55
 
47
- `discoverWork()` iterates every project in `config.projects[]` and runs four core discovery sources: pull requests, per-project work items, central work items, and pipeline/scheduled tasks. Results are prioritized: fixes > reviews > implements > work-items.
56
+ `discoverWork()` iterates every project in `config.projects[]` and runs four core discovery sources: pull requests, per-project work items, central work items, and scheduled work. Results are prioritized: fixes > reviews > implements > work-items.
48
57
 
49
- Before scanning, the engine materializes plans and specs into project-scoped SQL work items, so they're picked up by the work-items source below.
58
+ Plans are materialized before the project scan; specs are materialized inside each project pass before its work-item scan. Both become project-scoped SQL work items consumed by Source 2 below.
50
59
 
51
60
  ### Source 1: Pull Requests (`discoverFromPrs`)
52
61
 
@@ -103,18 +112,7 @@ Composition with per-project gates: setting `workItemsDiscoveryEnabled: false` s
103
112
 
104
113
  Flip via Dashboard → Settings → Polling → "Granular work-discovery controls (P-d6f0a2b5)" collapsible, or set the keys directly in `config.engine`.
105
114
 
106
- ### Source 2: PRD Gap Analysis (via `materializePlansAsWorkItems`)
107
-
108
- PRD items flow through `materializePlansAsWorkItems()`, which queries SQL PRDs for `missing` / `updated` / `planned` items and creates work items in the target project's queue.
109
-
110
- **Reads:** SQL `prds` and `prd_items`.
111
-
112
- | Item State | Action | Dispatch Type |
113
- |------------|--------|---------------|
114
- | `status: "missing"` or `"updated"` | Queue implementation (re-opens any existing done WI) | `implement` |
115
- | `estimated_complexity: "large"` | Routes to `implement:large` (prefers Rebecca) | `implement:large` |
116
-
117
- ### Source 3: Per-Project Work Items (`discoverFromWorkItems`)
115
+ ### Source 2: Per-Project Work Items (`discoverFromWorkItems`)
118
116
 
119
117
  **Reads:** the project's `work_items` SQL scope
120
118
 
@@ -124,7 +122,7 @@ PRD items flow through `materializePlansAsWorkItems()`, which queries SQL PRDs f
124
122
 
125
123
  After dispatching, the engine writes `status: "dispatched"` back to the item. The agent is scoped to the specific project directory.
126
124
 
127
- ### Source 4: Central Work Items (`discoverCentralWorkItems`)
125
+ ### Source 3: Central Work Items (`discoverCentralWorkItems`)
128
126
 
129
127
  **Reads:** the central `work_items` SQL scope
130
128
 
@@ -162,14 +160,30 @@ This means a single work item like "Add telemetry to the document creation pipel
162
160
 
163
161
  **Adding central work items:**
164
162
  - Dashboard Command Center → type your intent (no `#project` = central queue)
165
- - CLI: `node engine.js work "task title"` (defaults to central queue)
163
+ - CLI: `minions work "task title"` (defaults to central queue)
166
164
  - API: `POST /api/work-items` with no project
167
165
 
166
+ ### Source 4: Scheduled Work (`discoverScheduledWork`)
167
+
168
+ **Reads:** `config.schedules[]` and persistent schedule-run state.
169
+
170
+ Enabled schedules whose three-field cron expression matches the current minute produce work through `engine/scheduler.js`. Ordinary tasks and tri-agent harness missions are written to the central SQL work-item scope with `_scheduleId` metadata; meeting schedules create meeting records directly. The persisted `lastRun` value prevents a schedule from firing twice in the same calendar minute.
171
+
172
+ `engine.bootstrapDefaultSchedules` defaults to `true` and is configurable under
173
+ Dashboard → Settings → Workflow Defaults. `engine/schedule-bootstrap.js`
174
+ idempotently creates a read-only per-project git-fetch schedule (title-derived
175
+ `keep-branch-fresh-git-fetch-origin-…` id, `0 */12 *`, `explore`) and one shared
176
+ `harness-sweep-all-projects` schedule (`0 6 *`, `explore`, low priority).
177
+ Project creation applies the bootstrap in the same config lock; engine startup
178
+ reconciles older installs once. Existing operator customizations stay intact,
179
+ and only generated project schedules tagged during removal are re-enabled on
180
+ relink.
181
+
168
182
  ### Materialization: Specs and Plans → Work Items
169
183
 
170
- Before the 3 core sources run, the engine materializes indirect sources into work items:
184
+ Before the four core sources run, the engine materializes indirect sources into work items:
171
185
 
172
- **Specs** (`materializeSpecsAsWorkItems`): When a PR merges that added/modified `.md` files under `docs/` (configurable via `workSources.specs.filePatterns`), the engine reads each doc and checks for `type: spec` in its frontmatter. Only docs with this marker are treated as actionable specs — regular documentation is ignored. For matching docs, it extracts title/summary/priority and creates implementation work items with `createdBy: 'engine:spec-discovery'`. State tracked in `.minions/spec-tracker.json` to avoid re-processing merged PRs.
186
+ **Specs** (`materializeSpecsAsWorkItems`): When a PR merges that added/modified `.md` files under `docs/` (configurable via `workSources.specs.filePatterns`), the engine reads each doc and checks for `type: spec` in its frontmatter. Only docs with this marker are treated as actionable specs — regular documentation is ignored. For matching docs, it extracts title/summary/priority and creates implementation work items with `createdBy: 'engine:spec-discovery'`. State is tracked in `projects/<name>/spec-tracker.json` to avoid re-processing merged PRs.
173
187
 
174
188
  Example spec frontmatter:
175
189
  ```markdown
@@ -184,7 +198,7 @@ priority: high
184
198
 
185
199
  **Plans** (`materializePlansAsWorkItems`): Queries SQL PRDs for `missing`/`planned` items. Creates work items in the target project's queue with `createdBy: 'engine:plan-discovery'`. Work item ID = PRD item ID (e.g. `P-43e5ac28`). Deduped by `id`.
186
200
 
187
- Both write to the SQL work-item store and are picked up by Source 3 on the same or next tick.
201
+ Both write to the SQL work-item store and are picked up by Source 2 on the same or next tick.
188
202
 
189
203
  ## PR Status Polling (`pollPrStatus`)
190
204
 
@@ -223,7 +237,7 @@ Item found
223
237
 
224
238
  ├─ isOnCooldown(key)? → skip if dispatched within cooldown window
225
239
  │ Default: 30min for PRD/PRs, 0 for work-items
226
- │ Cooldowns are in-memory (reset on engine restart)
240
+ │ Cooldowns are persisted in SQLite and survive engine restart
227
241
 
228
242
  └─ resolveAgent(workType)? → skip if no idle agent available
229
243
  Checks routing.md: preferred → fallback → any idle agent
@@ -239,6 +253,7 @@ routing.md table (see the file for the authoritative list):
239
253
  implement:large → rebecca (fallback: dallas)
240
254
  review → ripley (fallback: lambert)
241
255
  fix → _author_ (fallback: _any_) ← routes to PR author, any idle as fallback
256
+ build-fix-complex → _author_ (fallback: dallas)
242
257
  plan → ripley (fallback: rebecca)
243
258
  plan-to-prd → lambert (fallback: rebecca)
244
259
  explore → ripley (fallback: rebecca)
@@ -250,6 +265,9 @@ routing.md table (see the file for the authoritative list):
250
265
  docs → lambert (fallback: _any_)
251
266
  setup → dallas (fallback: _any_)
252
267
  qa-validate → dallas (fallback: ralph)
268
+ qa-session-setup → dallas (fallback: ralph)
269
+ qa-session-draft → dallas (fallback: ralph)
270
+ qa-session-execute → dallas (fallback: ralph)
253
271
  ```
254
272
 
255
273
  Resolution order:
@@ -287,17 +305,24 @@ When an item is dispatched:
287
305
  meta.project.localPath → rootDir (the repo on disk)
288
306
  ```
289
307
 
290
- ### 2. Create Git Worktree (if task has a branch)
291
- ```
292
- git worktree add <rootDir>/../worktrees/<branch> -b <branch> <mainBranch>
293
- ```
294
- - Branch names are sanitized (alphanumeric, dots, hyphens, slashes only, max 200 chars)
295
- - If worktree fails for implement/fix item marked as error, moved to completed
296
- - If worktree fails for review/explore/ask falls back to rootDir (read-only tasks)
308
+ ### 2. Resolve the Checkout
309
+
310
+ `shared.resolveSpawnPaths()` owns placement:
311
+
312
+ - In worktree mode, every project-bound dispatch gets an engine-owned worktree.
313
+ Branch-bearing work uses its target branch; branchless/read-only work uses a
314
+ detached worktree. The engine never falls back to `project.localPath`.
315
+ - New worktrees require a freshly fetched `origin/<mainRef>` base. If the fetch
316
+ or remote ref cannot be verified, allocation fails instead of branching from
317
+ a stale local base.
318
+ - Live/hybrid validation work runs in `project.localPath` only when
319
+ `resolveCheckoutMode(project, type)` selects live mode.
320
+ - Project-less read-only work starts in `MINIONS_DIR`.
321
+ - A validated relative `meta.workdir` is applied beneath the selected base.
297
322
 
298
323
  ### 3. Render Playbook
299
324
  ```
300
- playbooks/<type>.md substitute {{variables}} → append notes.md append learnings requirement
325
+ playbooks/<type>.md substitute {{variables}} → inject shared rules/context appendices
301
326
  ```
302
327
 
303
328
  Variables injected from config and item metadata:
@@ -307,28 +332,23 @@ Variables injected from config and item metadata:
307
332
  - `{{team_root}}` — path to central `.minions/` directory
308
333
 
309
334
  ### 4. Build System Prompt
310
- Combines:
311
- - Agent identity (name, role, skills)
312
- - Agent charter (`agents/<name>/charter.md`)
313
- - Project context (repo name, repo host config, main branch)
314
- - Critical rules (worktrees, MCP tools, PowerShell, learnings)
315
- - Full `notes.md` content
316
-
317
- ### 5. Spawn Claude CLI
318
- ```bash
319
- claude -p --system-prompt-file <sysprompt-file> \
320
- --output-format stream-json --max-turns 100 --verbose \
321
- --dangerously-skip-permissions
322
- # Prompt text is piped via stdin (not passed as an arg).
323
- # Agent dispatches route through engine/spawn-agent.js; CC / doc-chat use a direct
324
- # spawn path in engine/llm.js that bypasses spawn-agent.js entirely.
325
- # Permission bypass is runtime-owned: Copilot uses
326
- # --autopilot --allow-all --no-ask-user instead.
327
- ```
335
+ Combines agent identity, project context, safety rules, pinned context, and
336
+ memory. With `memoryRetrieval` enabled, a bounded task-relevant evidence pack
337
+ replaces broad team/personal notes; otherwise bounded `notes.md` and personal
338
+ memory are used. Human/LLM-authored appendices are wrapped as untrusted input.
339
+
340
+ ### 5. Resolve and Spawn the Runtime
341
+
342
+ The engine resolves `resolveRuntime(resolveAgentCli(...))`; the selected adapter
343
+ owns binary discovery, argv, prompt delivery, workspace preparation, and output
344
+ parsing. Cold agent dispatches use the runtime-neutral
345
+ `engine/spawn-agent.js`; opt-in Copilot fleet dispatch can use the ACP worker
346
+ pool. CC/doc-chat use direct `engine/llm.js` calls.
328
347
 
329
- - Process runs in the worktree directory (or rootDir for reviews)
348
+ - Process runs in the resolved worktree/live checkout (or `MINIONS_DIR` for
349
+ project-less read-only work)
330
350
  - stdout/stderr captured (capped at 1MB each)
331
- - CLAUDECODE env vars stripped to allow nested sessions
351
+ - runtime-specific environment cleanup stays inside the adapter/spawn wrapper
332
352
 
333
353
  ### 6. Track State
334
354
  - Agent status derived from SQL dispatch state
@@ -337,12 +357,12 @@ claude -p --system-prompt-file <sysprompt-file> \
337
357
 
338
358
  ## Post-Completion
339
359
 
340
- When the claude process exits:
360
+ When the selected runtime exits:
341
361
 
342
362
  ```
343
363
  proc.on('close')
344
364
 
345
- ├─ Save output to agents/<name>/output.log
365
+ ├─ Save output to agents/<id>/output.log
346
366
 
347
367
  ├─ Dispatch completion determines visible agent status ("done"/"error")
348
368
 
@@ -351,9 +371,10 @@ proc.on('close')
351
371
  ├─ Sync PRs from output (scan for PR URLs → SQL PR store)
352
372
 
353
373
  ├─ Post-completion hooks:
354
- │ review → update PR minionsReview in SQL, vote on ADO
355
- │ fix → set PR minionsReview back to "waiting"
356
- build-test → record verification result and findings
374
+ │ review → update PR minionsReview in SQL; platform vote only when autoApplyReviewVote is enabled
375
+ │ fix → set PR minionsReview back to "waiting"
376
+ │ test/verify → record validation result and findings
377
+ │ qa-* → terminalize linked QA run/session state
357
378
 
358
379
  ├─ Check for learnings in notes/inbox/
359
380
  │ (warns if agent didn't write findings)
@@ -411,9 +432,9 @@ ADO + GitHub REST ── pollPrStatus() ──► SQL PR rows│
411
432
 
412
433
 
413
434
  notes.md
414
- (injected into
415
- all future
416
- playbooks)
435
+ (fallback memory
436
+ when active retrieval
437
+ has no evidence pack)
417
438
  ```
418
439
 
419
440
  ## Timeout & Stale-Orphan Detection
@@ -452,7 +473,7 @@ All discovery behavior is controlled via `config.json`:
452
473
  "maxConcurrent": 5, // max agents running at once
453
474
  "agentTimeout": 18000000, // 5 hours — hard runtime limit
454
475
  "heartbeatTimeout": 300000, // 5min — stale-orphan grace after process tracking is lost
455
- "maxTurns": 100, // max claude CLI turns per agent
476
+ "maxTurns": 100, // max runtime turns per agent
456
477
  "worktreeCreateTimeout": 300000, // timeout for git worktree add on large repos
457
478
  "worktreeCreateRetries": 1 // retry count for transient add failures
458
479
  },
@@ -475,4 +496,5 @@ All discovery behavior is controlled via `config.json`:
475
496
  }
476
497
  ```
477
498
 
478
- To disable a work source for a project, set `"enabled": false`. To change where the engine looks for PRD or PR files, change the `path` field (resolved relative to `localPath`).
499
+ To disable a work source for a project, set `"enabled": false`. PR and PRD runtime
500
+ state is SQL-backed; there is no JSON path override for those stores.