@yemi33/minions 0.1.1950 → 0.1.1952

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 (40) hide show
  1. package/dashboard/js/command-center.js +13 -2
  2. package/dashboard/js/modal-qa.js +10 -0
  3. package/dashboard/js/refresh.js +4 -0
  4. package/dashboard/js/render-dispatch.js +25 -0
  5. package/dashboard/js/render-other.js +109 -2
  6. package/dashboard/js/settings.js +1 -1
  7. package/dashboard/layout.html +2 -2
  8. package/dashboard/pages/engine.html +6 -0
  9. package/dashboard/slim.html +1987 -0
  10. package/dashboard/styles.css +8 -0
  11. package/dashboard.js +450 -40
  12. package/docs/completion-reports.md +25 -0
  13. package/docs/design-state-storage.md +1 -1
  14. package/docs/slim-ux/architecture-suggestions.md +467 -0
  15. package/docs/slim-ux/concepts.md +824 -0
  16. package/engine/ado-mcp-wrapper.js +33 -7
  17. package/engine/ado.js +123 -15
  18. package/engine/cc-worker-pool.js +41 -0
  19. package/engine/cleanup.js +71 -34
  20. package/engine/cli.js +37 -0
  21. package/engine/dispatch.js +32 -9
  22. package/engine/features.js +6 -0
  23. package/engine/gh-token.js +137 -0
  24. package/engine/github.js +166 -29
  25. package/engine/issues.js +29 -0
  26. package/engine/keep-process-sweep.js +397 -0
  27. package/engine/lifecycle.js +150 -33
  28. package/engine/playbook.js +17 -0
  29. package/engine/queries.js +71 -0
  30. package/engine/recovery.js +6 -0
  31. package/engine/shared.js +446 -14
  32. package/engine/spawn-agent.js +44 -2
  33. package/engine/timeout.js +34 -11
  34. package/engine/worktree-pool.js +410 -0
  35. package/engine.js +643 -119
  36. package/package.json +6 -3
  37. package/playbooks/review.md +2 -0
  38. package/playbooks/shared-rules.md +3 -1
  39. package/prompts/cc-system.md +24 -0
  40. package/engine/copilot-models.json +0 -5
