@yemi33/minions 0.1.2424 → 0.1.2425
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.
- package/bin/install-internal-minions.js +1209 -0
- package/bin/minions.js +75 -9
- package/dashboard/docs/typography.md +27 -12
- package/dashboard/js/command-center.js +13 -11
- package/dashboard/js/live-stream.js +1 -1
- package/dashboard/js/memory-search.js +388 -43
- package/dashboard/js/modal-qa.js +5 -5
- package/dashboard/js/qa.js +39 -26
- package/dashboard/js/refresh.js +37 -18
- package/dashboard/js/render-agents.js +14 -18
- package/dashboard/js/render-dispatch.js +14 -74
- package/dashboard/js/render-inbox.js +3 -3
- package/dashboard/js/render-meetings.js +8 -8
- package/dashboard/js/render-other.js +45 -20
- package/dashboard/js/render-pipelines.js +6 -6
- package/dashboard/js/render-plans.js +14 -14
- package/dashboard/js/render-prd.js +46 -46
- package/dashboard/js/render-prs.js +9 -65
- package/dashboard/js/render-schedules.js +5 -5
- package/dashboard/js/render-skills.js +6 -6
- package/dashboard/js/render-utils.js +4 -4
- package/dashboard/js/render-watches.js +4 -16
- package/dashboard/js/render-work-items.js +95 -107
- package/dashboard/js/settings.js +175 -74
- package/dashboard/layout.html +3 -2
- package/dashboard/pages/inbox.html +1 -1
- package/dashboard/pages/work.html +1 -1
- package/dashboard/shared/model-display.js +9 -0
- package/dashboard/shared/watches-source.js +43 -0
- package/dashboard/shared/welcome-popup.js +259 -0
- package/dashboard/slim/body.html +6 -6
- package/dashboard/slim/js/chat.js +4 -2
- package/dashboard/slim/js/history.js +10 -3
- package/dashboard/slim/js/modals-tiles.js +85 -16
- package/dashboard/slim/js/status.js +12 -16
- package/dashboard/slim/styles.css +24 -4
- package/dashboard/styles.css +62 -27
- package/dashboard-build.js +8 -2
- package/dashboard.js +3854 -2514
- package/docs/README.md +6 -4
- package/docs/api-errors.md +144 -0
- package/docs/auto-discovery.md +83 -61
- package/docs/capture-demos.js +173 -30
- package/docs/command-center.md +5 -1
- package/docs/completion-reports.md +127 -11
- package/docs/constants.md +15 -3
- package/docs/constellation-style-telemetry.md +2 -2
- package/docs/copilot-cli-schema.md +32 -22
- package/docs/cross-repo-plans.md +30 -30
- package/docs/demo/memory-system.html +1 -1
- package/docs/deprecated.json +132 -18
- package/docs/diagnostics-memory.md +8 -4
- package/docs/human-vs-automated.md +2 -2
- package/docs/internal-install.md +190 -0
- package/docs/kb-pr3223-cascade-archiving.md +16 -0
- package/docs/kb-pr696-merge-conflict-docs.md +23 -0
- package/docs/kb-sweep.md +2 -2
- package/docs/keep-processes.md +8 -1
- package/docs/live-checkout-mode.md +1 -1
- package/docs/managed-spawn.md +21 -3
- package/docs/named-agents.md +3 -2
- package/docs/plan-lifecycle.md +32 -32
- package/docs/pr-screenshots/pr-899/worker-pool-worktrees-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-899/worker-pool-worktrees-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-979/auto-fix-pane-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-979/auto-fix-pane-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-985/pr-column-em-dash-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-985/pr-column-em-dash-BEFORE.png +0 -0
- package/docs/qa-runbook-lifecycle.md +67 -51
- package/docs/qa-runbooks.md +2 -2
- package/docs/runtime-adapters.md +101 -50
- package/docs/security.md +28 -0
- package/docs/self-improvement.md +47 -13
- package/docs/skills.md +29 -0
- package/docs/slim-ux/concepts.md +2 -2
- package/docs/specs/agent-configurability.md +43 -41
- package/docs/specs/agent-rename.md +13 -13
- package/docs/team-memory.md +283 -14
- package/docs/tutorials/03-plan-driven-feature.md +3 -3
- package/docs/tutorials/04-runtimes-and-harness.md +18 -21
- package/docs/tutorials/08-operations-and-recovery.md +3 -2
- package/docs/tutorials/README.md +4 -3
- package/docs/visual-evidence-ci.md +103 -0
- package/docs/watches.md +35 -30
- package/docs/worktree-lifecycle.md +151 -13
- package/engine/acp-transport.js +1 -0
- package/engine/ado.js +80 -33
- package/engine/agent-api-validation.js +571 -0
- package/engine/agent-worker-pool.js +7 -6
- package/engine/api-contracts/agent-content.js +761 -0
- package/engine/api-contracts/cc-ops.js +219 -0
- package/engine/api-contracts/config-runtime.js +419 -0
- package/engine/api-contracts/core.js +138 -0
- package/engine/api-contracts/index.js +506 -0
- package/engine/api-contracts/orchestration.js +602 -0
- package/engine/api-contracts/pull-requests.js +323 -0
- package/engine/api-contracts/qa-process.js +764 -0
- package/engine/api-contracts/work-plan-prd.js +494 -0
- package/engine/api-validation.js +543 -0
- package/engine/cc-api-validation.js +586 -0
- package/engine/cc-worker-pool.js +9 -1
- package/engine/cleanup.js +393 -271
- package/engine/cli.js +65 -7
- package/engine/comment-classifier.js +70 -5
- package/engine/consolidation.js +123 -5
- package/engine/content-api-validation.js +606 -0
- package/engine/create-pr-worktree.js +22 -1
- package/engine/db/migrations/027-review-learning-lifecycle.js +162 -0
- package/engine/dispatch.js +33 -0
- package/engine/distribution.js +189 -0
- package/engine/execution-model.js +59 -0
- package/engine/features.js +12 -0
- package/engine/github.js +67 -25
- package/engine/harness-context.js +313 -0
- package/engine/inbox-store.js +1 -1
- package/engine/kb-sweep.js +161 -38
- package/engine/keep-process-sweep.js +43 -3
- package/engine/lifecycle.js +1066 -165
- package/engine/llm.js +4 -0
- package/engine/managed-spawn.js +463 -48
- package/engine/meeting.js +197 -34
- package/engine/memory-retrieval.js +280 -0
- package/engine/memory-store.js +821 -38
- package/engine/model-discovery.js +17 -3
- package/engine/pipeline.js +802 -14
- package/engine/plan-prd-validation.js +745 -0
- package/engine/playbook.js +206 -17
- package/engine/pooled-agent-process.js +6 -1
- package/engine/pr-action.js +1 -1
- package/engine/pr-issue-validation.js +653 -0
- package/engine/pr-resolve.js +75 -13
- package/engine/prd-store.js +39 -6
- package/engine/preflight.js +7 -2
- package/engine/process-utils.js +79 -31
- package/engine/projects.js +198 -12
- package/engine/promotion.js +371 -0
- package/engine/qa-from-prd.js +3 -0
- package/engine/qa-process-validation.js +572 -0
- package/engine/qa-runbooks.js +41 -37
- package/engine/qa-runners/maestro.js +11 -7
- package/engine/qa-runners/playwright.js +37 -14
- package/engine/qa-runners.js +9 -10
- package/engine/qa-runs.js +124 -11
- package/engine/qa-sessions.js +139 -40
- package/engine/quarantine-refs.js +81 -11
- package/engine/queries.js +163 -9
- package/engine/review-learning-backfill.js +482 -0
- package/engine/review-learning.js +1236 -0
- package/engine/runtimes/claude.js +60 -2
- package/engine/runtimes/codex.js +57 -16
- package/engine/runtimes/contract.js +21 -0
- package/engine/runtimes/copilot.js +51 -3
- package/engine/runtimes/index.js +1 -0
- package/engine/scheduler.js +201 -32
- package/engine/settings-validation.js +909 -0
- package/engine/shared.js +705 -208
- package/engine/spawn-agent.js +48 -21
- package/engine/steering-constraints.js +31 -0
- package/engine/steering-store.js +10 -2
- package/engine/steering.js +14 -2
- package/engine/timeout.js +404 -111
- package/engine/untrusted-fence.js +24 -10
- package/engine/watch-actions.js +7 -2
- package/engine/watches.js +353 -51
- package/engine/work-item-validation.js +561 -0
- package/engine/work-items-store.js +61 -1
- package/engine/worktree-gc.js +656 -37
- package/engine/worktree-preflight.js +154 -0
- package/engine.js +2068 -342
- package/package.json +1 -1
- package/playbooks/_pr-description-audit.md +88 -41
- package/playbooks/build-fix-complex.md +3 -3
- package/playbooks/docs.md +2 -2
- package/playbooks/fix.md +18 -18
- package/playbooks/implement.md +18 -18
- package/playbooks/qa-session-draft.md +10 -12
- package/playbooks/qa-session-execute.md +16 -12
- package/playbooks/qa-validate.md +8 -7
- package/playbooks/shared-rules.md +45 -0
- package/playbooks/test.md +4 -0
- package/prompts/cc-system.md +1 -1
- package/skills/check-self-authored-review-comment/SKILL.md +2 -2
|
@@ -10,18 +10,18 @@ W-mpdad3mq000m53bb).
|
|
|
10
10
|
## Runbook location
|
|
11
11
|
|
|
12
12
|
`<MINIONS_DIR>/projects/<project-name>/runbooks/<runbook-id>.json`. Each entry:
|
|
13
|
-
`{ id, name,
|
|
14
|
-
CRUD via `GET/POST /api/qa/runbooks
|
|
15
|
-
|
|
13
|
+
`{ id, name, project, targetName, steps, expectedArtifacts, createdAt, updatedAt }`.
|
|
14
|
+
CRUD via `GET/POST /api/qa/runbooks`; POST accepts the full spec, including the
|
|
15
|
+
caller-supplied kebab-case `id`, and returns the saved record. `targetName` is a name from `/api/managed-processes` or
|
|
16
16
|
`/api/keep-processes` (deduped by `<project>::<name>`, managed wins).
|
|
17
17
|
|
|
18
18
|
## Run-record path
|
|
19
19
|
|
|
20
|
-
The SQL `qa_runs` table stores newest-first
|
|
21
|
-
`{ id, runbookId,
|
|
22
|
-
`status` ∈ `pending|
|
|
23
|
-
`POST /api/qa/runbooks/run` (`{
|
|
24
|
-
work item and seeds the run with `
|
|
20
|
+
The SQL `qa_runs` table stores capped run records, sorted newest-first on read. Each run:
|
|
21
|
+
`{ id, runbookId, targetName, project, workItemId, status, startedAt, completedAt, artifacts, summary, createdAt }`.
|
|
22
|
+
`status` ∈ `pending|running|passed|failed|errored`. Created by
|
|
23
|
+
`POST /api/qa/runbooks/run` (`{ runbookId, targetName, agent? }`), which dispatches a `qa-validate`
|
|
24
|
+
work item and seeds the run with `pending`. Read via
|
|
25
25
|
`GET /api/qa/runs?limit=50` — UI polls every 5s while the QA page is active
|
|
26
26
|
and clears the interval on page navigation via the `switchPage` wrapper in
|
|
27
27
|
`dashboard/js/qa.js` (matches `_stopPlanPoll`/`_stopMeetingPoll` pattern in
|
|
@@ -49,46 +49,53 @@ only), confirms with the user, and surfaces success/error via
|
|
|
49
49
|
|
|
50
50
|
## Artifact contract
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
`GET /api/qa/artifacts/<runId>/<
|
|
54
|
-
|
|
55
|
-
`
|
|
52
|
+
Artifacts live at `<MINIONS_DIR>/engine/qa-artifacts/<runId>/<path>`, served via
|
|
53
|
+
`GET /api/qa/artifacts/<runId>/<path>`. `createRun()` pre-creates the per-run
|
|
54
|
+
directory, and the rendered QA prompt injects its absolute path as
|
|
55
|
+
`qa_artifacts_dir` so project-worktree agents write to the engine-owned
|
|
56
|
+
directory rather than their disposable worktree. The agent lists metadata in
|
|
57
|
+
the result sidecar using paths relative to the run's artifact directory as
|
|
58
|
+
`artifacts: [{ type, path, label, capturedAt }]`. UI auto-detects:
|
|
56
59
|
`screenshot`/`png|jpg|jpeg|gif|webp|svg` → `<img>`;
|
|
57
60
|
`video`/`mp4|webm|ogg|mov` → `<video controls>`; everything else → log
|
|
58
61
|
preview (first 40 lines fetched lazily) with a `View full` link to the same
|
|
59
62
|
endpoint. **No direct filesystem paths are exposed** — every artifact URL
|
|
60
63
|
goes through `/api/qa/artifacts/` so path traversal is server-gated.
|
|
61
|
-
|
|
62
|
-
when set, dashboard Settings exposes a matching toggle (CLAUDE.md
|
|
63
|
-
best-practice #15).
|
|
64
|
+
There is no configurable per-file size cap or completion-time copy step.
|
|
64
65
|
|
|
65
66
|
## Agent sidecar shape
|
|
66
67
|
|
|
67
|
-
The
|
|
68
|
+
The retired draft path `agents/<id>/qa-run.json` is not consumed.
|
|
69
|
+
The `qa-validate` agent writes the injected absolute `qa_result_sidecar` path,
|
|
70
|
+
which resolves to `<MINIONS_DIR>/agents/<id>/qa-run-result.json`, before exit:
|
|
68
71
|
|
|
69
72
|
```json
|
|
70
|
-
{ "runId": "
|
|
71
|
-
"status": "passed|failed|
|
|
73
|
+
{ "runId": "qarun-<id>",
|
|
74
|
+
"status": "passed|failed|errored",
|
|
72
75
|
"summary": "...",
|
|
73
|
-
"artifacts": [
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
"artifacts": [
|
|
77
|
+
{ "type": "screenshot", "path": "engine/qa-artifacts/<runId>/dashboard.png",
|
|
78
|
+
"label": "Dashboard", "capturedAt": "2026-05-20T20:42:00.000Z" },
|
|
79
|
+
{ "type": "log", "path": "engine/qa-artifacts/<runId>/test.log",
|
|
80
|
+
"label": "Test log", "capturedAt": "2026-05-20T20:42:00.000Z" }
|
|
81
|
+
] }
|
|
76
82
|
```
|
|
77
83
|
|
|
78
|
-
|
|
79
|
-
`
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
Before spawning a run, the engine removes any prior sidecar for that agent.
|
|
85
|
+
`runPostCompletionHooks` then verifies `runId` matches the current run, consumes
|
|
86
|
+
the file exactly once, and stamps the run record with `status`, `completedAt`,
|
|
87
|
+
`summary`, and normalized artifact metadata. Missing, malformed, stale-run, or
|
|
88
|
+
unknown-status sidecars mark the run `errored`. Lifecycle does not copy
|
|
89
|
+
or size-check artifact files; agents must write them to the injected absolute
|
|
90
|
+
artifact directory before exit.
|
|
84
91
|
|
|
85
92
|
## Entry point
|
|
86
93
|
|
|
87
94
|
`playbooks/qa-validate.md`. Dispatched by `POST /api/qa/runbooks/run`;
|
|
88
|
-
receives `target`, `steps`, `expectedArtifacts`
|
|
89
|
-
to write the sidecar above
|
|
90
|
-
the synthetic `qa-validate`
|
|
91
|
-
work too.
|
|
95
|
+
receives `target`, `steps`, `expectedArtifacts`, `qa_artifacts_dir`, and
|
|
96
|
+
`qa_result_sidecar` as template vars; required to write the sidecar above
|
|
97
|
+
before exit. Routing line in `routing.md` maps the synthetic `qa-validate`
|
|
98
|
+
task-type to the playbook so manual dispatches work too.
|
|
92
99
|
|
|
93
100
|
# QA Sessions (PL-qa-sessions)
|
|
94
101
|
|
|
@@ -182,16 +189,17 @@ routing default):
|
|
|
182
189
|
metadata via `/api/managed-processes/by-name/qa-session-<id>`, calls the
|
|
183
190
|
resolved runner's `generateBrief({target, flowsRaw, capture})` hook, and
|
|
184
191
|
writes the runner-native test file to
|
|
185
|
-
`engine/qa-tests/<sessionId>/test.<ext
|
|
186
|
-
`
|
|
187
|
-
|
|
188
|
-
|
|
192
|
+
the injected absolute `engine/qa-tests/<sessionId>/test.<ext>` path.
|
|
193
|
+
The completion report's `testFile` value is stored on the session. In
|
|
194
|
+
`confirm` mode the session parks at `awaiting-approval`; in `auto` mode
|
|
195
|
+
it auto-chains to EXECUTE.
|
|
189
196
|
|
|
190
197
|
3. **EXECUTE** (`playbooks/qa-session-execute.md`) runs the drafted test
|
|
191
198
|
against the live spawn via the runner's `executeBrief` hook, captures
|
|
192
199
|
artifacts per `spec.capture: { video, screenshots, logs }`, and writes
|
|
193
|
-
`
|
|
194
|
-
`qa-validate` runbook flow uses.
|
|
200
|
+
the injected absolute `qa_result_sidecar` path — the same single-use sidecar
|
|
201
|
+
the `qa-validate` runbook flow uses. Artifacts go to the injected absolute
|
|
202
|
+
`qa_artifacts_dir` keyed by the linked QA run id, not the session id. The
|
|
195
203
|
`engine/lifecycle.js#runPostCompletionHooks` `meta.qaRunId` hook ingests
|
|
196
204
|
the sidecar and marks the linked `qa-runs` record terminal; the
|
|
197
205
|
session-level `handleExecuteComplete` then reads the `qa-run` terminal
|
|
@@ -212,20 +220,27 @@ Documented in `dashboard.js`; routes are visible at `GET /api/routes`.
|
|
|
212
220
|
| POST | `/api/qa/from-prd` | "qa this PRD" bridge. Build a QA Session spec from a completed/approved PRD via `engine/qa-from-prd.js` (pure) then reuse `createSession` + `queueSetup`. Body: `{ prd, mode?, runner? }`. Non-ready / unknown / malformed PRD → **400** (`QaFromPrdError.reason`). Returns `sessionId`, `state`, `setupWorkItemId`, `managedSpawnName`, `projects`, `flowSource`, `warnings[]`, `note` (repo-native-harness copy), and optional `runnerHint`. The test is drafted on the repo's native test harness. |
|
|
213
221
|
| GET | `/api/qa/sessions` | List sessions newest-first. Optional `?limit=N` and `?state=pending\|spawning\|drafting\|awaiting-approval\|executing\|done\|failed\|killed`. |
|
|
214
222
|
| GET | `/api/qa/sessions/<id>` | Fetch a single session record by id. |
|
|
215
|
-
| POST | `/api/qa/sessions/<id>/approve` | `awaiting-approval → executing`. Server-side creates the linked `qa-runs` record (synthetic `runbookId='qa-session-<id>'`), queues EXECUTE WI, stamps `qaRunId` on the session. |
|
|
223
|
+
| POST | `/api/qa/sessions/<id>/approve` | `awaiting-approval → executing`. Accepts no request body. Server-side creates the linked `qa-runs` record (synthetic `runbookId='qa-session-<id>'`), queues EXECUTE WI, stamps `qaRunId` on the session. |
|
|
216
224
|
| POST | `/api/qa/sessions/<id>/edit` | `awaiting-approval → drafting`. Body: `{ feedback }`. Re-fires DRAFT with the reviewer feedback threaded into the prompt. |
|
|
217
225
|
| POST | `/api/qa/sessions/<id>/cancel` | Non-terminal → `killed`. Optional `{ reason }`. Does NOT touch the managed-spawn — use `/kill` for that. |
|
|
218
|
-
| POST | `/api/qa/sessions/<id>/kill` | Non-terminal → `killed
|
|
226
|
+
| POST | `/api/qa/sessions/<id>/kill` | Non-terminal → `killed`, then generation-safely removes the primary and every multi-project co-service managed-spawn. Best-effort when a spawn is absent or concurrently replaced. |
|
|
219
227
|
| POST | `/api/qa/sessions/<id>/dismiss` | Non-terminal → `done`. Accept the draft as final; leaves spawn alive. Optional `{ summary }`. |
|
|
220
228
|
| GET | `/api/qa/runners` | List registered runner adapters (built-ins + `qa-runners.d/` plugins). Metadata only — hooks (functions) are stripped. |
|
|
221
|
-
| POST | `/api/qa/runners/reload` |
|
|
229
|
+
| POST | `/api/qa/runners/reload` | Accepts no request body. Clears the in-process registry, re-registers built-ins, re-scans `qa-runners.d/` for plugin edits, and returns the fresh runner list. |
|
|
222
230
|
| DELETE | `/api/qa/runs/<id>` | Hard-delete a single QA run record (terminal-status runs only) and best-effort wipe its artifact directory under `engine/qa-artifacts/<runId>/`. Returns `{ ok: true, id, artifactsRemoved }` on success, `409 not_terminal` for in-flight runs, `404 not_found` for unknown ids. |
|
|
223
231
|
|
|
232
|
+
The audited contracts returned by `GET /api/routes` expose the canonical enum,
|
|
233
|
+
length, list, nested-field, path, and lifecycle constraints for these routes.
|
|
234
|
+
Validation failures use field/path-aware details and occur before QA records,
|
|
235
|
+
work items, runbooks, plugins, artifacts, or managed processes are mutated.
|
|
236
|
+
Traversal remains `403`, missing resources `404`, and wrong-state conflicts
|
|
237
|
+
`409`.
|
|
238
|
+
|
|
224
239
|
The single-session POSTs share `_qaSessionAction` in `dashboard.js`; module
|
|
225
240
|
errors are mapped to HTTP via `_qaSessionsErrorToStatus`:
|
|
226
241
|
|
|
227
242
|
- `'session not found'` → 404
|
|
228
|
-
- `'unsafe sessionId'` / `'invalid spec'` / `'requires …'` (
|
|
243
|
+
- `'unsafe sessionId'` / `'invalid spec'` / `'requires …'` / `'exceeds …'` (spec or feedback validation) → 400
|
|
229
244
|
- `'illegal state transition'` / `'requires state …'` / `'requires non-terminal'` → 409
|
|
230
245
|
|
|
231
246
|
## File locations
|
|
@@ -243,14 +258,14 @@ errors are mapped to HTTP via `_qaSessionsErrorToStatus`:
|
|
|
243
258
|
session's `cancelSession` if the operator opts for the cancel-without-
|
|
244
259
|
spawn-kill path.
|
|
245
260
|
- **EXECUTE artifacts**: same as runbooks — `engine/qa-artifacts/<runId>/`
|
|
246
|
-
served via `GET /api/qa/artifacts/<runId>/<
|
|
261
|
+
served via `GET /api/qa/artifacts/<runId>/<path>`.
|
|
247
262
|
|
|
248
263
|
## Runner adapters (P-c4a9e7f3 / P-b8e1d4a6)
|
|
249
264
|
|
|
250
265
|
Pluggable test-runner registry at `engine/qa-runners.js`. Built-in
|
|
251
|
-
adapters: `playwright` (priority
|
|
252
|
-
`maestro` (priority 80, detects `.maestro/`
|
|
253
|
-
hooks:
|
|
266
|
+
adapters: `playwright` (priority 50, always-true safe default),
|
|
267
|
+
`maestro` (priority 80, detects `.maestro/` and therefore wins when
|
|
268
|
+
present). Each adapter exports five hooks:
|
|
254
269
|
|
|
255
270
|
- `detect(target, project)` → `boolean`. Auto-detect for blank-runner
|
|
256
271
|
sessions.
|
|
@@ -258,8 +273,9 @@ hooks:
|
|
|
258
273
|
string. Handed to the DRAFT agent so it emits a runner-native test file.
|
|
259
274
|
- `executeBrief({sessionId, target, capture, project})` → instructions /
|
|
260
275
|
command for the EXECUTE agent.
|
|
261
|
-
- `validateOutputDir(dir)` → `{ ok, errors[] }`.
|
|
262
|
-
transition
|
|
276
|
+
- `validateOutputDir(dir)` → `{ ok, errors[] }`. Available to explicit
|
|
277
|
+
callers and tests; the production DRAFT transition does not invoke it
|
|
278
|
+
automatically today.
|
|
263
279
|
- `installHint` → string shown when `detect()` returns true but the
|
|
264
280
|
runner CLI is missing.
|
|
265
281
|
|
|
@@ -399,10 +415,10 @@ maps to `POST /api/qa/from-prd` (see `prompts/cc-system.md`).
|
|
|
399
415
|
`'managed-spawn-healthcheck-failed'`. The `error` field carries the
|
|
400
416
|
reason; check `engine/managed-logs/qa-session-<sessionId>.log` for the
|
|
401
417
|
failing healthcheck.
|
|
402
|
-
- **DRAFT
|
|
403
|
-
|
|
404
|
-
`engine/qa-tests/<sessionId
|
|
405
|
-
|
|
418
|
+
- **DRAFT agent reports failure** → inspect the DRAFT completion summary and
|
|
419
|
+
the injected
|
|
420
|
+
`engine/qa-tests/<sessionId>/` directory. The session failure class is
|
|
421
|
+
`qa-session-draft-failed` when the agent reports that contract failure.
|
|
406
422
|
- **EXECUTE qa-run terminal status is `failed`/`errored`** →
|
|
407
423
|
`failure_class: 'qa-session-execute-failed'` /
|
|
408
424
|
`'qa-session-execute-errored'`. The linked `qa-runs` record (joined via
|
package/docs/qa-runbooks.md
CHANGED
|
@@ -99,7 +99,7 @@ unlink).
|
|
|
99
99
|
|
|
100
100
|
The deferred follow-up items (W-mpeiwz6k0005bf34-b/c/d) have since landed. Brief pointers — see [CLAUDE.md](../CLAUDE.md) → "QA validation runs" for the deep dive:
|
|
101
101
|
|
|
102
|
-
- **Run dispatch + persistence** (`engine/qa-runs.js`): `POST /api/qa/runbooks/run` creates a SQL QA-run record with `status ∈ pending|
|
|
103
|
-
- **Artifact contract**: the `qa-validate` agent writes `agents/<id>/qa-run.json`
|
|
102
|
+
- **Run dispatch + persistence** (`engine/qa-runs.js`): `POST /api/qa/runbooks/run` creates a SQL QA-run record with `status ∈ pending|running|passed|failed|errored` and dispatches a `qa-validate` work item against the runbook's `targetName`. Read via `GET /api/qa/runs?limit=N&status=...` and `GET /api/qa/runs/<id>`.
|
|
103
|
+
- **Artifact contract**: the engine pre-creates `engine/qa-artifacts/<runId>/`; the `qa-validate` agent writes files there and records run-root-relative paths in the injected absolute `agents/<id>/qa-run-result.json` path. The engine clears that sidecar before dispatch, verifies its `runId`, and removes it after consumption. Lifecycle persists the metadata, and `GET /api/qa/artifacts/<runId>/<path>` serves root-level or nested files behind traversal guards (403 on escape). There is no `engine.qaArtifactsMaxBytes` setting or copy-on-completion gate.
|
|
104
104
|
- **UI**: `/qa` dashboard page (`dashboard/pages/qa.html`, `dashboard/js/qa.js`) polls `GET /api/qa/runs` every 5s while active; auto-detects screenshots/videos/logs for inline preview.
|
|
105
105
|
- **Playbook**: `playbooks/qa-validate.md` (routed via the synthetic `qa-validate` task-type in `routing.md`).
|
package/docs/runtime-adapters.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Runtime Adapters
|
|
2
2
|
|
|
3
|
-
How Minions abstracts over CLI runtimes (Claude Code, GitHub Copilot CLI,
|
|
4
|
-
adapters). Engine code never special-cases a runtime by name — every CLI-specific
|
|
3
|
+
How Minions abstracts over CLI runtimes (Claude Code, GitHub Copilot CLI, Codex,
|
|
4
|
+
and future adapters). Engine code never special-cases a runtime by name — every CLI-specific
|
|
5
5
|
behavior is hidden behind an adapter object resolved through `resolveRuntime()`.
|
|
6
6
|
|
|
7
7
|
## What lives in `engine/runtimes/`
|
|
@@ -33,18 +33,18 @@ methods that genuinely differ.
|
|
|
33
33
|
|--------|----------------|---------|
|
|
34
34
|
| `apiVersion` | number | Contract version. Bundled adapters use `1`; incompatible versions fail at registration. |
|
|
35
35
|
| `name` | string | Adapter identifier (matches the registry key). |
|
|
36
|
-
| `capabilities` | flag object (see below) |
|
|
36
|
+
| `capabilities` | flag object (see below) | Behavioral and declarative flags (see below). |
|
|
37
37
|
| `resolveBinary({ env, config? })` | `{ bin, native, leadingArgs }` or null | Probe PATH, npm-globals, package overrides; cached to `engine/<name>-caps.json`. `leadingArgs` is `[]` for direct binaries and `['copilot']` for the `gh copilot` subcommand fallback. |
|
|
38
38
|
| `capsFile` | absolute path | Cache file for `resolveBinary()` results. |
|
|
39
39
|
| `installHint` | string | Surfaced when `resolveBinary()` returns null. Consumed by `engine/preflight.js` and `engine/spawn-agent.js`. |
|
|
40
40
|
| `listModels()` | `Promise<{id,name,provider}[] | null>` | Model catalog or null when discovery isn't supported. |
|
|
41
41
|
| `modelsCache` | absolute path | Cache file for `listModels()` results. |
|
|
42
|
-
| `spawnScript` | absolute path | Path to the runtime-agnostic spawn wrapper (currently `engine/spawn-agent.js` for
|
|
42
|
+
| `spawnScript` | absolute path | Path to the runtime-agnostic spawn wrapper (currently `engine/spawn-agent.js` for all bundled runtimes). |
|
|
43
43
|
| `buildArgs(opts)` | `string[]` | CLI args excluding the binary itself. |
|
|
44
44
|
| `resolveInvocationOptions({ options, engineConfig, config, failureClass })` | object | Optional; maps harness-specific config and retry policy into semantic invocation options. Core code never reads harness-specific invocation keys. |
|
|
45
45
|
| `buildSpawnFlags(opts)` | `string[]` | Optional compatibility flags for older spawn wrappers. New fields travel in the opaque `--runtime-options` bag automatically. |
|
|
46
|
-
| `buildPrompt(promptText, sysPromptText)` | string | Final prompt delivered to the CLI. Adapters that lack `--system-prompt-file`
|
|
47
|
-
| `getUserAssetDirs({ homeDir })` | `string[]` | Runtime-native global asset roots
|
|
46
|
+
| `buildPrompt(promptText, sysPromptText, opts)` | string | Final prompt delivered to the CLI. Adapters that lack `--system-prompt-file` prepend a `<system>` block on fresh calls and omit that replay when `opts.sessionId` resumes an existing session. |
|
|
47
|
+
| `getUserAssetDirs({ homeDir })` | `string[]` | Runtime-native global asset roots exposed by read-only harness diagnostics. |
|
|
48
48
|
| `getSkillRoots({ homeDir, project? })` | `[{ scope, dir, projectName? }]` | Where `collectSkillFiles` looks for native + project skill markdown. |
|
|
49
49
|
| `getSkillWriteTargets({ homeDir, project? })` | `{ personal, project }` | Where `extractSkillsFromOutput` writes auto-extracted skills. |
|
|
50
50
|
| `getResumeSessionId(...)` | string or null | Pre-spawn resume probe; runtime-agnostic stamp prevents cross-runtime session-ID confusion. |
|
|
@@ -58,8 +58,9 @@ methods that genuinely differ.
|
|
|
58
58
|
| `prepareWorkspace(ctx)` | result object | Optional synchronous hook for harness-owned workspace state, such as trust configuration. |
|
|
59
59
|
| `isSpawnStartupEvent(event)` | boolean | Optional startup-event classifier used by the spawn-phase watchdog. |
|
|
60
60
|
| `shouldSuppressPostMutationError(ctx)` | boolean | Optional harness quirk policy for an error received after a confirmed mutation. |
|
|
61
|
+
| `hasUnfinishedToolCall(raw)` | boolean | Optional truncation detector: `true` when the raw output holds a tool call that was started and never completed. Lets the engine diagnose an exit-0 mid-turn death as `runtime-truncated-exit` instead of the generic `completion-report-missing`. Defaults to `false` when not implemented. |
|
|
61
62
|
| `buildWorkerArgs(opts)` | string[] | Required with `acpWorkerPool`; owns persistent-worker CLI flags. |
|
|
62
|
-
| `encodePooledOutput(event)` | string | Required with `acpWorkerPool`; translates semantic
|
|
63
|
+
| `encodePooledOutput(event)` | string | Required with `acpWorkerPool`; translates semantic `model` / `chunk` / `result` events into the adapter's normal parser format. |
|
|
63
64
|
| `detectPermissionGate`, `getPromptDeliveryMode`, `usesSystemPromptFile`, `classifyFailure` | misc | Adapter-owned policy that orchestration reads through the facade instead of branching on `runtime.name`. |
|
|
64
65
|
|
|
65
66
|
`engine/runtimes/contract.js` is authoritative. Registration normalizes legacy
|
|
@@ -89,10 +90,24 @@ Retirement gates for the temporary compatibility surfaces are tracked in
|
|
|
89
90
|
`preapprove-workspace-mcps-wrapper`. Calendar dates never override their
|
|
90
91
|
external-usage gates.
|
|
91
92
|
|
|
93
|
+
### Execution model attribution
|
|
94
|
+
|
|
95
|
+
Dispatch records keep the normalized model sent to the runtime as
|
|
96
|
+
`requestedModel`. Streaming runtimes then replace that provisional evidence with
|
|
97
|
+
their reported model in `executionModel`; pooled ACP dispatches obtain the same
|
|
98
|
+
authoritative value from `session/new.models.currentModelId` and re-emit it in
|
|
99
|
+
the Copilot JSONL shape. Review attribution resolves evidence in this order:
|
|
100
|
+
completion output, captured session output, requested model, then `unknown`.
|
|
101
|
+
`minions pr comment` uses the active dispatch to stamp the shared GitHub/ADO
|
|
102
|
+
marker and visible sign-off, and lifecycle persists the same value as
|
|
103
|
+
`minionsReview.model`. Model catalogs are never used to guess an implicit
|
|
104
|
+
runtime default.
|
|
105
|
+
|
|
92
106
|
## Capability Flags
|
|
93
107
|
|
|
94
|
-
Engine code branches on flags, never on runtime names.
|
|
95
|
-
|
|
108
|
+
Engine code branches on consumed flags, never on runtime names. A capability
|
|
109
|
+
may also begin as declarative metadata; add a consumer when orchestration needs
|
|
110
|
+
to act on that behavioral split.
|
|
96
111
|
|
|
97
112
|
| Flag | Claude | Copilot | Codex | Gates |
|
|
98
113
|
|------|--------|---------|-------|-------|
|
|
@@ -104,15 +119,18 @@ real behavioral split appears between adapters.
|
|
|
104
119
|
| `costTracking` | ✓ | ✗ | ✗ | USD + token counts in the result event. Copilot only emits `premiumRequests`; Codex accounting is not assumed. |
|
|
105
120
|
| `modelShorthands` | ✓ | ✗ | ✗ | Bare `sonnet`/`opus`/`haiku` accepted by Claude only. |
|
|
106
121
|
| `modelDiscovery` | ✗ | ✓ | ✓ | `listModels()` returns a real catalog when supported (Copilot API, Codex `debug models --bundled`). |
|
|
122
|
+
| `strictModelCatalog` | — | — | ✗ | An explicit false lets the runtime validate IDs missing from its cached catalog; Codex uses this because bundled catalogs can lag staged/custom models. |
|
|
107
123
|
| `promptViaArg` | ✗ | ✗ | ✗ | If true, prompt goes via `--prompt <text>` instead of stdin. False for all current runtimes. |
|
|
108
124
|
| `budgetCap` | ✓ | ✗ | ✗ | `--max-budget-usd <n>`. |
|
|
109
125
|
| `bareMode` | ✓ | ✗ | ✗ | `--bare` (suppresses CLAUDE.md auto-discovery). Other runtimes use their own config/suppression knobs. |
|
|
126
|
+
| `claudeMdNativeDiscovery` | ✓ | ✗ | ✗ | Skip engine-side CLAUDE.md propagation when the runtime already loads it natively. |
|
|
110
127
|
| `fallbackModel` | ✓ | ✗ | ✗ | `--fallback-model <id>` on rate-limit. |
|
|
111
128
|
| `sessionPersistenceControl` | ✓ | ✗ | ✗ | Engine writes `session.json`; Copilot and Codex own their runtime stores, while Minions records IDs only for safe resume. |
|
|
112
129
|
| `resumePromptCarryover` | ✗ | ✓ | ✓ | CC resume turns prepend recent visible Q&A in stdin when the runtime session store is opaque to Minions. |
|
|
113
130
|
| `resumeBookkeepingTurn` | ✓ | — | — | Claude CLI injects a synthetic "Continue from where you left off." meta turn on `--resume`; CC prompts must tell the model not to treat it as user intent. |
|
|
114
131
|
| `streamConsumer` | ✓ | ✓ | ✓ | Adapter implements `createStreamConsumer(ctx)` — required by `engine/llm.js` accumulator. |
|
|
115
132
|
| `imageInput` | ✓ | ✓ | ✓ | Runtime accepts `images: [{mimeType, dataBase64}]` and delivers them to the CLI using adapter-owned transport. When false, `_resolveImageOpts` returns a typed `model-unavailable` error. |
|
|
133
|
+
| `skillDiscovery` | ✓ | — | — | Currently set only by Claude to declare native `.claude/skills` discovery. It is metadata-only today; core orchestration has no consumer yet. |
|
|
116
134
|
| `acpWorkerPool` | ✗ | ✓ | ✗ | Runtime supports `<bin> --acp` (Agent Client Protocol), so it can be routed through a persistent worker pool instead of cold-spawning a fresh CLI process per turn/dispatch. Two independent consumers gate on this flag: `engine/cc-worker-pool.js` (CC/doc-chat tabs, `resolveCcUseWorkerPool`) and `engine/agent-worker-pool.js` (fleet agent dispatch, `resolveAgentUseWorkerPool`). Both resolvers hard-return `false` whenever this flag isn't `true` on the resolved runtime, regardless of any operator override, so a future non-ACP runtime can never be silently pooled. See [ACP Worker Pool](#acp-worker-pool-fleet-agent-dispatch) below. |
|
|
117
135
|
|
|
118
136
|
When a behavior is genuinely uniform across all current adapters, it still gets
|
|
@@ -120,10 +138,10 @@ a flag if a future runtime might disagree — flags are cheap.
|
|
|
120
138
|
|
|
121
139
|
## ACP Worker Pool (Fleet Agent Dispatch)
|
|
122
140
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
141
|
+
The `acpWorkerPool` capability backs **two** independent pools that avoid a
|
|
142
|
+
cold harness spawn for every turn/dispatch. Both share the runtime-neutral
|
|
143
|
+
JSON-RPC transport (`engine/acp-transport.js`); the adapter owns worker argv and
|
|
144
|
+
pooled-output encoding.
|
|
127
145
|
|
|
128
146
|
| Pool | Module | Ownership model | Config | Default |
|
|
129
147
|
|------|--------|------------------|--------|---------|
|
|
@@ -136,14 +154,16 @@ This section covers the fleet agent pool (P-9b3d5f61 / P-1d8f0b93 / P-4c6e8a72).
|
|
|
136
154
|
|
|
137
155
|
| Key | Resolver | Chain | Default |
|
|
138
156
|
|-----|----------|-------|---------|
|
|
139
|
-
| `engine.agentUseWorkerPool` | `shared.resolveAgentUseWorkerPool(engine, runtime)` | 1. Hard `false` unless `runtime.capabilities.acpWorkerPool === true
|
|
157
|
+
| `engine.agentUseWorkerPool` | `shared.resolveAgentUseWorkerPool(engine, runtime)` | 1. Hard `false` unless `runtime.capabilities.acpWorkerPool === true`. 2. `engine.agentUseWorkerPool` explicit `true`/`false` override. 3. `ENGINE_DEFAULTS.agentUseWorkerPool`. | `false` |
|
|
140
158
|
| `engine.agentAcpPoolSize` | `shared.resolveAgentAcpPoolSize(engine)` | 1. `engine.agentAcpPoolSize` (positive number, else ignored). 2. `engine.maxConcurrent` (fleet dispatch concurrency cap). 3. `ENGINE_DEFAULTS.maxConcurrent`. | `ENGINE_DEFAULTS.maxConcurrent` (currently `5`) |
|
|
141
159
|
|
|
142
|
-
`agentUseWorkerPool`
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
160
|
+
`agentUseWorkerPool` defaults to `false`; `ccUseWorkerPool` remains enabled by
|
|
161
|
+
default for Copilot. Fleet pooling must be explicitly opted into while its
|
|
162
|
+
newer dispatch-lifecycle path stabilizes.
|
|
163
|
+
Work items requesting `meta.keep_processes` always use the cold wrapper, even
|
|
164
|
+
when fleet pooling is enabled, so the established descendant-ownership contract
|
|
165
|
+
remains authoritative.
|
|
166
|
+
`agentAcpPoolSize` defaults to the same cap the engine would already use for cold-spawn
|
|
147
167
|
concurrency (`maxConcurrent`), so enabling the pool never queues more
|
|
148
168
|
concurrent dispatches than the fleet would have run anyway — it only changes
|
|
149
169
|
*how* those dispatches get a CLI process, not how many run at once.
|
|
@@ -159,31 +179,65 @@ handlers, PID-file writing, live-output.log, timeout/steering cancel-vs-kill,
|
|
|
159
179
|
restart-reattach) runs unmodified regardless of whether `proc` is a real OS
|
|
160
180
|
process or a pooled lease. Assignment strategy, in order:
|
|
161
181
|
|
|
162
|
-
1. A **free** worker whose MCP-server set
|
|
163
|
-
|
|
164
|
-
|
|
182
|
+
1. A **free** worker whose MCP-server set and process launch context already
|
|
183
|
+
match wins first. A persisted session prefers the worker that already owns
|
|
184
|
+
it; otherwise ACP `session/load` restores it. A dispatch without resume state
|
|
185
|
+
receives a fresh `session/new`.
|
|
165
186
|
2. Otherwise another free worker is **evicted** (closed) and a replacement is
|
|
166
|
-
spawned fresh with the requested MCP servers/cwd
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
isolated worktree dispatch.
|
|
187
|
+
spawned fresh with the requested MCP servers/cwd/process policy. MCP servers
|
|
188
|
+
and flags such as `--disable-builtin-mcps`,
|
|
189
|
+
`--max-autopilot-continues`, and reasoning summaries are process-scoped, so
|
|
190
|
+
changing them requires a full respawn, not just a new session.
|
|
171
191
|
3. Otherwise, if the pool has room (fewer than `agentAcpPoolSize` workers
|
|
172
192
|
allocated across free + busy + in-flight-spawn), a brand-new worker spawns.
|
|
173
193
|
4. Otherwise the request queues FIFO until a `release()` or worker crash frees
|
|
174
194
|
a slot.
|
|
175
195
|
|
|
196
|
+
Acquisition is cancellable and the initialize/session handshake is bounded to
|
|
197
|
+
60 seconds. Cancellation quarantines the lease until descendant cleanup
|
|
198
|
+
finishes, then discards that worker so no late response can contaminate another
|
|
199
|
+
dispatch. The engine applies settings every tick: lowering `agentAcpPoolSize`
|
|
200
|
+
immediately closes excess idle workers, and turning `agentUseWorkerPool` off
|
|
201
|
+
closes idle workers while active leases drain.
|
|
202
|
+
|
|
203
|
+
The facade also mirrors cold-spawn descendant cleanup. It preserves descendants
|
|
204
|
+
that existed before the lease (the worker's MCP subtree), tracks process trees
|
|
205
|
+
created during the lease, validates PID birth identity before killing, honors
|
|
206
|
+
validated `keep_processes` anchors, and reaps the rest before reuse. A worker
|
|
207
|
+
that produced kept descendants is discarded with a root-only kill so those
|
|
208
|
+
anchors survive. Tool-call-triggered snapshots plus a final worktree-CWD holder
|
|
209
|
+
scan catch fast-reparented subprocesses; if cleanup cannot be proven safe, the
|
|
210
|
+
dispatch fails closed.
|
|
211
|
+
The long-lived ACP process itself starts in project-scoped engine scratch while
|
|
212
|
+
each ACP session receives its dispatch worktree as `cwd`; a warm worker therefore
|
|
213
|
+
cannot pin a disposable Windows worktree or mutate the operator checkout through
|
|
214
|
+
its process cwd.
|
|
215
|
+
|
|
176
216
|
Dispatch records persist `item.pooled = true` in SQLite, not
|
|
177
217
|
just the in-memory `activeProcesses._pooled` flag (which is wiped on engine
|
|
178
218
|
restart) — the on-disk flag is what tells the restart-reattach path
|
|
179
219
|
(`engine/cli.js`) that a live worker PID is a pooled lease, not a resumable
|
|
180
220
|
cold-spawned child process.
|
|
221
|
+
If checkpoint steering hands a pooled dispatch to a detached cold resume,
|
|
222
|
+
the engine clears `pooled` first and replaces the canonical dispatch PID file,
|
|
223
|
+
restoring normal restart reattachment for the resumed process.
|
|
224
|
+
|
|
225
|
+
On an intentional stop/restart, the fleet pool enters drain mode: new
|
|
226
|
+
acquisitions are rejected, idle workers close immediately, and active leases
|
|
227
|
+
may finish until `engine.shutdownTimeout`. Detached cold-spawn agents are not
|
|
228
|
+
waited on and remain eligible for normal restart reattachment. If the drain
|
|
229
|
+
times out, the engine cancels each pooled facade, awaits its descendant/anchor
|
|
230
|
+
cleanup, and completes its dispatch as a retryable timeout before exiting.
|
|
231
|
+
After an unexpected crash, the persisted
|
|
232
|
+
`pooled` flag still bypasses PID trust and routes the dispatch through orphan
|
|
233
|
+
retry because a replacement engine cannot adopt the old ACP worker's stdio.
|
|
181
234
|
|
|
182
235
|
### Isolation tradeoff — read this before enabling `agentUseWorkerPool`
|
|
183
236
|
|
|
184
|
-
**Enabling the pool bounds
|
|
185
|
-
|
|
186
|
-
|
|
237
|
+
**Enabling the pool bounds cross-dispatch process-state risk by pool size — it
|
|
238
|
+
does not eliminate it.** Lease-created descendants and session state are reset,
|
|
239
|
+
but cold-spawn still gives every dispatch a stronger fresh OS
|
|
240
|
+
process; the pool instead keeps up to
|
|
187
241
|
`agentAcpPoolSize` `copilot --acp` processes warm and reuses them across
|
|
188
242
|
dispatches whenever the MCP-server set matches. Concretely:
|
|
189
243
|
|
|
@@ -199,14 +253,11 @@ dispatches whenever the MCP-server set matches. Concretely:
|
|
|
199
253
|
size narrows it at the cost of more evictions/respawns (and therefore more
|
|
200
254
|
MCP-auth prompts) when the requested MCP-server set changes between
|
|
201
255
|
dispatches.
|
|
202
|
-
- This mirrors the same tradeoff `engine.ccUseWorkerPool`
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
operator has evaluated the tradeoff for their own MCP-server set.
|
|
208
|
-
|
|
209
|
-
Operators enabling `engine.agentUseWorkerPool` should choose `agentAcpPoolSize`
|
|
256
|
+
- This mirrors the same tradeoff `engine.ccUseWorkerPool` accepts for CC tabs
|
|
257
|
+
(see [docs/command-center.md](./command-center.md)). Operators can explicitly
|
|
258
|
+
disable either pool when strict per-dispatch process isolation is required.
|
|
259
|
+
|
|
260
|
+
Operators using `engine.agentUseWorkerPool` should choose `agentAcpPoolSize`
|
|
210
261
|
deliberately: a pool size of `1` gives the strongest isolation (still weaker
|
|
211
262
|
than cold-spawn, since consecutive dispatches on that single worker still
|
|
212
263
|
share process state) at the cost of maximum serialization/respawns; a larger
|
|
@@ -314,24 +365,24 @@ if (mappedEffort) args.push('--effort', mappedEffort);
|
|
|
314
365
|
When `resolveAgentModel` returns undefined the adapter omits `--model` from
|
|
315
366
|
`buildArgs` entirely and the underlying CLI uses its own default.
|
|
316
367
|
|
|
317
|
-
## Per-Runtime Skill Roots
|
|
368
|
+
## Per-Runtime Native Skill Roots
|
|
318
369
|
|
|
319
|
-
Skills live in
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
370
|
+
Skills must live in directories the selected CLI natively discovers. The table
|
|
371
|
+
below lists the reliable native roots; adapter diagnostics may inventory
|
|
372
|
+
additional directories, but inventory does not make those directories visible
|
|
373
|
+
to the CLI.
|
|
323
374
|
|
|
324
375
|
| Adapter | Personal skill root | Project skill roots | Auto-extraction write targets |
|
|
325
376
|
|---------|---------------------|---------------------|-------------------------------|
|
|
326
|
-
| Claude | `~/.claude/skills`
|
|
327
|
-
| Copilot | `~/.copilot/skills
|
|
377
|
+
| Claude | `~/.claude/skills` | `<repo>/.claude/skills` | personal: `~/.claude/skills`; project: `<repo>/.claude/skills` |
|
|
378
|
+
| Copilot | `~/.copilot/skills`, `~/.agents/skills` | `<repo>/.github/skills`, `<repo>/.claude/skills`, `<repo>/.agents/skills` | personal: `~/.copilot/skills`; project: `<repo>/.github/skills` |
|
|
328
379
|
| Codex | `~/.agents/skills` (+ `/etc/codex/skills`) | `<repo>/.agents/skills` | personal: `~/.agents/skills`; project: `<repo>/.agents/skills` |
|
|
329
380
|
|
|
330
|
-
`
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
381
|
+
`getSkillRoots()` feeds the dashboard and `minions doctor --harness` inventory;
|
|
382
|
+
`getSkillWriteTargets()` controls skill auto-extraction. Normal dispatch does not
|
|
383
|
+
turn inventory rows into an engine-computed `--add-dir` list: the selected CLI
|
|
384
|
+
performs native discovery from its cwd and user configuration. In particular,
|
|
385
|
+
Claude does not natively discover `.agents/skills`.
|
|
335
386
|
|
|
336
387
|
For a full per-runtime survey of which dirs the engine actually surfaces today
|
|
337
388
|
— grouped by scope label and with on-disk-missing flags — run
|
package/docs/security.md
CHANGED
|
@@ -139,6 +139,34 @@ previous tick — cannot be silently consumed. Anything in the report body
|
|
|
139
139
|
itself remains agent-controlled and is treated as such (no `eval`, no shell
|
|
140
140
|
interpolation, schema-validated fields only).
|
|
141
141
|
|
|
142
|
+
### Review-learning trust boundaries
|
|
143
|
+
|
|
144
|
+
Structured review learning (see
|
|
145
|
+
[team-memory.md](team-memory.md#security-and-trust-boundaries)) introduces a new
|
|
146
|
+
memory-derived prompt layer, so it observes the same "memory is evidence, not an
|
|
147
|
+
instruction channel" boundary as the rest of retrieval, plus review-specific
|
|
148
|
+
defenses enforced at the persistence boundary in `engine/review-learning.js`:
|
|
149
|
+
|
|
150
|
+
- **Fenced, bounded injection.** Recalled lessons are wrapped with
|
|
151
|
+
`engine/untrusted-fence.js` and capped at 4 records / 4 KiB, independent of the
|
|
152
|
+
generic memory budget. They carry provenance and instruct the agent to verify
|
|
153
|
+
against live code.
|
|
154
|
+
- **No raw reviewer prose is ever stored.** Candidate/lesson bodies are engine-
|
|
155
|
+
generated. Raw comment, transcript, reasoning, and chain-of-thought fields are
|
|
156
|
+
rejected (`assertNoProhibitedReviewPayload`), and secret-shaped values are
|
|
157
|
+
redacted, so the store never becomes a covert channel for injected reviewer text.
|
|
158
|
+
- **Trusted retrieval-trace binding.** An agent may only report an application or
|
|
159
|
+
trigger a contradiction for a lesson its own dispatch's persisted retrieval trace
|
|
160
|
+
actually showed it, and only within its own project. A forged id, an unshown
|
|
161
|
+
lesson, or a cross-project id is rejected as a diagnostic — it cannot quarantine a
|
|
162
|
+
lesson it was never given.
|
|
163
|
+
- **Flag-gated, capture-only-safe.** Both flags default off; capture-only changes no
|
|
164
|
+
rendered prompt, and disabling recall is a complete prompt rollback. Stored
|
|
165
|
+
records stay auditable through the diagnostics endpoints regardless of flag state.
|
|
166
|
+
- **Injection-flag / nonce gates still apply.** A completion flagged
|
|
167
|
+
`failure_class: "injection-flagged"` or failing the nonce check never reaches
|
|
168
|
+
review-learning capture or application processing.
|
|
169
|
+
|
|
142
170
|
## 4. Secret management
|
|
143
171
|
|
|
144
172
|
- **PATs and API tokens live in environment variables only.** GitHub tokens
|