@yemi33/minions 0.1.2369 → 0.1.2371

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/bin/minions.js +38 -11
  2. package/dashboard/js/memory-search.js +112 -0
  3. package/dashboard/js/render-kb.js +15 -0
  4. package/dashboard/js/render-other.js +2 -30
  5. package/dashboard/js/render-work-items.js +0 -34
  6. package/dashboard/js/settings.js +27 -27
  7. package/dashboard/pages/inbox.html +1 -1
  8. package/dashboard/pages/tools.html +1 -1
  9. package/dashboard.js +148 -258
  10. package/docs/README.md +2 -3
  11. package/docs/architecture.excalidraw +2 -2
  12. package/docs/auto-discovery.md +3 -3
  13. package/docs/completion-reports.md +0 -121
  14. package/docs/copilot-cli-schema.md +9 -17
  15. package/docs/deprecated.json +0 -51
  16. package/docs/design-state-storage.md +4 -4
  17. package/docs/harness-propagation.md +33 -263
  18. package/docs/human-vs-automated.md +1 -1
  19. package/docs/named-agents.md +0 -2
  20. package/docs/plan-lifecycle.md +5 -6
  21. package/docs/qa-runbook-lifecycle.md +10 -25
  22. package/docs/shared-lifecycle-module-map.md +2 -10
  23. package/docs/team-memory.md +18 -4
  24. package/engine/ado-comment.js +5 -11
  25. package/engine/ado.js +10 -5
  26. package/engine/cleanup.js +16 -36
  27. package/engine/cli.js +13 -175
  28. package/engine/comment-format.js +8 -182
  29. package/engine/consolidation.js +72 -1
  30. package/engine/db/index.js +60 -10
  31. package/engine/db/migrations/017-agent-memory.js +208 -0
  32. package/engine/db/migrations/018-sql-only-cutover.js +56 -0
  33. package/engine/dispatch-store.js +0 -114
  34. package/engine/dispatch.js +1 -6
  35. package/engine/features.js +6 -0
  36. package/engine/gh-comment.js +2 -10
  37. package/engine/github.js +8 -6
  38. package/engine/lifecycle.js +141 -173
  39. package/engine/llm.js +9 -11
  40. package/engine/managed-spawn.js +1 -6
  41. package/engine/memory-retrieval.js +165 -0
  42. package/engine/memory-store.js +367 -0
  43. package/engine/metrics-store.js +4 -128
  44. package/engine/pipeline.js +4 -7
  45. package/engine/playbook.js +64 -198
  46. package/engine/prd-store.js +115 -141
  47. package/engine/preflight.js +8 -55
  48. package/engine/projects.js +34 -41
  49. package/engine/pull-requests-store.js +9 -234
  50. package/engine/qa-runs.js +4 -15
  51. package/engine/qa-sessions.js +5 -17
  52. package/engine/queries.js +23 -103
  53. package/engine/routing.js +1 -1
  54. package/engine/runtimes/claude.js +1 -2
  55. package/engine/runtimes/codex.js +0 -2
  56. package/engine/runtimes/copilot.js +1 -4
  57. package/engine/shared-branch-pr-reconcile.js +2 -5
  58. package/engine/shared.js +179 -533
  59. package/engine/small-state-store.js +12 -647
  60. package/engine/spawn-agent.js +5 -96
  61. package/engine/state-operations.js +166 -0
  62. package/engine/supervisor.js +0 -1
  63. package/engine/watch-actions.js +2 -3
  64. package/engine/watches-store.js +2 -128
  65. package/engine/work-items-store.js +3 -254
  66. package/engine.js +102 -334
  67. package/package.json +2 -2
  68. package/playbooks/build-fix-complex.md +0 -4
  69. package/playbooks/fix.md +0 -4
  70. package/playbooks/implement-shared.md +0 -4
  71. package/playbooks/implement.md +0 -4
  72. package/playbooks/plan-to-prd.md +16 -11
  73. package/playbooks/plan.md +0 -4
  74. package/playbooks/review.md +0 -6
  75. package/playbooks/shared-rules.md +0 -65
  76. package/docs/harness-transparency.md +0 -199
  77. package/docs/project-skills.md +0 -193
  78. package/engine/discover-project-skills.js +0 -673
  79. package/engine/playbook-intents.js +0 -76
package/docs/README.md CHANGED
@@ -43,8 +43,8 @@ Architecture, design proposals, and lifecycle references for people working on t
43
43
  - [deprecated-process.md](deprecated-process.md) — Schema for `docs/deprecated.json` and the weekly `cleanup-deprecated` audit walk that retires entries past their removal signal.
44
44
  - [design-state-storage.md](design-state-storage.md) — Design proposal evaluating five database options for replacing Minions' file-based JSON state; recommends `node:sqlite` (accepted; implementation tracked in CHANGELOG.md Phases 0–10).
45
45
  - [harness-mode.md](harness-mode.md) — Tri-Agent Harness Mode (`harness_mode: "tri_agent"` on scheduled tasks): Planner → Generator → Evaluator loop that iterates a shared on-disk artifact until a rubric passes or the iteration cap fires.
