@yemi33/minions 0.1.2370 → 0.1.2372
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/minions.js +38 -11
- package/dashboard/js/render-other.js +2 -30
- package/dashboard/js/render-work-items.js +0 -34
- package/dashboard/js/settings.js +12 -27
- package/dashboard/pages/tools.html +1 -1
- package/dashboard.js +80 -257
- package/docs/README.md +2 -3
- package/docs/architecture.excalidraw +2 -2
- package/docs/auto-discovery.md +3 -3
- package/docs/completion-reports.md +0 -121
- package/docs/copilot-cli-schema.md +9 -17
- package/docs/deprecated.json +0 -51
- package/docs/design-state-storage.md +4 -4
- package/docs/harness-propagation.md +33 -263
- package/docs/human-vs-automated.md +1 -1
- package/docs/named-agents.md +0 -2
- package/docs/plan-lifecycle.md +5 -6
- package/docs/qa-runbook-lifecycle.md +10 -25
- package/docs/shared-lifecycle-module-map.md +2 -10
- package/engine/ado-comment.js +5 -11
- package/engine/ado.js +10 -5
- package/engine/cleanup.js +16 -36
- package/engine/cli.js +13 -175
- package/engine/comment-format.js +8 -182
- package/engine/db/index.js +60 -10
- package/engine/db/migrations/018-sql-only-cutover.js +56 -0
- package/engine/dispatch-store.js +0 -114
- package/engine/dispatch.js +1 -6
- package/engine/gh-comment.js +2 -10
- package/engine/github.js +8 -6
- package/engine/lifecycle.js +58 -173
- package/engine/llm.js +9 -11
- package/engine/managed-spawn.js +1 -6
- package/engine/memory-store.js +8 -6
- package/engine/metrics-store.js +4 -128
- package/engine/pipeline.js +4 -7
- package/engine/playbook.js +8 -196
- package/engine/prd-store.js +115 -141
- package/engine/preflight.js +8 -55
- package/engine/projects.js +34 -41
- package/engine/pull-requests-store.js +9 -234
- package/engine/qa-runs.js +4 -15
- package/engine/qa-sessions.js +5 -17
- package/engine/queries.js +23 -103
- package/engine/routing.js +1 -1
- package/engine/runtimes/claude.js +1 -2
- package/engine/runtimes/codex.js +0 -2
- package/engine/runtimes/copilot.js +1 -4
- package/engine/shared-branch-pr-reconcile.js +2 -5
- package/engine/shared.js +174 -533
- package/engine/small-state-store.js +12 -647
- package/engine/spawn-agent.js +5 -96
- package/engine/state-operations.js +166 -0
- package/engine/supervisor.js +0 -1
- package/engine/watch-actions.js +2 -3
- package/engine/watches-store.js +2 -128
- package/engine/work-items-store.js +3 -254
- package/engine.js +102 -334
- package/package.json +2 -2
- package/playbooks/build-fix-complex.md +0 -4
- package/playbooks/fix.md +0 -4
- package/playbooks/implement-shared.md +0 -4
- package/playbooks/implement.md +0 -4
- package/playbooks/plan-to-prd.md +16 -11
- package/playbooks/plan.md +0 -4
- package/playbooks/review.md +0 -6
- package/playbooks/shared-rules.md +0 -65
- package/docs/harness-transparency.md +0 -199
- package/docs/project-skills.md +0 -193
- package/engine/discover-project-skills.js +0 -673
- package/engine/playbook-intents.js +0 -76
|
@@ -86,73 +86,7 @@ Do **not** invent, regenerate, or share the nonce across dispatches — each spa
|
|
|
86
86
|
| `pending` | string | Any remaining work, or `none`. |
|
|
87
87
|
| `followups` | array | Optional. PR-comment follow-up work items the agent dispatched via `POST /api/work-items` with `meta.pr_followup` set. Each entry: `{wi_id, title, reason, parent_comment_id}`. See [PR-comment follow-ups](#pr-comment-follow-ups). |
|
|
88
88
|
| `invalidates` | string[] | Optional. List of work-item IDs (e.g. `["W-abc123"]`) whose goals are superseded by this completion. The engine cancels each listed WI that is currently in `pending` or `queued` status, stamping `cancellationReason: "invalidated-by:<source-wi-id>"`. WIs in any other status (dispatched, done, failed, cancelled) are skipped with a warning — they are NOT cancelled. Missing IDs also log a warning and are skipped. Only processed on successful (`effectiveSuccess`) completions. See [Goal invalidation](#goal-invalidation). |
|
|
89
|
-
| `meta.review` | object | Optional, review tasks only. Records project-local review-skill outcome — see [Review skill outcomes](#review-skill-outcomes). Aliased by the generalized `meta.skill` (W-mq1cczi90006b21f). |
|
|
90
|
-
| `meta.skill` | object | Optional. Records project-local skill outcome for ANY playbook type that surfaces a `## Project skills` block (implement / fix / plan / review / etc.). See [Project skill outcomes](#project-skill-outcomes). |
|
|
91
89
|
| `meta.descriptionAudit` | object | Optional, `fix` / `implement` dispatches that push commits. Records the PR description audit + screenshot-refresh outcome — see [PR description audit](#pr-description-audit). |
|
|
92
|
-
| `harnessUsed` | object | Optional. Self-report of the harness affordances (skills / MCP servers / commands / docs) the agent actually consulted. Canonical `{ skills, mcpServers, commands, docs }` shape; cross-checked against what the engine exposed and annotated `grounded: true\|false` (never dropped). See [Harness usage](#harness-usage-harnessused). |
|
|
93
|
-
|
|
94
|
-
## Project skill outcomes
|
|
95
|
-
|
|
96
|
-
W-mq1cczi90006b21f. Generalizes the PR-82 review-only `meta.review.skill*` fields to the full Minions lifecycle. When the playbook renders a `## Project skills` block (via `engine/playbook-intents.js` → `engine/discover-project-skills.js`) and the agent acts on a discovered skill, record the outcome under `meta.skill` so later evaluation can compare skill-driven vs. first-principles work across implement / fix / plan / review dispatches uniformly.
|
|
97
|
-
|
|
98
|
-
All `meta.skill` fields are optional and backward-compatible — older agents that never set them stay valid.
|
|
99
|
-
|
|
100
|
-
```json
|
|
101
|
-
{
|
|
102
|
-
"status": "success",
|
|
103
|
-
"meta": {
|
|
104
|
-
"skill": {
|
|
105
|
-
"invoked": {
|
|
106
|
-
"name": "bump-fmf-android",
|
|
107
|
-
"path": ".claude/skills/bump-fmf-android/SKILL.md",
|
|
108
|
-
"kind": "skill",
|
|
109
|
-
"intent": "build"
|
|
110
|
-
},
|
|
111
|
-
"findings": 3
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
```
|
|
116
|
-
|
|
117
|
-
| Field | Type | Notes |
|
|
118
|
-
|---|---|---|
|
|
119
|
-
| `meta.skill.invoked` | object | The project skill the agent actually ran. Shape: `{name, path, kind, intent}` where `kind` is one of `skill`, `command`, `slash-command` (mirrors the discovery layer in `engine/discover-project-skills.js`) and `intent` is the bucket it served (`build`, `review`, `fix`, `test`, `plan`, `research`, `deploy`, `observability`, `meta`). Omit when no skill was invoked. |
|
|
120
|
-
| `meta.skill.findings` | number | Count of findings/artifacts the invoked skill returned. Semantics is per-skill; treat as opaque integer. Omit when no skill was invoked. |
|
|
121
|
-
| `meta.skill.skipped` | object | Set when a project skill was available but the agent intentionally chose not to run it (trivial diff, out-of-scope, meta-work on the skill itself, etc.). Shape: `{name, reason}`. **Before recording a skip you MUST validate it against the skill's own documented scope** — re-read the skill's SKILL.md checklist and confirm the skip reason does not contradict any explicit "Flag if…" / "Verify that…" / "Requirements" item; if the diff trips any such item, skipping is not permitted (apply the skill or that item instead). Mirror the skip rationale into the PR comment so a human sees it **before** merge, not only via a later API call — `minions pr comment … --skill-skipped-file <f>` / `--skill-skipped-json <j>` folds a visible `> ⚠️ Skipped project skill: <name> — <reason>` callout into the same comment as the verdict (single renderer `engine/comment-format.js#buildSkippedSkillSection`, byte-identical on GitHub and ADO). The `{name, reason}` in the comment MUST match the one recorded here (no drift). |
|
|
122
|
-
|
|
123
|
-
Dispatchers can suppress the block entirely by setting `meta.skipProjectSkills: true` on the work item — the playbook then renders without the skills block. Use this for meta-work that targets the skill itself; the engine still accepts `meta.skill.skipped` in the report regardless. The PR-82 `meta.skipProjectReviewSkills` flag is preserved as an alias (suppresses the block on every dispatch type, not just review).
|
|
124
|
-
|
|
125
|
-
## Review skill outcomes
|
|
126
|
-
|
|
127
|
-
W-mq16xtdx001a347e. **Original PR-82 fields, preserved as aliases.** New code should prefer the generalized `meta.skill.*` fields above (W-mq1cczi90006b21f) — those work for every playbook type, not just review.
|
|
128
|
-
|
|
129
|
-
Review playbook renders a `## Project review skills` block at dispatch time when the target project ships `.claude/skills/*` or `.claude/commands/*` with `review` / `swarm` in the name or description (or when `.github/copilot-instructions.md` / `CLAUDE.md` mention a canonical `/…review…` slash-command). When the agent acts on that block, it records the outcome under `meta.review` so later evaluation can compare skill-driven reviews vs. first-principles reviews.
|
|
130
|
-
|
|
131
|
-
All `meta.review` fields are optional and backward-compatible — older agents that never set them stay valid.
|
|
132
|
-
|
|
133
|
-
```json
|
|
134
|
-
{
|
|
135
|
-
"status": "success",
|
|
136
|
-
"meta": {
|
|
137
|
-
"review": {
|
|
138
|
-
"skillInvoked": {
|
|
139
|
-
"name": "code-reviewer",
|
|
140
|
-
"path": ".claude/skills/code-reviewer/SKILL.md",
|
|
141
|
-
"kind": "skill"
|
|
142
|
-
},
|
|
143
|
-
"skillFindings": 3
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
```
|
|
148
|
-
|
|
149
|
-
| Field | Type | Notes |
|
|
150
|
-
|---|---|---|
|
|
151
|
-
| `meta.review.skillInvoked` | object | The project review skill the agent actually ran. Shape: `{name, path, kind}` where `kind` is one of `skill`, `command`, `slash-command` (mirrors the discovery layer in `engine/discover-project-skills.js`). Omit when no skill was invoked. Aliased by `meta.skill.invoked`. |
|
|
152
|
-
| `meta.review.skillFindings` | number | Count of findings the invoked skill returned. Used later to measure skill quality and the value-add of first-principles review on top. Omit when no skill was invoked. Aliased by `meta.skill.findings`. |
|
|
153
|
-
| `meta.review.skillSkipped` | object | Set when a project review skill was available but the agent intentionally chose not to run it (trivial diff, out-of-scope diff, meta-review of the skill itself, etc.). Shape: `{name, reason}`. Aliased by `meta.skill.skipped`. **The skip reason is validated against the skill's own scope** — before recording a skip the agent must re-read the skill's SKILL.md checklist and confirm the reason does not contradict any explicit "Flag if…" / "Verify that…" / "Requirements" item; if the diff trips any such item, skipping is not permitted. The same `{name, reason}` must also be surfaced in the PR review comment (visible `> ⚠️ Skipped project skill` callout, via `minions pr comment … --skill-skipped-json`) so a human sees it before merge — no drift between the report and the comment. |
|
|
154
|
-
|
|
155
|
-
Dispatchers can suppress the block entirely by setting `meta.skipProjectReviewSkills: true` on the review work item — the playbook then renders identically to the pre-W-mq16xtdx 8-step contract. Use this for meta-reviews of the review skill itself; the engine still accepts `meta.review.skillSkipped` in the report regardless. (W-mq1cczi90006b21f generalized this to `meta.skipProjectSkills`, which suppresses the block on every dispatch type — both flags are honored.)
|
|
156
90
|
|
|
157
91
|
## PR description audit
|
|
158
92
|
|
|
@@ -216,60 +150,6 @@ P-mqyp0009y025z6a7. An optional `invalidates: string[]` field in the completion
|
|
|
216
150
|
|
|
217
151
|
**Implementation:** `engine/lifecycle.js#applyGoalInvalidation`, called from `runPostCompletionHooks` after the source WI is marked done.
|
|
218
152
|
|
|
219
|
-
## Harness usage (`harnessUsed`)
|
|
220
|
-
|
|
221
|
-
P-a8f3c2d1. Optional self-report of the harness affordances the agent actually
|
|
222
|
-
consulted to do the work — the skills it ran, the MCP servers it called, the
|
|
223
|
-
slash-commands it invoked, and the reference docs it read. The field is
|
|
224
|
-
backward-compatible: older agents that never set it stay valid. Omit it when no
|
|
225
|
-
harness affordance was used; do not pad it with affordances you didn't touch.
|
|
226
|
-
|
|
227
|
-
Use the canonical `{ skills, mcpServers, commands, docs }` shape
|
|
228
|
-
(`shared.HARNESS_USED_KINDS`). Each kind keeps only the listed fields, and the
|
|
229
|
-
**required** field must be present or `shared.normalizeHarnessUsed()` drops the
|
|
230
|
-
entry:
|
|
231
|
-
|
|
232
|
-
| Kind | Fields | Required |
|
|
233
|
-
|---|---|---|
|
|
234
|
-
| `skills` | `name`, `source`, `path` | `name` |
|
|
235
|
-
| `mcpServers` | `name`, `scope` | `name` |
|
|
236
|
-
| `commands` | `name`, `scope` | `name` |
|
|
237
|
-
| `docs` | `path`, `why` | `path` |
|
|
238
|
-
|
|
239
|
-
```json
|
|
240
|
-
{
|
|
241
|
-
"status": "success",
|
|
242
|
-
"summary": "...",
|
|
243
|
-
"harnessUsed": {
|
|
244
|
-
"skills": [
|
|
245
|
-
{"name": "run-tests", "source": "project", "path": ".claude/skills/run-tests/SKILL.md"}
|
|
246
|
-
],
|
|
247
|
-
"mcpServers": [
|
|
248
|
-
{"name": "azure-ado", "scope": "user"}
|
|
249
|
-
],
|
|
250
|
-
"commands": [
|
|
251
|
-
{"name": "simplify", "scope": "user"}
|
|
252
|
-
],
|
|
253
|
-
"docs": [
|
|
254
|
-
{"path": "docs/completion-reports.md", "why": "confirmed the harnessUsed field shape"}
|
|
255
|
-
]
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
**Grounding semantics.** The report is a self-report — a *claim*. The engine
|
|
261
|
-
captures what it actually propagated into the worktree at spawn time
|
|
262
|
-
(`_harnessPropagated`, unioning user-scope + project-scope harness roots) and
|
|
263
|
-
cross-checks each self-reported entry against it. Entries are annotated
|
|
264
|
-
`grounded: true | false` and **kept, never dropped**: a `grounded: false` entry
|
|
265
|
-
means "the agent claims it used something the engine has no record of exposing"
|
|
266
|
-
(a genuine out-of-band tool, a stale path, or a hallucinated entry) and is
|
|
267
|
-
surfaced for a human rather than silently discarded. Normalization also clamps
|
|
268
|
-
each field to 512 chars and caps each kind at 50 entries
|
|
269
|
-
(`HARNESS_USED_MAX_FIELD_LEN` / `HARNESS_USED_MAX_ENTRIES`). The full
|
|
270
|
-
capture → ground → surface contract is in
|
|
271
|
-
[harness-transparency.md](harness-transparency.md).
|
|
272
|
-
|
|
273
153
|
## `failure_class` enum
|
|
274
154
|
|
|
275
155
|
Defined in `engine/shared.js` as `FAILURE_CLASS`. Use the canonical hyphenated string.
|
|
@@ -493,5 +373,4 @@ The legacy fenced ` ```completion ` block parser and the `task_complete` prose-s
|
|
|
493
373
|
- `engine/lifecycle.js` — `parseCompletionReportFile()`, `parseCompletionNoop()`, `enforcePrAttachmentContract()`
|
|
494
374
|
- `engine/dispatch.js` — `isRetryableFailureReason()`, `writeFailedAgentReport()`
|
|
495
375
|
- `docs/rfc-completion-json.md` — original RFC describing the protocol's design
|
|
496
|
-
- `docs/harness-transparency.md` — the `harnessUsed` capture → ground → surface contract
|
|
497
376
|
- `playbooks/shared-rules.md` — the per-task "Completion Reports" instruction every playbook inherits
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
| `capabilities.costTracking` | **`false`** | `result.usage` contains `premiumRequests` (count, not USD), no token counts, no cost. |
|
|
24
24
|
| `capabilities.modelShorthands` | **`false`** | The Copilot CLI requires full model IDs (`claude-sonnet-4.5`, `gpt-5.4`). Minions may accept internal aliases (`haiku`, `sonnet`, `opus`), but the adapter translates them to Copilot model IDs before invoking the CLI. |
|
|
25
25
|
| `capabilities.budgetCap` | **`false`** | No `--max-budget-usd` flag. |
|
|
26
|
-
| `capabilities.bareMode` | **`false`** | No `--bare
|
|
26
|
+
| `capabilities.bareMode` | **`false`** | No `--bare` equivalent. |
|
|
27
27
|
| `capabilities.fallbackModel` | **`false`** | No `--fallback-model` flag. |
|
|
28
28
|
| `capabilities.sessionPersistenceControl` | **`false`** | Copilot manages session state internally in `~/.copilot/session-state/`. Engine cannot opt out without `--config-dir`. |
|
|
29
29
|
| `capabilities.imageInput` | **`true`** | Base64 image payloads are materialized to temp files and passed as `--attachment <path>` (repeatable flag, W-mqv7324u0021db5d). See §10a. |
|
|
@@ -32,7 +32,6 @@
|
|
|
32
32
|
|---|---|
|
|
33
33
|
| `copilotStreamMode` (default config field) | `'on'` — preserves incremental UX; the adapter parser tolerates either mode. |
|
|
34
34
|
| `copilotDisableBuiltinMcps` | `true` — github-mcp-server bypasses Minions' `pull-requests.json` tracking; default OFF. |
|
|
35
|
-
| `copilotSuppressAgentsMd` | `true` — Minions injects its own playbook prompt; AGENTS.md auto-load conflicts with that. |
|
|
36
35
|
| `copilotReasoningSummaries` | `false` — opt-in; only some models honor it. |
|
|
37
36
|
|
|
38
37
|
---
|
|
@@ -154,9 +153,8 @@ function buildPrompt(promptText, sysPromptText) {
|
|
|
154
153
|
}
|
|
155
154
|
```
|
|
156
155
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
what Minions sent.
|
|
156
|
+
Copilot's native custom-instruction discovery remains enabled, so repository
|
|
157
|
+
instructions augment the Minions task prompt as they do in normal CLI usage.
|
|
160
158
|
|
|
161
159
|
---
|
|
162
160
|
|
|
@@ -172,7 +170,6 @@ Empirically confirmed flags for non-interactive Copilot invocations:
|
|
|
172
170
|
| `--no-ask-user` | **required** | Removes the `ask_user` tool. Without it the agent can stall waiting for human input. |
|
|
173
171
|
| `--autopilot` | for multi-turn agency | Enables `task_complete`-driven multi-turn loop. **Without it** the session ends after one assistant response (see §3.1). |
|
|
174
172
|
| `--log-level error` | recommended | Suppresses INFO/DEBUG diagnostics that aren't part of the JSONL stream. |
|
|
175
|
-
| `--no-custom-instructions` | gated by config | Disables AGENTS.md auto-load. Default-on for Minions (`copilotSuppressAgentsMd: true`). |
|
|
176
173
|
| `--disable-builtin-mcps` | gated by config | Disables `github-mcp-server`. Default-on for Minions (`copilotDisableBuiltinMcps: true`) to prevent split-brain PR creation. |
|
|
177
174
|
| `--no-color` | optional | Cosmetic; safe to omit when `--output-format json`. |
|
|
178
175
|
| `--plain-diff` | optional | Cosmetic; the agent's diff rendering doesn't appear in JSONL stream anyway. |
|
|
@@ -485,9 +482,9 @@ catalog, treat it as a future regression.
|
|
|
485
482
|
|
|
486
483
|
---
|
|
487
484
|
|
|
488
|
-
## 7. Verifying
|
|
485
|
+
## 7. Verifying native instructions and `--disable-builtin-mcps`
|
|
489
486
|
|
|
490
|
-
###
|
|
487
|
+
### Native AGENTS.md auto-load
|
|
491
488
|
|
|
492
489
|
Constructed test: created `AGENTS.md` in cwd with content
|
|
493
490
|
`Always end every response with the marker: __AGENTS_LOADED__`, then ran:
|
|
@@ -497,15 +494,10 @@ Constructed test: created `AGENTS.md` in cwd with content
|
|
|
497
494
|
PS> "Just say hello." | copilot --output-format json -s --allow-all --no-ask-user --autopilot --log-level error
|
|
498
495
|
{"type":"assistant.message", ..., "content": "Hello. __AGENTS_LOADED__"} ← marker present
|
|
499
496
|
|
|
500
|
-
# B) With --no-custom-instructions
|
|
501
|
-
PS> "Just say hello." | copilot --output-format json -s --allow-all --no-ask-user --autopilot --log-level error --no-custom-instructions
|
|
502
|
-
{"type":"assistant.message", ..., "content": ""} ← no marker; AGENTS.md ignored
|
|
503
497
|
```
|
|
504
498
|
|
|
505
|
-
**Confirmed**:
|
|
506
|
-
|
|
507
|
-
still appear in `session.skills_loaded`) — it's narrowly scoped to AGENTS-style
|
|
508
|
-
custom instruction files.
|
|
499
|
+
**Confirmed**: default Copilot CLI behavior loads `AGENTS.md`. Minions preserves
|
|
500
|
+
that default.
|
|
509
501
|
|
|
510
502
|
### `--disable-builtin-mcps` (github-mcp-server)
|
|
511
503
|
|
|
@@ -603,8 +595,8 @@ When implementing `engine/runtimes/copilot.js`:
|
|
|
603
595
|
- **Never** probe npm. Document this in the file header.
|
|
604
596
|
3. `buildArgs(opts)` always emits:
|
|
605
597
|
`--output-format json -s --allow-all --no-ask-user --autopilot --log-level error`
|
|
606
|
-
plus the conditional flags from §3, plus `--
|
|
607
|
-
|
|
598
|
+
plus the conditional flags from §3, plus `--disable-builtin-mcps` per
|
|
599
|
+
`opts.disableBuiltinMcps`,
|
|
608
600
|
plus `--attachment <path>` (repeatable) for each image in `opts.images` (§10a).
|
|
609
601
|
**Never** emit `--verbose`.
|
|
610
602
|
4. `buildPrompt()` injects `<system>...</system>\n\n` block when sysprompt is
|
package/docs/deprecated.json
CHANGED
|
@@ -28,14 +28,6 @@
|
|
|
28
28
|
"targetRemovalDate": "2026-09-17",
|
|
29
29
|
"notes": "Safe to remove on or after 2026-09-17 (~3 release windows) once the removal gate clears. Removal scope: drop the `?? agent.skills` / `?? a.skills` fallbacks in engine/playbook.js:950, engine/lifecycle.js:4620-4621, and engine/queries.js:731; drop the `updates.skills` legacy branch + `delete config.agents[id].skills` in dashboard.js:10708-10716; and update docs/named-agents.md to stop mentioning the legacy key. Does NOT touch the unrelated executable-skills system (queries.js harnesses, runtime adapters, dashboard renderSkills, SKILL.md tooling)."
|
|
30
30
|
},
|
|
31
|
-
{
|
|
32
|
-
"id": "qa-json-sidecars",
|
|
33
|
-
"location": "engine/small-state-store.js _mirrorQaRunsJson + _mirrorQaSessionsJson; engine/shared.js _qaMutator (mirror call); dashboard/js/settings.js set-qaDualWriteJson toggle",
|
|
34
|
-
"reason": "Phase 8 migration (migrate-qa-state-to-sqlite, shipped 2026-06) moved qa_runs + qa_sessions into SQLite (engine/state.db, tables qa_runs + qa_sessions) as the source of truth. The legacy JSON sidecars engine/qa-runs.json and engine/qa-sessions.json are dual-written on every mutation while operators migrate external tooling and dashboards off the JSON files. Gated by engine.qaDualWriteJson (default true).",
|
|
35
|
-
"deprecated": "2026-06-03",
|
|
36
|
-
"targetRemovalDate": "2026-09-03",
|
|
37
|
-
"notes": "Safe to remove on or after 2026-09-03 (90 days post-ship, ~3 release windows) once: (1) operator telemetry / dashboard Settings shows engine.qaDualWriteJson flipped false on the main fleet; (2) no external readers (CI scripts, dashboards, ops runbooks) reference the JSON sidecars directly. Removal scope: delete _mirrorQaRunsJson + _mirrorQaSessionsJson + their exports in engine/small-state-store.js; drop the _qaDualWriteEnabled() + mirror call in engine/shared.js#_qaMutator; remove qaDualWriteJson from ENGINE_DEFAULTS and from the Settings toggle in dashboard/js/settings.js; remove the divergence-rehydrate branch in _resyncQaRunsIfDiverged / _resyncQaSessionsIfDiverged (the JSON files no longer exist to diverge against)."
|
|
38
|
-
},
|
|
39
31
|
{
|
|
40
32
|
"id": "config-poll-key-migration",
|
|
41
33
|
"location": "engine/queries.js:126-163",
|
|
@@ -126,49 +118,6 @@
|
|
|
126
118
|
"targetRemovalDate": null,
|
|
127
119
|
"notes": "Do NOT set targetRemovalDate — gating is signal-based. The function is silent on no-op (returns false without logging), so the meaningful telemetry signal is the absence of the promotion log line over the sweep window, NOT the absence of function invocations (cli.js calls it every boot regardless)."
|
|
128
120
|
},
|
|
129
|
-
{
|
|
130
|
-
"id": "sql-state-json-mirrors",
|
|
131
|
-
"description": "Phase X.5 follow-up to the SQL state migration (commits 62bd6a2c..1111cf54, phases 0–7). Every engine state file that previously used mutateJsonFileLocked now routes through a SQL store, but each store still writes a JSON dual-write mirror after every mutation because a handful of direct-readers (a few unit tests + a couple of inline safeJson calls) have not been migrated to the SQL read path. Once those readers are confirmed routed through the SQL store (or rewritten to use the store's read helper), the mirror writers can be deleted and the JSON files retired.",
|
|
132
|
-
"code": [
|
|
133
|
-
{
|
|
134
|
-
"file": "engine/dispatch-store.js",
|
|
135
|
-
"note": "_mirrorJsonFromSql + _readDispatchJsonFallback — used when SQL is empty AND JSON has content (test seeding + first-time hydrate)"
|
|
136
|
-
},
|
|
137
|
-
{
|
|
138
|
-
"file": "engine/work-items-store.js",
|
|
139
|
-
"note": "_mirrorJsonFromSql + _readJsonArrayFallback (per scope) — same fallback contract as dispatch-store"
|
|
140
|
-
},
|
|
141
|
-
{
|
|
142
|
-
"file": "engine/pull-requests-store.js",
|
|
143
|
-
"note": "_mirrorJsonFromSql + _readJsonArrayFallback (per scope)"
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
"file": "engine/logs-store.js",
|
|
147
|
-
"note": "engine/log.json mirror written by shared._flushLogBuffer's byJsonPath loop — Phase 4.5 will retire"
|
|
148
|
-
},
|
|
149
|
-
{
|
|
150
|
-
"file": "engine/metrics-store.js",
|
|
151
|
-
"note": "_mirrorJsonFromSql + _readJsonObjectFallback"
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
"file": "engine/watches-store.js",
|
|
155
|
-
"note": "_mirrorJsonFromSql + _readJsonArrayFallback"
|
|
156
|
-
},
|
|
157
|
-
{
|
|
158
|
-
"file": "engine/small-state-store.js",
|
|
159
|
-
"note": "_mirrorScheduleRunsJson, _mirrorPipelineRunsJson, _mirrorManagedProcessesJson, _mirrorWorktreePoolJson + each store's _readJson fallback path"
|
|
160
|
-
},
|
|
161
|
-
{
|
|
162
|
-
"file": "CLAUDE.md",
|
|
163
|
-
"lines": "47-66, 240-265",
|
|
164
|
-
"note": "State Files + Concurrency sections still describe JSON files as the source of truth; they describe a layered SQLite-then-mirror reality in places but the headline contract still reads as JSON-primary. Rewrite these sections to make SQL-as-source-of-truth the headline and the JSON mirrors a transitional compatibility detail."
|
|
165
|
-
}
|
|
166
|
-
],
|
|
167
|
-
"removalGate": "All direct-readers of the mirror JSON files must be confirmed routed through their respective SQL store's read helper. Specifically: (a) grep the codebase for `safeJson`, `safeJsonArr`, `safeJsonObj`, `readFileSync(...work-items.json|pull-requests.json|metrics.json|watches.json|schedule-runs.json|pipeline-runs.json|managed-processes.json|worktree-pool.json|log.json|dispatch.json...)` and confirm every hit is either (i) a test fixture that can move to the SQL helper, or (ii) intentionally documented as bypassing SQL. (b) Run the full test suite with each store's _mirrorJsonFromSql temporarily neutered (returning early before safeWrite) and confirm 0 failures — that proves no production code path depends on the mirror. Once both conditions hold, removal deletes each store's _mirrorJsonFromSql call site in shared.js (mutateWorkItems/mutatePullRequests/etc.), the corresponding _readJsonArrayFallback paths, and the JSON file gitignore entries. CLAUDE.md update can ship independently as soon as someone has bandwidth.",
|
|
168
|
-
"status": "active",
|
|
169
|
-
"targetRemovalDate": null,
|
|
170
|
-
"notes": "Do NOT set targetRemovalDate — gating is signal-based, not calendar-based. The mirror writes are cheap (a few KB per write, sub-ms) so there is no production cost to keeping them indefinitely; the only reason to remove them is to simplify the codebase and lock in SQL-as-the-single-source-of-truth. Order matters: when retiring a specific store's mirror, retire the corresponding CLAUDE.md mention in the same PR so the docs never claim SQL-only while a mirror still writes."
|
|
171
|
-
},
|
|
172
121
|
{
|
|
173
122
|
"id": "prune-default-claude-config",
|
|
174
123
|
"description": "pruneDefaultClaudeConfig: active sanitizer that strips generated `config.claude.{binary,outputFormat,allowedTools,permissionMode}` defaults from persisted config.json so the `deprecated-config-claude` warning stops tripping on stale defaults left by older `minions init` versions. Sub-cluster of `config-claude-binary-override` — the prune deliberately preserves non-default user overrides (binary/allowedTools), which is what keeps the override branch in engine/runtimes/claude.js load-bearing.",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Design: Replacing File-Based State with a Structured Database
|
|
2
2
|
|
|
3
|
-
> Author: Rebecca (Architect) | Date: 2026-04-07 | Status: **
|
|
3
|
+
> Author: Rebecca (Architect) | Date: 2026-04-07 | Status: **Implemented**
|
|
4
4
|
|
|
5
|
-
> **Implementation status (as of 2026-06):**
|
|
5
|
+
> **Implementation status (as of 2026-06):** Migrations 001–018 implement the full SQLite cutover. `engine/state.db` is the sole runtime-state authority; migration 018 validates the database, records a durable cutover marker, and retires known legacy mirrors. Historical migrations retain one-time JSON import support. Normal runtime never reads or writes retired mirrors. `minions state check`, `backup`, and `export` provide operations support; explicit offline recovery import is available through `minions state import-legacy-json <dir> --confirm`. Sections 1–3 below are retained as historical design rationale.
|
|
6
6
|
|
|
7
7
|
## Executive Summary
|
|
8
8
|
|
|
9
|
-
Minions
|
|
9
|
+
Minions previously persisted runtime state as flat JSON files guarded by file-lock-based concurrency. This analysis records the options and benchmarks that led to the completed SQLite migration.
|
|
10
10
|
|
|
11
|
-
**Verdict:**
|
|
11
|
+
**Verdict:** `node:sqlite` (`DatabaseSync`) is the implemented runtime-state backend.
|
|
12
12
|
|
|
13
13
|
---
|
|
14
14
|
|
|
@@ -1,273 +1,43 @@
|
|
|
1
|
-
# Harness
|
|
1
|
+
# Native Repository Harness
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
> rest of the plan can extend them without reinventing the contract. Read this
|
|
8
|
-
> before adding a new adapter method, a new asset kind, or a new opt-out flag.
|
|
3
|
+
Minions delegates repository instructions, skills, commands, and MCP discovery
|
|
4
|
+
to the selected CLI runtime. It does not classify repository assets, inject
|
|
5
|
+
selected skill content into prompts, add external harness directories, suppress
|
|
6
|
+
repository instruction files, or attest which harnesses an agent used.
|
|
9
7
|
|
|
10
|
-
##
|
|
8
|
+
## Runtime contract
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
runtime CLI auto-discovers when it starts:
|
|
10
|
+
For each dispatch Minions:
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
12
|
+
1. Creates or selects the checkout.
|
|
13
|
+
2. Sets the CLI working directory to the repository root or the configured
|
|
14
|
+
`meta.workdir`.
|
|
15
|
+
3. Invokes the selected runtime adapter with the task prompt and explicit
|
|
16
|
+
orchestration/security flags.
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
on this machine, it works when Minions dispatches the same task here.*
|
|
18
|
+
From that point, Claude, Copilot, or Codex performs its normal native discovery
|
|
19
|
+
from the working directory and user configuration. Running the same CLI in the
|
|
20
|
+
same checkout should expose the same repository harness.
|
|
23
21
|
|
|
24
|
-
|
|
22
|
+
Repository harness files must exist in the dispatched checkout. In worktree
|
|
23
|
+
mode, uncommitted files from the operator's main checkout are intentionally not
|
|
24
|
+
copied into the dispatch worktree. Commit shared repository harness files, use
|
|
25
|
+
the runtime's user-level configuration for personal assets, or opt into live
|
|
26
|
+
checkout mode when the operator tree itself must be used.
|
|
25
27
|
|
|
26
|
-
|
|
27
|
-
No engine code branches on `runtime.name` for any of them — the runtime
|
|
28
|
-
adapter answers the contract questions and the engine fans out.
|
|
28
|
+
## Explicit exceptions
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
- `engine.copilotDisableBuiltinMcps` prevents Copilot's bundled GitHub MCP from
|
|
31
|
+
bypassing Minions PR tracking. This is an orchestration safety policy, not a
|
|
32
|
+
repository-harness override.
|
|
33
|
+
- `engine.claudePreApproveWorkspaceMcps` pre-approves the checkout's native
|
|
34
|
+
`.mcp.json` entries so a headless Claude process does not block on an invisible
|
|
35
|
+
trust prompt. It does not alter discovery or server definitions.
|
|
36
|
+
- Workspace manifests may restrict tools and repositories as an explicit
|
|
37
|
+
security boundary.
|
|
31
38
|
|
|
32
|
-
|
|
33
|
-
Minions does not copy, symlink, or aggregate user-level assets — it just
|
|
34
|
-
makes sure the relevant dirs are *readable* from the agent's cwd (see
|
|
35
|
-
mechanism #3 below). The actual loading is the CLI's job.
|
|
39
|
+
## Diagnostics
|
|
36
40
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
| Copilot (`engine/runtimes/copilot.js`) | `~/.copilot/skills`, `~/.agents/skills`, `~/.copilot/installed-plugins/<…>/skills` | `~/.copilot/commands` *(probe)* | `~/.copilot/mcp-config.json → mcpServers` |
|
|
41
|
-
| Codex (`engine/runtimes/codex.js`) | `~/.agents/skills`, `/etc/codex/skills` | not yet supported by CLI | not yet a stable contract |
|
|
42
|
-
|
|
43
|
-
The first column is the source of truth for "where does the CLI look on
|
|
44
|
-
this machine?". The dashboard's tooling page mirrors this via
|
|
45
|
-
`engine/queries.js → collectSkillFiles / collectCommandFiles`.
|
|
46
|
-
|
|
47
|
-
### 2. Cwd routing (`shared.resolveSpawnPaths`)
|
|
48
|
-
|
|
49
|
-
`engine/shared.js → resolveSpawnPaths(project, type, MINIONS_DIR)` decides
|
|
50
|
-
what the agent's `cwd` is:
|
|
51
|
-
|
|
52
|
-
- **Read-only types** (`meeting`, `ask`, `explore`, `plan-to-prd`, `plan`)
|
|
53
|
-
→ `cwd = project.localPath` (the operator's main checkout — sees
|
|
54
|
-
uncommitted files).
|
|
55
|
-
- **Code-mutating types** (`implement`, `fix`, `review`, `test`, `verify`,
|
|
56
|
-
`decompose`, `docs`) → `cwd = <worktree>` (a fresh `git worktree add`
|
|
57
|
-
checked out at branch tip — only sees committed files).
|
|
58
|
-
|
|
59
|
-
Cwd routing matters because every CLI's native discovery is **rooted at
|
|
60
|
-
cwd**. Project-scope skills like `<repo>/.claude/skills/foo/SKILL.md` are
|
|
61
|
-
loaded by the CLI only if `<cwd>/.claude/skills/foo/SKILL.md` exists at
|
|
62
|
-
spawn time. See *The worktree-uncommitted footgun* below.
|
|
63
|
-
|
|
64
|
-
Live-checkout mode (`project.checkoutMode: 'live'`) collapses both branches
|
|
65
|
-
to `cwd = project.localPath` for every dispatch type, so the agent sees
|
|
66
|
-
the operator's working tree as-is (including uncommitted assets). The
|
|
67
|
-
tradeoff is single-mutating-dispatch concurrency per project — see
|
|
68
|
-
`docs/live-checkout-mode.md`.
|
|
69
|
-
|
|
70
|
-
### 3. `--add-dir` (`engine/spawn-agent.js → computeAddDirs`)
|
|
71
|
-
|
|
72
|
-
`computeAddDirs({ runtime, minionsDir, homeDir })` builds the list of
|
|
73
|
-
absolute dirs the CLI is allowed to read **outside** its cwd. The current
|
|
74
|
-
list:
|
|
75
|
-
|
|
76
|
-
1. `minionsDir` — always first, so playbooks, system prompt, and skill
|
|
77
|
-
index are reachable from any worktree.
|
|
78
|
-
2. Every existing dir returned by `runtime.getUserAssetDirs({ homeDir })`
|
|
79
|
-
for the resolved runtime — e.g. `~/.claude` + `~/.agents` for Claude,
|
|
80
|
-
`~/.copilot` + `~/.agents` for Copilot, `~/.codex` + `~/.agents` for
|
|
81
|
-
Codex.
|
|
82
|
-
|
|
83
|
-
Non-existent dirs are dropped (Claude CLI rejects unknown `--add-dir`
|
|
84
|
-
entries) and the list is deduped by resolved path.
|
|
85
|
-
|
|
86
|
-
`--add-dir` is the **only** mechanism today that crosses the worktree
|
|
87
|
-
boundary. It does not (yet) cover project-local-but-uncommitted assets —
|
|
88
|
-
that's plan item #5 (`harnessPropagateProjectLocal`).
|
|
89
|
-
|
|
90
|
-
### 4. MCP suppression flags
|
|
91
|
-
|
|
92
|
-
Two flags strip otherwise-inherited MCP / instruction surfaces; everything
|
|
93
|
-
else flows through implicitly because the CLI reads its native config on
|
|
94
|
-
every spawn:
|
|
95
|
-
|
|
96
|
-
- `engine.copilotDisableBuiltinMcps` (default `true`) → `--disable-builtin-mcps`
|
|
97
|
-
on Copilot. Strips Copilot's built-in `github-mcp-server` so dispatched
|
|
98
|
-
agents do not try to open a parallel PR through the bundled MCP while
|
|
99
|
-
Minions is already managing the PR via the host integration.
|
|
100
|
-
- `engine.copilotSuppressAgentsMd` (default `true`) → `--no-custom-instructions`
|
|
101
|
-
on Copilot. Strips project `AGENTS.md` auto-load so Minions playbook
|
|
102
|
-
prompts are not silently overridden by repo-local instructions.
|
|
103
|
-
|
|
104
|
-
There is no equivalent flag for stripping user-level skills, user-level
|
|
105
|
-
slash commands, or user-level MCPs. The current posture is "always inherit"
|
|
106
|
-
— `engine.hermeticHarness` (P-49e1c8b7, default `false`) is the per-fleet /
|
|
107
|
-
per-agent opt-out. When TRUE:
|
|
108
|
-
|
|
109
|
-
- `--add-dir` collapses to exactly `[minionsDir]` — every dir from
|
|
110
|
-
`runtime.getUserAssetDirs({ homeDir })` is dropped.
|
|
111
|
-
- `harnessPropagateProjectLocal` is skipped — no `--project-harness-dir`
|
|
112
|
-
flags emitted.
|
|
113
|
-
- `claudePreApproveWorkspaceMcps` is skipped — workspace `.mcp.json`
|
|
114
|
-
servers are not pre-approved in `~/.claude.json`.
|
|
115
|
-
|
|
116
|
-
The flag is **independent** of `copilotDisableBuiltinMcps` and
|
|
117
|
-
`copilotSuppressAgentsMd` — those keep their existing semantics so an
|
|
118
|
-
operator can run hermetic Claude *and* keep Copilot's built-in MCPs off
|
|
119
|
-
or AGENTS.md auto-load suppressed without re-thinking each lever. Per-agent
|
|
120
|
-
override at `agent.hermeticHarness` (resolved via
|
|
121
|
-
`shared.resolveAgentHermeticHarness(agent, engine)`, mirrors
|
|
122
|
-
`shared.resolveAgentBareMode`).
|
|
123
|
-
|
|
124
|
-
## The worktree-uncommitted footgun
|
|
125
|
-
|
|
126
|
-
The single biggest behavioral wrinkle for new contributors:
|
|
127
|
-
|
|
128
|
-
1. The operator drops an experimental skill at
|
|
129
|
-
`<repo>/.claude/skills/bar/SKILL.md` on their main checkout.
|
|
130
|
-
2. The skill works fine when invoked by hand:
|
|
131
|
-
`cd <repo>; claude "use the bar skill"` — Claude's auto-discovery
|
|
132
|
-
sees it because cwd is the main checkout.
|
|
133
|
-
3. The operator dispatches an `implement` work item against the same repo.
|
|
134
|
-
4. The engine runs `git worktree add <wt> origin/<branch>` (uncommitted
|
|
135
|
-
files do not appear in a fresh worktree), then spawns the agent with
|
|
136
|
-
`cwd = <wt>`.
|
|
137
|
-
5. Claude's discovery now happens at `<wt>` — `.claude/skills/bar/` is
|
|
138
|
-
absent. The agent silently underperforms with no error message.
|
|
139
|
-
|
|
140
|
-
Read-only dispatch types (`meeting`, `ask`, `explore`, `plan-to-prd`,
|
|
141
|
-
`plan`) do **not** hit this footgun, because their cwd is
|
|
142
|
-
`project.localPath`. Mutating types do.
|
|
143
|
-
|
|
144
|
-
`--add-dir` is not currently extended to cover this case (plan item #5),
|
|
145
|
-
so the only workarounds today are:
|
|
146
|
-
|
|
147
|
-
- **Commit it.** The skill becomes visible to every dispatch and every
|
|
148
|
-
teammate, with the usual reviewability tradeoff.
|
|
149
|
-
- **Move it user-scope.** Drop it under `~/.claude/skills/bar/` instead —
|
|
150
|
-
the CLI's user-skill discovery still works inside a worktree because
|
|
151
|
-
`--add-dir` attaches `~/.claude`.
|
|
152
|
-
- **Flip to live-checkout mode.** Set `project.checkoutMode = 'live'` on
|
|
153
|
-
the project so every dispatch runs in `project.localPath`. Caveats in
|
|
154
|
-
`docs/live-checkout-mode.md`.
|
|
155
|
-
|
|
156
|
-
The dashboard tooling page does not yet surface this gap; that's plan
|
|
157
|
-
item #8 ("Harness diagnostics" panel). Until then, run
|
|
158
|
-
`minions doctor --harness` to get the per-runtime view of which dirs the
|
|
159
|
-
engine actually surfaces, and check that flagged "missing" entries
|
|
160
|
-
actually match the assets you expected to inherit.
|
|
161
|
-
|
|
162
|
-
## `minions doctor --harness`
|
|
163
|
-
|
|
164
|
-
One-shot CLI diagnostic that prints, per registered runtime, every dir
|
|
165
|
-
or file the engine would surface to a spawned agent under its scope label.
|
|
166
|
-
Implemented in `engine/preflight.js → runHarnessDoctor(minionsHome)` and
|
|
167
|
-
wired into `bin/minions.js` and `engine/cli.js` as the `--harness` mode
|
|
168
|
-
of the existing `minions doctor` command.
|
|
169
|
-
|
|
170
|
-
### What it prints
|
|
171
|
-
|
|
172
|
-
```
|
|
173
|
-
Minions Harness Propagation
|
|
174
|
-
Runtime: claude
|
|
175
|
-
User asset dirs (--add-dir to agents):
|
|
176
|
-
✓ /home/you/.claude [user]
|
|
177
|
-
✓ /home/you/.agents [user]
|
|
178
|
-
Skill roots (CLI native discovery):
|
|
179
|
-
✓ /home/you/.claude/skills [user]
|
|
180
|
-
✓ /home/you/.agents/skills [user]
|
|
181
|
-
⚠ /repo/.claude/skills [project:myrepo] (missing on disk)
|
|
182
|
-
✓ /repo/.agents/skills [project:myrepo]
|
|
183
|
-
Skill write targets (auto-extract destinations):
|
|
184
|
-
✓ /home/you/.claude/skills [personal]
|
|
185
|
-
✓ /repo/.claude/skills [project:myrepo]
|
|
186
|
-
Runtime: copilot
|
|
187
|
-
User asset dirs (--add-dir to agents):
|
|
188
|
-
✓ /home/you/.copilot [user]
|
|
189
|
-
✓ /home/you/.agents [user]
|
|
190
|
-
…
|
|
191
|
-
Worktree --add-dir snapshot (engine fleet default: copilot):
|
|
192
|
-
✓ /home/you/.minions [minions]
|
|
193
|
-
✓ /home/you/.copilot [user]
|
|
194
|
-
✓ /home/you/.agents [user]
|
|
195
|
-
All harness paths surveyed. Missing on-disk paths are warnings, not failures —
|
|
196
|
-
they're listed so you can decide whether to create the dir, populate it, or
|
|
197
|
-
ignore it for this host.
|
|
198
|
-
```
|
|
199
|
-
|
|
200
|
-
### Exit behavior
|
|
201
|
-
|
|
202
|
-
The command exits **0 on a healthy host** even if some scoped paths do
|
|
203
|
-
not exist on disk. The whole point is to surface "what would the engine
|
|
204
|
-
attach today?" — a user that does not run Codex may legitimately have
|
|
205
|
-
no `~/.codex` dir, and that is not a failure. Exits non-zero only on a
|
|
206
|
-
true runtime/config error (e.g. registry refuses to resolve a known
|
|
207
|
-
runtime, or `config.json` is unparseable).
|
|
208
|
-
|
|
209
|
-
### When to run it
|
|
210
|
-
|
|
211
|
-
- After installing a new skill / command / MCP and "it didn't take" on
|
|
212
|
-
the next dispatched agent — confirm Minions actually surfaces that dir
|
|
213
|
-
for the runtime you're dispatching with.
|
|
214
|
-
- After changing `engine.defaultCli` — different runtimes have different
|
|
215
|
-
asset dirs; the `Worktree --add-dir snapshot` block reflects the fleet
|
|
216
|
-
default.
|
|
217
|
-
- After re-cloning a repo with `<repo>/.claude/skills/` — the diagnostic
|
|
218
|
-
shows whether the project-scope path is on disk.
|
|
219
|
-
- Before reporting "agent ignored my skill" — half the time the answer is
|
|
220
|
-
visible in the diagnostic output.
|
|
221
|
-
|
|
222
|
-
It does **not** check whether the assets *load successfully* inside the
|
|
223
|
-
CLI (no parse of `SKILL.md`, no MCP handshake). For loadability,
|
|
224
|
-
inspect the dashboard tooling page or run an `ask` dispatch and watch
|
|
225
|
-
the live output.
|
|
226
|
-
|
|
227
|
-
## Adapter contract summary
|
|
228
|
-
|
|
229
|
-
The runtime adapters answer these questions. The engine never special-cases
|
|
230
|
-
a runtime by name — it only calls these methods on the resolved adapter.
|
|
231
|
-
|
|
232
|
-
| Method | Signature | Used by |
|
|
233
|
-
|--------|-----------|---------|
|
|
234
|
-
| `getUserAssetDirs({ homeDir })` | → `string[]` | `engine/spawn-agent.js → computeAddDirs`; `runHarnessDoctor` |
|
|
235
|
-
| `getSkillRoots({ homeDir, project? })` | → `[{ scope, dir, projectName? }]` | `engine/queries.js → collectSkillFiles`; `runHarnessDoctor` |
|
|
236
|
-
| `getSkillWriteTargets({ homeDir, project? })` | → `{ personal, project? }` | `engine/lifecycle.js → extractSkillsFromOutput`; `runHarnessDoctor` |
|
|
237
|
-
| `getCommandRoots({ homeDir, project? })` | → `[{ scope, dir, projectName? }]` | `engine/queries.js → collectCommandFiles` (via `getProjectHarnesses` for project scope); `runHarnessDoctor` |
|
|
238
|
-
| `getMcpConfigPaths({ homeDir, project? })` | → `[{ scope, file, projectName? }]` | `runHarnessDoctor`; planned: `engine/queries.js → getStatusSlowStateMtimePaths` |
|
|
239
|
-
|
|
240
|
-
`runHarnessDoctor` renders all five surfaces as "Slash commands" and "MCP
|
|
241
|
-
config files" sections alongside the existing User asset dirs / Skill
|
|
242
|
-
roots / Skill write targets blocks. Adapters that don't yet have a stable
|
|
243
|
-
CLI contract for a surface (today: Codex for both commands and MCP,
|
|
244
|
-
Copilot for project-scope commands) return `[]` so consumers can iterate
|
|
245
|
-
runtimes generically without per-runtime branching.
|
|
246
|
-
|
|
247
|
-
`engine/queries.js` exposes two shared helpers — `getUserHarnesses(homeDir)`
|
|
248
|
-
and `getProjectHarnesses(project)` — that iterate every registered runtime
|
|
249
|
-
via `engine/runtimes.listRuntimes()` + `resolveRuntime()` and union the
|
|
250
|
-
`getSkillRoots` / `getCommandRoots` / `getMcpConfigPaths` contributions,
|
|
251
|
-
deduped by absolute path. The same physical dir contributed by multiple
|
|
252
|
-
adapters (e.g. `~/.agents/skills` exposed by Claude, Copilot, and Codex)
|
|
253
|
-
surfaces once with a `runtimes: [name, ...]` provenance array. Use them
|
|
254
|
-
from dashboard / diagnostics consumers instead of re-walking adapters by
|
|
255
|
-
hand; `collectSkillFiles` / `collectCommandFiles` already do.
|
|
256
|
-
|
|
257
|
-
> **Follow-up.** `getStatusSlowStateMtimePaths` still hardcodes the
|
|
258
|
-
> per-runtime MCP file paths; refactoring it to consume
|
|
259
|
-
> `getUserHarnesses(...).mcps` + `getProjectHarnesses(...).mcps` is
|
|
260
|
-
> tracked separately so the slow-state mtime tracker automatically picks
|
|
261
|
-
> up new adapters.
|
|
262
|
-
|
|
263
|
-
## Related docs
|
|
264
|
-
|
|
265
|
-
- `docs/runtime-adapters.md` — full adapter interface table.
|
|
266
|
-
- `docs/live-checkout-mode.md` — `project.checkoutMode: 'live'`
|
|
267
|
-
contract (alternative to the worktree-add-dir story for repos where
|
|
268
|
-
worktrees are unworkable).
|
|
269
|
-
- `docs/skills.md` — skill block format and auto-extraction targets.
|
|
270
|
-
- `plans/seamless-user-repo-harness-invocation.md` — full multi-item plan
|
|
271
|
-
this doc is the foundation of.
|
|
272
|
-
- `CLAUDE.md` → "Agent Spawn" + "Adapter Contract" — load-bearing
|
|
273
|
-
invariants the propagation contract piggy-backs on.
|
|
41
|
+
`minions doctor --harness` and the dashboard Tools view show adapter-declared
|
|
42
|
+
native locations as read-only inventory. They do not influence spawning and do
|
|
43
|
+
not claim that a runtime loaded or used an asset.
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
| Metrics | Engine (auto-collect) | Engine | You (view) | — |
|
|
16
16
|
| Error recovery | Engine (detect) | — | You (retry/delete) | You |
|
|
17
17
|
| Project linking | You (`minions add/scan`) | — | — | — |
|
|
18
|
-
| MCP servers / Skills / Commands | You (native CLI config) |
|
|
18
|
+
| MCP servers / Skills / Commands | You (native CLI config) | Discovered natively by the selected runtime | — | — |
|
|
19
19
|
|
|
20
20
|
## The Two Human Gates
|
|
21
21
|
|