@@ -0,0 +1,824 @@
1
+ # Minions Concept Dictionary
2
+
3
+ > Plain-English definitions for every first-class noun in the Minions system. This is the team's
4
+ > shared language before we redesign the UI; it is intentionally factual — design opinions live in
5
+ > [`architecture-suggestions.md`](./architecture-suggestions.md).
6
+ >
7
+ > Every backing claim is anchored to a file path and line number. If you change the code, please
8
+ > update the line numbers here too.
9
+
10
+ ---
11
+
12
+ ## How the system fits together (one paragraph)
13
+
14
+ A **human** types something into the **Command Center** chat. CC turns that into a **Work Item**
15
+ (or a **Plan**, **Note**, **Schedule**, **Watch**, etc.) by emitting an `===ACTIONS===` JSON block.
16
+ The **Engine** wakes up on its 60-second tick, looks at the pending **Dispatch Queue**, picks an
17
+ **Agent** (a Minion / Team Member) by consulting **Routing**, spawns a CLI process for that agent
18
+ (Claude or Copilot), and waits. The agent reads its **Charter**, the **Playbook** for the work
19
+ type, the project's **CLAUDE.md**, the **Pinned Context**, the team's **Notes** and
20
+ **Knowledge Base**, then does the work — usually opening a **Pull Request**. When the agent exits,
21
+ it writes a **Completion** report; the engine syncs the PR back, marks the Work Item done, and
22
+ runs the **Inbox** through the **KB Sweep** so the team's memory grows. **Watches**, **Schedules**,
23
+ and **Pipelines** are the three ways things happen without a human typing.
24
+
25
+ ---
26
+
27
+ ## 1. Command Center (CC)
28
+
29
+ **What it is.** The chat box on the dashboard's home page. It's a Claude (or Copilot) instance
30
+ running with a beefy system prompt that knows about your projects, agents, work items, and the
31
+ JSON action grammar. You talk to CC; CC dispatches Work Items, creates Plans, files Notes, opens
32
+ Watches, etc. It is the primary human-to-fleet interface.
33
+
34
+ **Where it lives.**
35
+ - System prompt: `prompts/cc-system.md`
36
+ - Per-tab session state: `engine/cc-sessions.json` (also legacy `engine/cc-session.json`).
37
+ - Direct CLI invocation: `engine/llm.js` `callLLM({ direct: true })` — bypasses
38
+ `spawn-agent.js` and runs the runtime CLI itself.
39
+
40
+ **Backing classes / functions.**
41
+ - Streaming endpoint handler: `dashboard.js` line 7194 (`/api/command-center/stream` → `handleCommandCenterStream`).
42
+ - Non-streaming handler: `dashboard.js` line 7193 (`/api/command-center` → `handleCommandCenter`).
43
+ - Action parser: `parseCCActions` / `executeCCActions` (search `dashboard.js` for `parseCCActions`).
44
+ - Tab session bookkeeping: dashboard.js around line 1185 (`/api/cc-sessions/:id`).
45
+
46
+ **How the existing dashboard surfaces it.** `dashboard/pages/home.html` — the Command Center is
47
+ the top-of-page input box. There is also a "past commands" / history modal.
48
+
49
+ **Endpoints (`dashboard.js` line refs from the `ROUTES` table starting at line 6807).**
50
+
51
+ | Method | Path | Line | Purpose |
52
+ |--------|------|------|---------|
53
+ | POST | `/api/command-center` | 7193 | Single-shot CC turn |
54
+ | POST | `/api/command-center/stream` | 7194 | SSE-streaming CC turn |
55
+ | POST | `/api/command-center/new-session` | 7191 | Clear active CC session |
56
+ | POST | `/api/command-center/abort` | 7192 | Cancel an in-flight stream |
57
+ | GET | `/api/cc-sessions` | 7195 | List per-tab sessions |
58
+ | DELETE | `/api/cc-sessions/:id` | (see line 1185) | Close a tab |
59
+
60
+ **Relationships.** CC is the *creator* of almost every other concept on this page (Work Item,
61
+ Plan, Note, Schedule, Watch, Knowledge entry, Pinned note). Per-call cap is
62
+ `ENGINE_DEFAULTS.ccMaxTurns` (50, `engine/shared.js` line 860+); sessions themselves never expire.
63
+
64
+ ---
65
+
66
+ ## 2. Work Item
67
+
68
+ **What it is.** A unit of work the engine can dispatch to an agent. Has a title, type
69
+ (`implement`, `fix`, `review`, …), priority, optional project, and lifecycle state. Most things on
70
+ the home page eventually reduce to a Work Item.
71
+
72
+ **Where it lives.**
73
+ - Central queue: `work-items.json` (root).
74
+ - Per-project queue: `projects/<name>/work-items.json` (`projectWorkItemsPath`,
75
+ `engine/shared.js` line ~1530).
76
+ - In-flight copy: `engine/dispatch.json` (`pending[] / active[] / completed[]`).
77
+
78
+ **Backing classes / functions.**
79
+ - Status constants: `engine/shared.js` line 1348 (`WI_STATUS`).
80
+ - Type constants: `engine/shared.js` line 1359 (`WORK_TYPE`).
81
+ - `addToDispatch`: `engine/dispatch.js` line 128.
82
+ - `updateWorkItemStatus`: `engine/lifecycle.js` line 484 (validates against `WI_STATUS`).
83
+ - `isItemCompleted`: `engine/lifecycle.js` line 477.
84
+ - Lifecycle: pending → dispatched → done | failed; failed auto-retries up to
85
+ `ENGINE_DEFAULTS.maxRetries`.
86
+
87
+ **Existing dashboard.** `dashboard/pages/work.html` — the side-panel "Work Items" tab with
88
+ pending / active / completed columns.
89
+
90
+ **Endpoints (all under `/api/work-items*`, `dashboard.js` lines 6852–6888).**
91
+ - `POST /api/work-items` (6852) — create
92
+ - `POST /api/work-items/update` (6853) — edit
93
+ - `POST /api/work-items/retry` (6854) — back to pending
94
+ - `POST /api/work-items/delete` (6855) — kill + remove
95
+ - `POST /api/work-items/cancel` (6856) — cancel with reason
96
+ - `POST /api/work-items/archive` (6857) — move to archive
97
+ - `GET /api/work-items/archive` (6858) — list archive
98
+ - `POST /api/work-items/reopen` (6859) — done/failed → pending
99
+ - `POST /api/work-items/feedback` (6860) — 👍 / 👎 → inbox note
100
+
101
+ **Relationships.** A Work Item is the *body* the **Dispatch Queue** carries. It points to a
102
+ **Project**, an **Agent** (post-dispatch), and a **Pull Request** (post-completion). Materialized
103
+ from a **PRD Item** via the plan-to-prd flow. **Pipelines** can declare Work Items as stages.
104
+
105
+ ---
106
+
107
+ ## 3. Plan
108
+
109
+ **What it is.** A markdown document in `plans/` describing what should be built and why. The plan
110
+ flow is: human (or agent) writes plan → human approves → `plan-to-prd` agent converts it to a
111
+ **PRD** JSON → materializer creates **Work Items** with `depends_on` edges → engine executes them
112
+ → verify task auto-runs → human archives.
113
+
114
+ **Where it lives.**
115
+ - Drafts: `plans/*.md`.
116
+ - Archived: `plans/archive/*.md`.
117
+ - Status field is on the PRD JSON twin (see PRD).
118
+
119
+ **Backing classes / functions.**
120
+ - Status constants: `engine/shared.js` line 1365 (`PLAN_STATUS = { ACTIVE, AWAITING_APPROVAL,
121
+ APPROVED, PAUSED, REJECTED, COMPLETED, REVISION_REQUESTED }`).
122
+ - Atomic dispatch: `queuePlanToPrd` (used by every plan-to-prd path).
123
+ - Plan completion / archival: `engine/lifecycle.js`
124
+ - `checkPlanCompletion` line 22
125
+ - `archivePlan` line 355
126
+ - `cleanupPlanWorktrees` line 415.
127
+ - Plan dirs: `engine/pipeline.js` line 23 (`PLANS_DIR`).
128
+
129
+ **Existing dashboard.** `dashboard/pages/plans.html` — plan browser, approve / reject / archive
130
+ buttons.
131
+
132
+ **Endpoints (`dashboard.js` lines 6952–6963).**
133
+ - `GET /api/plans` (6952) — list .md drafts + .json PRDs
134
+ - `POST /api/plans/trigger-verify` (6953)
135
+ - `POST /api/plans/approve` (6954) — kicks off plan-to-prd
136
+ - `POST /api/plans/pause` (6955)
137
+ - `POST /api/plans/execute` (6956)
138
+ - `POST /api/plans/reject` (6957)
139
+ - `POST /api/plans/regenerate` (6958)
140
+ - `POST /api/plans/delete` (6959)
141
+ - `POST /api/plans/archive` (6960) — manual archive
142
+ - `POST /api/plans/unarchive` (6961)
143
+ - `POST /api/plans/revise` (6962)
144
+ - `POST /api/plans/discuss` (6963)
145
+ - `POST /api/plans/create` (7055)
146
+
147
+ **Relationships.** Plan ↔ **PRD** ↔ **Work Items** is a one-to-one-to-many chain. **Pipelines**
148
+ can include `plan` stages. **Verification** is owned by the plan: when all work items finish, a
149
+ verify Work Item auto-spawns.
150
+
151
+ ---
152
+
153
+ ## 4. PRD (Product Requirements Document)
154
+
155
+ **What it is.** The structured JSON twin of a Plan. Where the Plan markdown is for humans, the
156
+ PRD JSON is what the engine reads to materialize work items. Each PRD has an `items` array; each
157
+ item has acceptance criteria, complexity, dependencies, and a status (`missing | updated | done`).
158
+
159
+ **Where it lives.** `prd/*.json`, archived to `prd/archive/*.json`. The materializer treats
160
+ `missing` and `updated` items as work to do (`PRD_MATERIALIZABLE`, `engine/shared.js` line 1370).
161
+
162
+ **Backing classes / functions.**
163
+ - Status constants: `engine/shared.js` line 1370 (`PRD_ITEM_STATUS`, `PRD_MATERIALIZABLE`).
164
+ - Sync from Work Items: `syncPrdItemStatus`, `reconcilePrdStatuses` (`engine/lifecycle.js`
165
+ lines 564, 597).
166
+ - Plan-to-PRD agent: `playbooks/plan-to-prd.md`, dispatched via `queuePlanToPrd`.
167
+ - PRD dir: `engine/pipeline.js` line 24 (`PRD_DIR`).
168
+
169
+ **Existing dashboard.** `dashboard/pages/plans.html` — same page as Plan, with a graph view of
170
+ PRD items and their states. Recent feature: PRD graph view at parity with list view (commit
171
+ `b4767d2d`).
172
+
173
+ **Endpoints (`dashboard.js`).**
174
+ - `POST /api/prd-items` (6968) — create PRD item
175
+ - `POST /api/prd-items/update` (6969)
176
+ - `POST /api/prd-items/remove` (6970) — also cancels matching Work Item
177
+
178
+ **Relationships.** PRD is the bridge between **Plan** (human-readable) and the **Work Item**
179
+ queue (machine-executable). When a plan's PRD items are all `done`, the plan completes; archive
180
+ is still manual.
181
+
182
+ ---
183
+
184
+ ## 5. Note
185
+
186
+ **What it is.** A small markdown file written by an agent (after a task) or a human (via "+
187
+ Note") capturing what was learned. Notes are *raw*; the consolidation engine reads them and
188
+ either merges them into `notes.md` or promotes them into a **Knowledge Base** category.
189
+
190
+ **Where it lives.** `notes/inbox/*.md` while raw, `notes/archive/<category>/*.md` after KB sweep,
191
+ and merged content lives in `notes.md`.
192
+
193
+ **Backing classes / functions.**
194
+ - Inbox writer: `writeToInbox` — `engine/shared.js` line 648 (re-exported line 2959).
195
+ - ID parser: `parseNoteId` (same module).
196
+ - Consolidation orchestration: `engine/consolidation.js`
197
+ - `consolidateInbox` line 24
198
+ - `consolidateWithLLM` line 116
199
+ - `classifyToKnowledgeBase` line 389
200
+ - `archiveInboxFiles` line 444.
201
+
202
+ **Existing dashboard.** `dashboard/pages/inbox.html` — the inbox tab. A "+ Note" quick-action
203
+ exists in the top bar of `home.html`.
204
+
205
+ **Endpoints (`dashboard.js`).**
206
+ - `POST /api/notes` (6946) — write to inbox
207
+ - `GET /api/notes-full` (6947) — read consolidated `notes.md`
208
+ - `POST /api/notes-save` (6948) — save edited `notes.md`
209
+
210
+ **Relationships.** Notes feed **Inbox** → **Consolidation** → **Knowledge Base** (or
211
+ `notes.md`). Agents are *required* to drop a note in the inbox at the end of every successful
212
+ task; failure cases must NOT write a note.
213
+
214
+ ---
215
+
216
+ ## 6. Knowledge Base (KB)
217
+
218
+ **What it is.** The team's long-term memory. After consolidation, notes get classified into one of
219
+ five categories and archived. Agents read the KB before researching outside.
220
+
221
+ **Where it lives.**
222
+ - `notes/archive/architecture/*.md`
223
+ - `notes/archive/conventions/*.md`
224
+ - `notes/archive/project-notes/*.md`
225
+ - `notes/archive/build-reports/*.md`
226
+ - `notes/archive/reviews/*.md`
227
+
228
+ **Backing classes / functions.**
229
+ - Categories: `engine/shared.js` line 840 (`KB_CATEGORIES`).
230
+ - Pin store: `engine/shared.js` line 15 (`PINNED_ITEMS_PATH = engine/kb-pins.json`).
231
+ - Sweep / classification: `engine/kb-sweep.js`, `engine/consolidation.js`
232
+ `classifyToKnowledgeBase` line 389.
233
+
234
+ **Existing dashboard.** `dashboard/pages/inbox.html` — same tab as Notes. KB browser by category.
235
+
236
+ **Endpoints (`dashboard.js`).**
237
+ - `GET /api/knowledge` (7146) — list KB grouped by category
238
+ - `POST /api/knowledge` (7147) — create entry directly
239
+ - `POST /api/knowledge/sweep` (7163) — async sweep
240
+ - `GET /api/knowledge/sweep/status` (7164) — poll sweep
241
+
242
+ **Relationships.** Inbox → KB → agent prompt context. Pinned notes (next entry) are a *subset* of
243
+ the KB.
244
+
245
+ ---
246
+
247
+ ## 7. Pinned Context (`pinned.md`)
248
+
249
+ **What it is.** Critical context the human flagged as "READ FIRST." Prepended to every agent
250
+ prompt regardless of work type. Use sparingly — pinned notes pollute every dispatch.
251
+
252
+ **Where it lives.** `pinned.md` (root). Index file: `engine/kb-pins.json` (`PINNED_ITEMS_PATH`,
253
+ `engine/shared.js` line 15).
254
+
255
+ **Backing classes / functions.**
256
+ - Add / remove handlers: `dashboard.js` lines 6891, 6895, 6908.
257
+ - Parser: `parsePinnedEntries` (referenced at line 6893).
258
+ - Slow-state cache invalidation explicitly on edits (`includeSlow: true`, line 6905).
259
+
260
+ **Existing dashboard.** `dashboard/pages/home.html` — "Pinned Context" widget. Pin / unpin
261
+ buttons appear in the KB browser.
262
+
263
+ **Endpoints (`dashboard.js`).**
264
+ - `GET /api/pinned` (6891)
265
+ - `POST /api/pinned` (6895) — add
266
+ - `POST /api/pinned/remove` (6908)
267
+
268
+ **Relationships.** Pinned ⊂ KB. Pinned content shows up in *every* agent prompt (even short
269
+ ones), so it's also coupled to **Charter** and **Routing** in terms of "what gets read first."
270
+
271
+ ---
272
+
273
+ ## 8. Notes Inbox
274
+
275
+ **What it is.** The waiting room for raw notes before consolidation. Files dropped into
276
+ `notes/inbox/` are the engine's signal that an agent succeeded; they get consolidated into
277
+ `notes.md` or promoted into the **KB** on a schedule.
278
+
279
+ **Where it lives.** `notes/inbox/*.md` (filename convention:
280
+ `<agent>-<work-item-id>-<date>-<time>.md`, with YAML frontmatter `id:`, `agent:`, `date:`).
281
+
282
+ **Backing classes / functions.**
283
+ - Inbox dir constant: `INBOX_DIR` in `engine/queries.js` (used at line 526).
284
+ - Consolidation tick path: `engine/consolidation.js` `consolidateInbox` line 24.
285
+ - Promote / delete API handlers: `handleInboxPersist`, `handleInboxPromoteKb`,
286
+ `handleInboxOpen`, `handleInboxDelete`.
287
+
288
+ **Existing dashboard.** `dashboard/pages/inbox.html` — note list, promote-to-KB buttons,
289
+ consolidate-now button.
290
+
291
+ **Endpoints (`dashboard.js`).**
292
+ - `POST /api/inbox/persist` (7172) — promote to `notes.md`
293
+ - `POST /api/inbox/promote-kb` (7173) — promote to KB category
294
+ - `POST /api/inbox/open` (7174) — reveal in OS file manager
295
+ - `POST /api/inbox/delete` (7175)
296
+
297
+ **Relationships.** Inbox is the staging area between **Notes** (the act of writing) and the
298
+ **KB** / `notes.md` (the durable store). Failure inboxes are explicitly forbidden by team rules.
299
+
300
+ ---
301
+
302
+ ## 9. Schedule (cron)
303
+
304
+ **What it is.** A recurring trigger that creates a Work Item on a cron pattern. The engine ticks
305
+ every 60 s; if a schedule's last-run was ≥ its interval ago and the cron pattern matches, the
306
+ engine drops a Work Item into the queue.
307
+
308
+ **Where it lives.**
309
+ - Definitions: `config.json` `schedules: []` (3-field cron `min hour dow`).
310
+ - Last-run history: `engine/schedule-runs.json`.
311
+
312
+ **Backing classes / functions.**
313
+ - Cron parser: `engine/scheduler.js`
314
+ - `parseCronField` line 63
315
+ - `parseCronExpr` line 106
316
+ - `shouldRunNow` line 145.
317
+ - Variable substitution: `resolveScheduleTemplateVars` line 46 (handles `{{date}}`, etc., before
318
+ the work item lands in the queue).
319
+ - Work-item factory: `createScheduledWorkItem` line 168.
320
+ - Tick path: `discoverScheduledWork` line 209.
321
+
322
+ **Existing dashboard.** `dashboard/pages/schedule.html` — schedule list, natural-language → cron
323
+ helper.
324
+
325
+ **Endpoints (`dashboard.js`).**
326
+ - `GET /api/schedules` (7200)
327
+ - `POST /api/schedules` (7201) — create
328
+ - `POST /api/schedules/update` (7202)
329
+ - `POST /api/schedules/delete` (7203)
330
+ - `POST /api/schedules/run-now` (7204)
331
+ - `POST /api/schedules/parse-natural` (7199) — natural-language → cron
332
+
333
+ **Relationships.** Schedule → emits Work Items into the **Dispatch Queue** on a cron. Closely
334
+ analogous to **Watch** (event-driven instead of time-driven).
335
+
336
+ ---
337
+
338
+ ## 10. Watch
339
+
340
+ **What it is.** A persistent monitor on a PR or Work Item that fires when a condition is met
341
+ (merged, build passes, build fails, status changes, new comments, vote changes). Watches are
342
+ event-driven, schedules are time-driven.
343
+
344
+ **Where it lives.** `engine/watches.json` (`engine/watches.js` line 17 `_watchesPath`).
345
+
346
+ **Backing classes / functions.**
347
+ - Status constants: `engine/shared.js` line 1380 (`WATCH_STATUS`).
348
+ - Condition constants: `WATCH_CONDITION` (same file, near 1380); fire-once set
349
+ `WATCH_ABSOLUTE_CONDITIONS`.
350
+ - CRUD: `engine/watches.js` `createWatch` line 44, `updateWatch` line 88, `deleteWatch`
351
+ line 116.
352
+ - Tick path: `evaluateWatch` line 138, `checkWatches` line 214 (runs every 3 ticks).
353
+ - State diff store: `_captureState` line 297 (`_lastState` per watch).
354
+
355
+ **Existing dashboard.** `dashboard/pages/watches.html` — watch list, condition picker.
356
+
357
+ **Endpoints (`dashboard.js`).**
358
+ - `GET /api/watches` (7207)
359
+ - `POST /api/watches` (7208) — create
360
+ - `POST /api/watches/update` (7209) — pause / resume / modify
361
+ - `POST /api/watches/delete` (7210)
362
+
363
+ **Relationships.** Watch ⇒ optionally re-fires (notify, dispatch, etc.) when its condition flips.
364
+ A merged-PR watch is the canonical "tell me when X ships" primitive.
365
+
366
+ ---
367
+
368
+ ## 11. Pipeline
369
+
370
+ **What it is.** A multi-stage workflow. Stages can be a Work Item (`task`), a `meeting`, or a
371
+ `plan`. Stages can declare dependencies on previous stages. Pipelines run via triggers (manual,
372
+ schedule, watch) and persist their state in `pipeline-runs.json`.
373
+
374
+ **Where it lives.**
375
+ - Definitions: `pipelines/*.json` (one file per pipeline).
376
+ - Run state: `engine/pipeline-runs.json`.
377
+
378
+ **Backing classes / functions.**
379
+ - Dirs: `engine/pipeline.js` lines 19–24 (`PIPELINES_DIR`, `PIPELINE_RUNS_PATH`, `PLANS_DIR`,
380
+ `PRD_DIR`).
381
+ - CRUD: `getPipelines` line 35, `getPipeline` line 53, `savePipeline` line 58, `deletePipeline`
382
+ line 63.
383
+ - Run lifecycle: `getActiveRun` line 80, `startRun` line 86, `updateRunStage` line 116,
384
+ `completeRun` line 127.
385
+
386
+ **Existing dashboard.** `dashboard/pages/pipelines.html` — pipeline editor, run history, stage
387
+ state.
388
+
389
+ **Endpoints (`dashboard.js`).**
390
+ - `GET /api/pipelines` (7213)
391
+ - `POST /api/pipelines` (7220) — create
392
+ - `POST /api/pipelines/update` (7232)
393
+ - `POST /api/pipelines/delete` (7248)
394
+ - `POST /api/pipelines/trigger` (7256)
395
+ - `POST /api/pipelines/continue` (7268) — past wait stage
396
+ - `POST /api/pipelines/abort` (7280)
397
+ - `POST /api/pipelines/retrigger` (7307)
398
+
399
+ **Relationships.** Pipeline = composer of Work Items / Meetings / Plans. Confusion vector:
400
+ unrelated to ADO/GitHub Actions pipelines, even though the word collides.
401
+
402
+ ---
403
+
404
+ ## 12. Dispatch
405
+
406
+ **What it is.** The act of taking a pending Work Item and spawning an agent process for it. A
407
+ dispatch holds the agent's PID, prompt sidecar path, worktree path, and current status until the
408
+ process exits.
409
+
410
+ **Where it lives.** Inside `engine/dispatch.json`'s `active[]` array.
411
+
412
+ **Backing classes / functions.**
413
+ - `mutateDispatch`: `engine/dispatch.js` line 60 (the only safe RMW path).
414
+ - `addToDispatch`: line 128.
415
+ - `findActivePrOrBranchLock`: line 112 (dedupe).
416
+ - `completeDispatch`: line 327.
417
+ - `cancelPendingDispatchesForPr`: line 550.
418
+ - Result codes: `engine/shared.js` line 1433 (`DISPATCH_RESULT`).
419
+
420
+ **Existing dashboard.** `dashboard/pages/engine.html` — dispatch log; `home.html` — "Dispatch
421
+ Queue" widget.
422
+
423
+ **Endpoints.** No public CRUD — dispatch is a side effect of `/api/work-items` and the engine
424
+ tick. Read shape via `/api/status` (line 6838).
425
+
426
+ **Relationships.** Dispatch wraps a **Work Item** + an **Agent** + a **Project** worktree. A
427
+ **Completion** is dispatch's exit signal.
428
+
429
+ ---
430
+
431
+ ## 13. Dispatch Queue
432
+
433
+ **What it is.** The three-bucket structure inside `engine/dispatch.json`:
434
+
435
+ - `pending[]` — admitted Work Items waiting on agent / dependency / cooldown / budget.
436
+ - `active[]` — currently spawned.
437
+ - `completed[]` — finished (success or failure), kept for audit until cleaned.
438
+
439
+ The queue's invariants are: max concurrent (default 5), per-PR / per-branch lock to avoid two
440
+ agents fighting on the same branch, dependency-aware spawning (`depends_on` IDs must be done
441
+ first), retry on failure up to `ENGINE_DEFAULTS.maxRetries`.
442
+
443
+ **Where it lives.** `engine/dispatch.json`.
444
+
445
+ **Backing classes / functions.** All in `engine/dispatch.js`. Mutation only via `mutateDispatch`
446
+ line 60. Queue dedupe keys: `getDispatchProjectKey` line 80, `getPrDispatchTargetKey` line 85,
447
+ `getPrDispatchDedupeKey` line 95, `getBranchDispatchLockKey` line 103.
448
+
449
+ **Existing dashboard.** `dashboard/pages/home.html` ("Dispatch Queue" section) and
450
+ `engine.html` (full log).
451
+
452
+ **Endpoints.** Read-only via `/api/status` (line 6838).
453
+
454
+ **Relationships.** Queue ⊃ Dispatches ⊃ Work Items. The queue is the engine's state of mind.
455
+
456
+ ---
457
+
458
+ ## 14. Completion
459
+
460
+ **What it is.** The structured report an agent writes before exit. JSON shape lives at the path
461
+ the engine puts in `MINIONS_COMPLETION_REPORT`. Fields: `status`, `summary`, `verdict`, `pr`,
462
+ `failure_class`, `retryable`, `needs_rerun`, `artifacts[]`. Fenced ` ```completion ` blocks in
463
+ stdout are also accepted as a fallback.
464
+
465
+ **Where it lives.**
466
+ - File path: `engine/completions/<dispatchId>.json` (built by `dispatchCompletionReportPath`,
467
+ `engine/shared.js` line 351).
468
+ - Field constants: `COMPLETION_FIELDS` (`engine/shared.js` line 1474–1475).
469
+
470
+ **Backing classes / functions.** Parsing happens during `completeDispatch` (`engine/dispatch.js`
471
+ line 327) and `engine/lifecycle.js`'s post-completion path (`syncPrsFromOutput` line 644).
472
+
473
+ **Existing dashboard.** `dashboard/pages/work.html` — completion details when an item is
474
+ expanded; `home.html` "Recent Completions" widget.
475
+
476
+ **Endpoints.** Read-only via `/api/status` and `/api/work-items/archive`.
477
+
478
+ **Relationships.** Completion sits between **Dispatch** (the run) and **Work Item** (the long-term
479
+ record). It also feeds **Pull Request** sync (`pr` field).
480
+
481
+ ---
482
+
483
+ ## 15. Pull Request (as tracked in minions)
484
+
485
+ **What it is.** A row in `projects/<name>/pull-requests.json`. Tracks status, vote tally, build
486
+ state, review verdict, and the work item that created it. *Not* the GitHub/ADO PR itself —
487
+ minions polls the host and writes a sanitized snapshot here.
488
+
489
+ **Where it lives.** `projects/<name>/pull-requests.json` (`projectPrPath`, `engine/shared.js`
490
+ line 1546). Cross-project links also tracked in `engine/pr-links.json`.
491
+
492
+ **Backing classes / functions.**
493
+ - Status / pollable constants: `engine/shared.js` line 1372 (`PR_STATUS`,
494
+ `PR_POLLABLE_STATUSES`).
495
+ - GitHub poller: `engine/github.js`.
496
+ - ADO poller: `engine/ado.js`.
497
+ - Parallel comment poller for human comments only (filters bots).
498
+ - Sync from agent output: `syncPrsFromOutput` (`engine/lifecycle.js` line 644).
499
+ - PR-attachment requirement check: `isPrAttachmentRequired` (line 875).
500
+
501
+ **Existing dashboard.** `dashboard/pages/prs.html` — the "Pull Requests" tab.
502
+
503
+ **Endpoints (`dashboard.js`).**
504
+ - `POST /api/pull-requests/link` (6974) — manually link external PR
505
+ - `POST /api/pull-requests/delete` (7030)
506
+
507
+ **Relationships.** PR ↔ Work Item is one-to-one in normal flow (review / fix work items can
508
+ re-attach to the same PR). PR ↔ Watch is one-to-many (you can watch the same PR with multiple
509
+ conditions).
510
+
511
+ ---
512
+
513
+ ## 16. Agent / Minion / Team Member
514
+
515
+ **What it is.** A named role with a charter, a skill list, a default CLI runtime, and metrics.
516
+ Examples: Ripley (architect / explorer), Dallas (engineer), Lambert (analyst), Rebecca
517
+ (architect), Ralph (engineer). Sometimes called "Minions" (the project's name), "Team Members"
518
+ (in the dashboard), or just "Agents" (in the code).
519
+
520
+ **Where it lives.**
521
+ - Default roster: `engine/shared.js` line 1486 (`DEFAULT_AGENTS`).
522
+ - Charter: `agents/<id>/charter.md` — read by `getAgentCharter` (`engine/queries.js` line 505).
523
+ - Per-agent config (cli, model, budget, skills): `config.json` `agents.<id>`.
524
+ - Metrics: `engine/metrics.json` (per-agent token / cost / quality / runtime).
525
+
526
+ **Backing classes / functions.**
527
+ - Charter loader: `engine/queries.js` line 505.
528
+ - Roster builder: `getAgents` line 509.
529
+ - Spawn entry: `engine/spawn-agent.js`.
530
+ - Charter injection into prompt: `engine/playbook.js` line 517.
531
+
532
+ **Existing dashboard.** `dashboard/pages/home.html` — "Minions Members" / agent cards.
533
+
534
+ **Endpoints.**
535
+ - `POST /api/agent-kill/:id` (line 3847)
536
+ - `GET /api/agent/:id/live-stream` (SSE — search for `/live-stream`)
537
+ - `GET /api/agent-detail/:id` (line 6686)
538
+
539
+ **Relationships.** Agent ↔ Charter (1:1), Agent ↔ Skill (1:N), Agent ↔ runtime (Claude or
540
+ Copilot via `resolveAgentCli`), Agent ↔ Work Item (N:N over history). Routing decides which agent
541
+ gets which work type.
542
+
543
+ ---
544
+
545
+ ## 17. Project
546
+
547
+ **What it is.** A repository the engine knows about. Has a name, local path, repo host
548
+ (`github` or `ado`), repository ID, main branch, and per-source toggles (`workSources`).
549
+
550
+ **Where it lives.**
551
+ - Definitions: `config.json` `projects: []`.
552
+ - State: `projects/<name>/{work-items.json, pull-requests.json}`.
553
+ - Removal artifact: `projects/.archived/<name>-YYYYMMDD/`.
554
+
555
+ **Backing classes / functions.**
556
+ - Helpers: `engine/shared.js`
557
+ - `getProjects` (~line 1502)
558
+ - `projectStateDir`, `projectWorkItemsPath` (~line 1530)
559
+ - `projectPrPath` (line 1546).
560
+ - Removal: `engine/projects.js` `removeProject` (canonical teardown — never edit `config.json`
561
+ directly).
562
+
563
+ **Existing dashboard.** `dashboard/pages/settings.html` — Projects section.
564
+
565
+ **Endpoints (`dashboard.js`).**
566
+ - `POST /api/projects/browse` (7181)
567
+ - `POST /api/projects/scan` (7182)
568
+ - `POST /api/projects/confirm-token` (7183) — SEC-05 single-use token
569
+ - `POST /api/projects/add` (7184)
570
+ - `POST /api/projects/remove` (7185)
571
+
572
+ **Relationships.** Project ⊃ Work Items, Pull Requests, Schedules (via `project` field), and
573
+ Pipelines that target it. The minions repo is special: it's the home of the engine itself.
574
+
575
+ ---
576
+
577
+ ## 18. Skill
578
+
579
+ **What it is.** A reusable prompt / workflow snippet under `.claude/skills/<name>/SKILL.md`.
580
+ Skills can be `scope: minions` (installed personally to the runtime's user dir) or
581
+ `scope: project` (PR'd into the project repo). Agents auto-extract skills from their output via
582
+ ` ```skill ` fenced blocks.
583
+
584
+ **Where it lives.**
585
+ - User skills: `~/.claude/skills/`, `~/.copilot/skills/`, etc. (runtime-specific).
586
+ - Project skills: `<project>/.claude/skills/`, `<project>/.github/skills/`.
587
+ - Frontmatter parser: `parseSkillFrontmatter` (`engine/shared.js`, exported line 14 of
588
+ `engine/queries.js`).
589
+
590
+ **Backing classes / functions.**
591
+ - Discovery: `engine/queries.js` `collectSkillFiles` line 789, `getSkills` line 891,
592
+ `getSkillIndex` line 916.
593
+ - Per-runtime roots: adapter `getSkillRoots()` / `getSkillWriteTargets()` (engine/runtimes/).
594
+
595
+ **Existing dashboard.** `dashboard/pages/tools.html` — skill browser.
596
+
597
+ **Endpoints.**
598
+ - `GET /api/skill` (line 7178) — read a single skill file.
599
+
600
+ **Relationships.** Skill ↔ Runtime adapter (storage paths differ). Skills ↔ Agent prompts
601
+ (skills can be invoked mid-task).
602
+
603
+ ---
604
+
605
+ ## 19. MCP Server
606
+
607
+ **What it is.** A Model Context Protocol server the runtime CLI can call. Examples: GitHub MCP,
608
+ Azure DevOps MCP, custom tool servers. Configured per-fleet and per-runtime; agents see them as
609
+ extra tools.
610
+
611
+ **Where it lives.**
612
+ - Configuration: `config.json` `mcpServers: { … }`.
613
+ - Aggregator: `getMcpServers` in `dashboard.js` line 759 (also re-reads runtime-specific
614
+ configs at lines 750–787, e.g. `~/.copilot/mcp-config.json`, `~/.claude/mcp-config.json`).
615
+
616
+ **Backing classes / functions.**
617
+ - Loader: `dashboard.js` line 759 (`getMcpServers`).
618
+ - Engine status integration: `getStatusJson` includes `mcpServers` (line 905).
619
+ - Per-runtime adapter knobs: `engine.copilotDisableBuiltinMcps` (default true) strips the
620
+ built-in `github-mcp-server` because it would mutate state behind the engine's back.
621
+
622
+ **Existing dashboard.** `dashboard/pages/tools.html` — MCP server list with status.
623
+
624
+ **Endpoints.** Read-only via `/api/status`. There is no dedicated MCP CRUD endpoint —
625
+ configuration is via `/api/settings` (config.json edits).
626
+
627
+ **Relationships.** MCP ↔ Runtime (Copilot has built-in MCPs that we explicitly disable). MCP ↔
628
+ Skill is unrelated; skills are prompt-level, MCPs are tool-level.
629
+
630
+ ---
631
+
632
+ ## 20. Engine
633
+
634
+ **What it is.** The orchestrator daemon. One Node process; runs a 60 s tick that drains the
635
+ **Dispatch Queue**, polls **PRs**, evaluates **Watches** every 3 ticks, runs **Schedules**,
636
+ consolidates the **Inbox**, and so on. It's also the gatekeeper for control state
637
+ (`paused | running | stopping`).
638
+
639
+ **Where it lives.**
640
+ - Process: `engine.js` (root).
641
+ - State: `engine/control.json` (mode), `engine/log.json` (audit ring buffer, max 2500 trimmed
642
+ to 2000), `engine/metrics.json` (counters), `engine/dispatch.json` (queue).
643
+
644
+ **Backing classes / functions.**
645
+ - Tick: `engine.js` (top-level `tick()`).
646
+ - Defaults: `engine/shared.js` line 860 (`ENGINE_DEFAULTS`).
647
+ - Concurrency caps: `mutateJsonFileLocked` for all shared-JSON RMW.
648
+ - Restart re-attach: PID files in `engine/tmp/pid-<id>.pid` + `live-output.log` mtimes,
649
+ 20-min grace.
650
+
651
+ **Existing dashboard.** `dashboard/pages/engine.html` — engine timeline, log, controls.
652
+
653
+ **Endpoints.**
654
+ - `POST /api/engine/wakeup` (7406) — set `_wakeupAt` so the tick fires now.
655
+ - `POST /api/engine/restart` (7410) — graceful restart.
656
+ - `GET /api/status` (6838), `/api/health` (6844), `/api/status-stream` (6839, SSE).
657
+
658
+ **Relationships.** Engine = the verb. Every other concept on this page is the engine's data.
659
+
660
+ ---
661
+
662
+ ## 21. Settings
663
+
664
+ **What it is.** `config.json`. Holds projects, agents, engine defaults, schedules, features, and
665
+ runtime knobs. Merged with `.claude/settings.local.json` for user-only overrides.
666
+
667
+ **Where it lives.** `config.json` (root); `.claude/settings.local.json` (gitignored).
668
+
669
+ **Backing classes / functions.**
670
+ - Loader: `engine/queries.js` `getConfig` (around line 86–166, includes migrations like
671
+ `applyLegacyCcModelMigration`).
672
+ - Defaults: `engine/shared.js` line 860 (`ENGINE_DEFAULTS`).
673
+ - Routing knob: `routing.md` (separate file).
674
+
675
+ **Existing dashboard.** `dashboard/pages/settings.html` — multi-tab editor for engine, projects,
676
+ agents, runtimes.
677
+
678
+ **Endpoints (`dashboard.js`).**
679
+ - Settings reads / writes are via the `/api/settings*` family (search for them in the ROUTES
680
+ table around 6249–6599 in earlier dashboard.js layouts; the agent-driven version uses the
681
+ ROUTES registry).
682
+ - `POST /api/settings/reset` — restore defaults.
683
+ - `POST /api/settings/routing` — read `routing.md`.
684
+
685
+ **Relationships.** Settings is the *write target* for almost every config-changing action in CC
686
+ and the dashboard. Two locations to know about: per-fleet (`engine.*`) and per-agent
687
+ (`agents.<id>.*`). They don't fall through to each other for runtime selection.
688
+
689
+ ---
690
+
691
+ ## 22. Feature Flag
692
+
693
+ **What it is.** A temporary gate registered in `engine/features.js`. Resolved per request:
694
+ env var (`MINIONS_FEATURE_<UPPER_SNAKE>`) → `config.features[id]` → registry default. Throws if
695
+ asked for an unknown id. The slim UX itself is gated behind `slim-ux`.
696
+
697
+ **Where it lives.** `engine/features.js` lines 1–62 (registry + `isFeatureOn`).
698
+
699
+ **Backing classes / functions.**
700
+ - Registry: `FEATURES` (top of `engine/features.js`).
701
+ - Resolver: `isFeatureOn(id, config)`.
702
+ - Env override: any `MINIONS_FEATURE_*` translates id `slim-ux` ↔ `MINIONS_FEATURE_SLIM_UX`.
703
+
704
+ **Existing dashboard.** `dashboard/pages/settings.html` — "Show experimental flags" disclosure.
705
+ Slim UX also has its own minimal flags-only settings dialog (`dashboard/slim.html` line ~445).
706
+
707
+ **Endpoints (`dashboard.js`).**
708
+ - `GET /api/features` (7457)
709
+ - `POST /api/features/toggle` (7458)
710
+
711
+ **Relationships.** Feature flag ↔ everything that gets ramped behind one. When the feature
712
+ ships, *delete the registry entry and the gate* — stale entries past `expires` surface in
713
+ preflight.
714
+
715
+ ---
716
+
717
+ ## 23. Routing (`routing.md`)
718
+
719
+ **What it is.** A markdown table mapping work types to agents (e.g. `implement → dallas`,
720
+ `review → ripley`, `fix → _author_`). The engine parses it on every tick.
721
+
722
+ **Where it lives.** `routing.md` (root).
723
+
724
+ **Backing classes / functions.**
725
+ - Parser: `engine/routing.js` `parseRoutingTable` line 31.
726
+ - Path constant: line 15.
727
+ - Cache: line 59 (`_routingCache`).
728
+ - Re-export: line 301.
729
+
730
+ **Existing dashboard.** `dashboard/pages/settings.html` — Routing panel (read-only with an edit
731
+ modal).
732
+
733
+ **Endpoints.**
734
+ - `POST /api/settings/routing` — read `routing.md`.
735
+
736
+ **Relationships.** Routing decides which **Agent** receives which **Work Type**. The CC action
737
+ parser pre-flights routing to surface "no agent available" warnings before enqueue. Per-project
738
+ overrides are possible via `projects/<name>/routing.md`.
739
+
740
+ ---
741
+
742
+ ## 24. Charter (Agent Charter)
743
+
744
+ **What it is.** A short markdown file describing an agent's role, voice, and rules of engagement.
745
+ Loaded into the agent's system prompt at every dispatch.
746
+
747
+ **Where it lives.** `agents/<id>/charter.md`. Examples: `agents/dallas/charter.md`,
748
+ `agents/ripley/charter.md`, …
749
+
750
+ **Backing classes / functions.**
751
+ - Loader: `engine/queries.js` `getAgentCharter` line 505.
752
+ - Injection into prompt: `engine/playbook.js` line 517 (`prompt += '## Your Charter\n\n' +
753
+ charter`).
754
+
755
+ **Existing dashboard.** Agent detail modal on `home.html` shows the charter.
756
+
757
+ **Endpoints.** Read-only via `/api/agent-detail/:id` (line 6686).
758
+
759
+ **Relationships.** Charter ↔ Agent (1:1). Distinct from Skills (skills are reusable work
760
+ recipes; charter is identity).
761
+
762
+ ---
763
+
764
+ ## 25. Meeting
765
+
766
+ **What it is.** A multi-agent debate workflow. Three rounds: investigate → debate → conclude.
767
+ Participants are explicitly listed; each round writes a structured findings file before the
768
+ engine advances. The engine times out / advances rounds automatically.
769
+
770
+ **Where it lives.** `meetings/*.json` (definitions + transcripts). Per-agent artifact notes
771
+ land in `notes/inbox/`.
772
+
773
+ **Backing classes / functions.**
774
+ - Dirs / status: `engine/meeting.js`
775
+ - lines 21–24 (`MEETINGS_DIR`, `MEETING_NOTE_ARTIFACT_ROOT`, `TERMINAL_MEETING_STATUSES`,
776
+ `ROUND_STATUS_BY_NAME`).
777
+ - line 29 (`ROUND_NUMBER_BY_NAME`).
778
+ - Round bookkeeping: `roundKeyFor` line 40, `getRoundFailures` line 46, `hasRoundFailure`
779
+ line 59, `hasRoundSuccess` line 63, `hasRoundTerminalOutcome` line 69,
780
+ `allParticipantsFinishedRound` line 73.
781
+ - Advance / fail handling: `advanceMeetingIfRoundComplete` line 93,
782
+ `buildFailedMeetingConclusion` line 87.
783
+ - Empty-output detection: `EMPTY_OUTPUT_PATTERNS` line 15, `isEmptyMeetingContent` line 124.
784
+
785
+ **Existing dashboard.** `dashboard/pages/meetings.html` — meeting browser, round status, notes.
786
+
787
+ **Endpoints (`dashboard.js`).**
788
+ - `POST /api/meetings` (7322) — create
789
+ - `GET /api/meetings` (7337)
790
+ - `POST /api/meetings/note` (7349)
791
+ - `POST /api/meetings/advance` (7359)
792
+ - `POST /api/meetings/end` (7369)
793
+ - `POST /api/meetings/archive` (7378)
794
+ - `POST /api/meetings/unarchive` (7387)
795
+ - `POST /api/meetings/delete` (7396)
796
+
797
+ **Relationships.** Meeting → emits Notes into the inbox. Each meeting round dispatches one Work
798
+ Item per participant. Pipelines may include `meeting` stages.
799
+
800
+ ---
801
+
802
+ ## Cross-cutting relationship cheatsheet
803
+
804
+ ```
805
+ Human ──► Command Center ──► [Work Item | Plan | Note | Schedule | Watch | Pinned | Knowledge]
806
+
807
+ └─► Dispatch Queue ──► Dispatch ──► Agent (CLI)
808
+
809
+ ├─► Pull Request (synced from output)
810
+ ├─► Completion (JSON report)
811
+ └─► Notes Inbox ──► Consolidation ──► KB / notes.md
812
+
813
+ └─► Pinned (manual subset)
814
+
815
+ Plan ──► PRD ──► Work Items (depends_on edges) ──► … ──► Verify Work Item ──► Manual Archive
816
+
817
+ Pipeline (stages: task / meeting / plan) ──► spawns Work Items / Meetings / Plans
818
+
819
+ Schedule (cron) ──► spawns Work Items
820
+ Watch (event) ──► spawns notifications / Work Items / pipeline-continuations
821
+
822
+ Engine reads: routing.md, config.json, all state JSON
823
+ Engine writes: control.json, log.json, metrics.json, dispatch.json, project state files
824
+ ```