46
- - [harness-propagation.md](harness-propagation.md) — How user-level and project-local harness assets (skills, slash-commands, MCP config, `CLAUDE.md` / `AGENTS.md`) propagate into an agent's worktree via `--add-dir`, the `harnessPropagateProjectLocal` flag, and the project-local-on-main worktree-visibility footgun.
47
- - [harness-transparency.md](harness-transparency.md) — The `harnessUsed` self-report contract: capture (agent reports the skills / MCPs / commands / docs it used) → ground (engine cross-checks against `_harnessPropagated` and annotates `grounded:true\|false`, never dropping) → surface (PR comment, final agent note, work-item modal).
46
+ - [harness-propagation.md](harness-propagation.md) — The native runtime
47
+ contract for repository instructions, skills, commands, and MCPs.
48
48
  - [kb-dedup-duplicate-pair-investigation.md](kb-dedup-duplicate-pair-investigation.md) — Investigation-only pass diffing suspected duplicate KB filename groups (content-hash dedup for agent-authored reviews/build-reports) to confirm true full-body duplication before any fix is proposed.
49
49
  - [kb-pr3223-cascade-archiving.md](kb-pr3223-cascade-archiving.md) — Findings from PR #3223: cascade-archiving PRDs when their linked markdown plan is archived, including the per-concern try/catch pattern and `source_plan` basename-matching invariant in `handlePlansArchive` (`dashboard.js`).
50
50
  - [kb-pr696-merge-conflict-docs.md](kb-pr696-merge-conflict-docs.md) — Findings from PR #696: resolving a merge conflict in `docs/kb-sweep.md` with stale line-number citations to `engine/kb-sweep.js`.
@@ -57,7 +57,6 @@ Architecture, design proposals, and lifecycle references for people working on t
57
57
  - [pr-auto-fix-dispatch.md](pr-auto-fix-dispatch.md) — Short reference table mapping each PR auto-fix / review dispatch site in `engine.js#discoverFromPrs` to its gate flag, plus the `pollingPaused` / `autoFixPaused` master kill-switches and the per-provider polling gates.
58
58
  - [pr-comment-followup.md](pr-comment-followup.md) — PR-comment follow-up dispatch contract: fix/review agents may spin off a new WI via `POST /api/work-items` with `meta.pr_followup` instead of broadening the current PR or rebutting the comment.
59
59
  - [pr-review-fix-loop.md](pr-review-fix-loop.md) — How the engine moves a PR from creation through review, fix dispatch, and re-review, including stale-status guards.
60
- - [project-skills.md](project-skills.md) — Project-local skill discovery (`.claude/skills/`, `.claude/commands/`, `CLAUDE.md` / `.github/copilot-instructions.md` slash-command mentions): how dispatched agents see and steer toward purpose-built tooling the project ships, plus the intent-vocabulary contract.
61
60
  - [proposals/repo-pool-for-live-checkout.md](proposals/repo-pool-for-live-checkout.md) — Review-only artifact reproducing the approved plan + PRD for a repo pool covering live-checkout projects (multi-enlistment dispatch), so the design has a git-tracked surface for human comment before the dependent implementation work items land as code PRs.
62
61
  - [qa-runbook-lifecycle.md](qa-runbook-lifecycle.md) — End-to-end QA runbook lifecycle (W-mpeiwz6k0005bf34): runbook + run-record storage, `POST /api/qa/runbooks/run` dispatch into the `qa-validate` playbook, artifact contract, and how the `/qa` page mirrors managed-spawn observability.
63
62
  - [qa-runbooks.md](qa-runbooks.md) — Per-project QA runbook schema, storage layout (`projects/<name>/runbooks/<id>.json`), CRUD endpoints, run-record lifecycle, and the `qa-validate` agent sidecar contract.
@@ -1551,11 +1551,11 @@
1551
1551
  "versionNonce": 1820013027,
1552
1552
  "fontSize": 12,
1553
1553
  "fontFamily": 3,
1554
- "text": "copilot adapter\n--autopilot --allow-all\n--disable-builtin-mcps\n--no-custom-instructions",
1554
+ "text": "copilot adapter\n--autopilot --allow-all\n--disable-builtin-mcps",
1555
1555
  "textAlign": "center",
1556
1556
  "verticalAlign": "middle",
1557
1557
  "containerId": "NSvcvc9cT4YYzxMebEDz",
1558
- "originalText": "copilot adapter\n--autopilot --allow-all\n--disable-builtin-mcps\n--no-custom-instructions",
1558
+ "originalText": "copilot adapter\n--autopilot --allow-all\n--disable-builtin-mcps",
1559
1559
  "lineHeight": 1.25,
1560
1560
  "autoResize": false
1561
1561
  },
@@ -105,9 +105,9 @@ Flip via Dashboard → Settings → Polling → "Granular work-discovery control
105
105
 
106
106
  ### Source 2: PRD Gap Analysis (via `materializePlansAsWorkItems`)
107
107
 
108
- PRD items flow through `materializePlansAsWorkItems()`, which scans `~/.minions/prd/*.json` for PRD files with `missing` / `updated` / `planned` items and creates work items in the target project's queue.
108
+ PRD items flow through `materializePlansAsWorkItems()`, which queries SQL PRDs for `missing` / `updated` / `planned` items and creates work items in the target project's queue.
109
109
 
110
- **Reads:** `~/.minions/prd/*.json` the central PRD directory. (Legacy `<project>/docs/prd-gaps.json` paths are no longer scanned.)
110
+ **Reads:** SQL `prds` and `prd_items`.
111
111
 
112
112
  | Item State | Action | Dispatch Type |
113
113
  |------------|--------|---------------|
@@ -182,7 +182,7 @@ priority: high
182
182
  ...
183
183
  ```
184
184
 
185
- **Plans** (`materializePlansAsWorkItems`): Scans `~/.minions/prd/*.json` for PRD files with `missing`/`planned` items. Creates work items in the target project's queue with `createdBy: 'engine:plan-discovery'`. Work item ID = PRD item ID (e.g. `P-43e5ac28`). Deduped by `id`.
185
+ **Plans** (`materializePlansAsWorkItems`): Queries SQL PRDs for `missing`/`planned` items. Creates work items in the target project's queue with `createdBy: 'engine:plan-discovery'`. Work item ID = PRD item ID (e.g. `P-43e5ac28`). Deduped by `id`.
186
186
 
187
187
  Both write to `work-items.json` and are picked up by Source 3 on the same or next tick.
188
188
 
@@ -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`. Closest equivalent is `--no-custom-instructions` (suppresses AGENTS.md only, not all auto-discovery). |
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
- Combined with `--no-custom-instructions` (default-on per
158
- `copilotSuppressAgentsMd`), this guarantees the prompt the agent sees is exactly
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 `--no-custom-instructions` and `--disable-builtin-mcps`
485
+ ## 7. Verifying native instructions and `--disable-builtin-mcps`
489
486
 
490
- ### `--no-custom-instructions` (AGENTS.md auto-load)
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**: `--no-custom-instructions` suppresses AGENTS.md auto-load. The
506
- flag does **not** affect skills loading (project skills under `.claude/skills/`
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 `--no-custom-instructions` /
607
- `--disable-builtin-mcps` per `opts.suppressAgentsMd` / `opts.disableBuiltinMcps`,
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
@@ -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: **Accepted — implementation in progress**
3
+ > Author: Rebecca (Architect) | Date: 2026-04-07 | Status: **Implemented**
4
4
 
5
- > **Implementation status (as of 2026-06):** The `node:sqlite` recommendation in §3 has been adopted ahead of schedule. Phases 010 have shipped (events, dispatches, work_items, pull_requests, logs, metrics, watches, schedule_runs + pipeline_runs + managed_processes + worktree_pool, qa_runs + qa_sessions, pr_links, cooldowns + pending_rebases + cc_sessions + doc_sessions, and steering_deliveries (Phases 0–9); plans + prds + prd_items + prd_verify_prs (Phase 10, migration `015-plans-prds.js`) — see `CHANGELOG.md` and `engine/db/migrations/`). The SQLite schema lives under `engine/db/migrations/` and the singleton opens `engine/state.db` in WAL mode. Phase 8 added the first opt-out toggle for the JSON sidecars (`engine.qaDualWriteJson`, default true). Phase 9.4 went further and deleted the silent SQL-unavailable JSON fallbacks in the engine — SQL is now the only reader/writer for everything migrated; the JSON mirror layer is dual-written as a passive mirror and slated for deletion in Phase 9.5. Phase 10 dual-writes PRD state to SQL (`engine/prd-store.js`); the `prdReadsFromSql` read-flip flag was removed after soaking (default had been ON since 0.1.2090) SQL is now the unconditional PRD read path in `engine/queries.js`, with SQL errors propagating instead of silently falling back to a disk scan. Phase 10 step 4.3 added a second, still-flagged toggle, `prdJoinFromFk`: it resolves the dashboard WI↔PRD-item join via the SQL FK (`work_items.prd_item_id` `prd_items.id`) instead of the legacy feature-id string match, with a fallback to the string match when the flag is OFF or the FK is unstamped/NULL (default ON, reversible, expires 2026-12-01). The "Phase 2: estimated Node 26 LTS" timeline in §3 is now historical context; treat sections 1–3 as design rationale rather than a forward plan.
5
+ > **Implementation status (as of 2026-06):** Migrations 001018 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 persists all runtime state as flat JSON files guarded by file-lock-based concurrency (`mutateJsonFileLocked`). This analysis evaluates five options for migrating to a structured database, benchmarks each against the current approach, and delivers a phased recommendation.
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:** Stay with improved file-based state short-term. Adopt `node:sqlite` (`DatabaseSync`) as the medium-term target once it exits experimental status, migrating the highest-pain state files first.
11
+ **Verdict:** `node:sqlite` (`DatabaseSync`) is the implemented runtime-state backend.
12
12
 
13
13
  ---
14
14