@yemi33/minions 0.1.2424 → 0.1.2426

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. package/bin/install-internal-minions.js +1209 -0
  2. package/bin/minions.js +75 -9
  3. package/dashboard/docs/typography.md +27 -12
  4. package/dashboard/js/command-center.js +13 -11
  5. package/dashboard/js/live-stream.js +1 -1
  6. package/dashboard/js/memory-search.js +388 -43
  7. package/dashboard/js/modal-qa.js +5 -5
  8. package/dashboard/js/qa.js +39 -26
  9. package/dashboard/js/refresh.js +37 -18
  10. package/dashboard/js/render-agents.js +14 -18
  11. package/dashboard/js/render-dispatch.js +14 -74
  12. package/dashboard/js/render-inbox.js +3 -3
  13. package/dashboard/js/render-meetings.js +8 -8
  14. package/dashboard/js/render-other.js +45 -20
  15. package/dashboard/js/render-pipelines.js +6 -6
  16. package/dashboard/js/render-plans.js +14 -14
  17. package/dashboard/js/render-prd.js +46 -46
  18. package/dashboard/js/render-prs.js +9 -65
  19. package/dashboard/js/render-schedules.js +5 -5
  20. package/dashboard/js/render-skills.js +6 -6
  21. package/dashboard/js/render-utils.js +4 -4
  22. package/dashboard/js/render-watches.js +4 -16
  23. package/dashboard/js/render-work-items.js +95 -107
  24. package/dashboard/js/settings.js +175 -74
  25. package/dashboard/layout.html +3 -2
  26. package/dashboard/pages/inbox.html +1 -1
  27. package/dashboard/pages/work.html +1 -1
  28. package/dashboard/shared/model-display.js +9 -0
  29. package/dashboard/shared/watches-source.js +43 -0
  30. package/dashboard/shared/welcome-popup.js +259 -0
  31. package/dashboard/slim/body.html +6 -6
  32. package/dashboard/slim/js/chat.js +4 -2
  33. package/dashboard/slim/js/history.js +10 -3
  34. package/dashboard/slim/js/modals-tiles.js +85 -16
  35. package/dashboard/slim/js/status.js +12 -16
  36. package/dashboard/slim/styles.css +24 -4
  37. package/dashboard/styles.css +62 -27
  38. package/dashboard-build.js +8 -2
  39. package/dashboard.js +3854 -2514
  40. package/docs/README.md +7 -5
  41. package/docs/api-errors.md +144 -0
  42. package/docs/auto-discovery.md +83 -61
  43. package/docs/capture-demos.js +173 -30
  44. package/docs/command-center.md +5 -1
  45. package/docs/completion-reports.md +127 -11
  46. package/docs/constants.md +15 -3
  47. package/docs/constellation-style-telemetry.md +2 -2
  48. package/docs/copilot-cli-schema.md +32 -22
  49. package/docs/cross-repo-plans.md +30 -30
  50. package/docs/demo/memory-system.html +1 -1
  51. package/docs/deprecated.json +132 -18
  52. package/docs/diagnostics-memory.md +8 -4
  53. package/docs/human-vs-automated.md +2 -2
  54. package/docs/index.html +9 -2
  55. package/docs/internal-install.md +212 -0
  56. package/docs/kb-pr3223-cascade-archiving.md +16 -0
  57. package/docs/kb-pr696-merge-conflict-docs.md +23 -0
  58. package/docs/kb-sweep.md +2 -2
  59. package/docs/keep-processes.md +8 -1
  60. package/docs/live-checkout-mode.md +1 -1
  61. package/docs/managed-spawn.md +21 -3
  62. package/docs/named-agents.md +3 -2
  63. package/docs/onboarding.md +26 -0
  64. package/docs/plan-lifecycle.md +32 -32
  65. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-AFTER.png +0 -0
  66. package/docs/pr-screenshots/pr-899/worker-pool-worktrees-BEFORE.png +0 -0
  67. package/docs/pr-screenshots/pr-979/auto-fix-pane-AFTER.png +0 -0
  68. package/docs/pr-screenshots/pr-979/auto-fix-pane-BEFORE.png +0 -0
  69. package/docs/pr-screenshots/pr-985/pr-column-em-dash-AFTER.png +0 -0
  70. package/docs/pr-screenshots/pr-985/pr-column-em-dash-BEFORE.png +0 -0
  71. package/docs/qa-runbook-lifecycle.md +67 -51
  72. package/docs/qa-runbooks.md +2 -2
  73. package/docs/runtime-adapters.md +101 -50
  74. package/docs/security.md +28 -0
  75. package/docs/self-improvement.md +47 -13
  76. package/docs/skills.md +29 -0
  77. package/docs/slim-ux/concepts.md +2 -2
  78. package/docs/specs/agent-configurability.md +43 -41
  79. package/docs/specs/agent-rename.md +13 -13
  80. package/docs/team-memory.md +283 -14
  81. package/docs/tutorials/01-install-and-connect.md +23 -0
  82. package/docs/tutorials/03-plan-driven-feature.md +3 -3
  83. package/docs/tutorials/04-runtimes-and-harness.md +18 -21
  84. package/docs/tutorials/08-operations-and-recovery.md +3 -2
  85. package/docs/tutorials/README.md +4 -3
  86. package/docs/visual-evidence-ci.md +103 -0
  87. package/docs/watches.md +35 -30
  88. package/docs/worktree-lifecycle.md +151 -13
  89. package/engine/acp-transport.js +1 -0
  90. package/engine/ado.js +80 -33
  91. package/engine/agent-api-validation.js +571 -0
  92. package/engine/agent-worker-pool.js +7 -6
  93. package/engine/api-contracts/agent-content.js +761 -0
  94. package/engine/api-contracts/cc-ops.js +219 -0
  95. package/engine/api-contracts/config-runtime.js +419 -0
  96. package/engine/api-contracts/core.js +138 -0
  97. package/engine/api-contracts/index.js +506 -0
  98. package/engine/api-contracts/orchestration.js +602 -0
  99. package/engine/api-contracts/pull-requests.js +323 -0
  100. package/engine/api-contracts/qa-process.js +764 -0
  101. package/engine/api-contracts/work-plan-prd.js +494 -0
  102. package/engine/api-validation.js +543 -0
  103. package/engine/cc-api-validation.js +586 -0
  104. package/engine/cc-worker-pool.js +9 -1
  105. package/engine/cleanup.js +393 -271
  106. package/engine/cli.js +65 -7
  107. package/engine/comment-classifier.js +70 -5
  108. package/engine/consolidation.js +123 -5
  109. package/engine/content-api-validation.js +606 -0
  110. package/engine/create-pr-worktree.js +22 -1
  111. package/engine/db/migrations/027-review-learning-lifecycle.js +162 -0
  112. package/engine/dispatch.js +33 -0
  113. package/engine/distribution.js +189 -0
  114. package/engine/execution-model.js +59 -0
  115. package/engine/features.js +12 -0
  116. package/engine/github.js +67 -25
  117. package/engine/harness-context.js +313 -0
  118. package/engine/inbox-store.js +1 -1
  119. package/engine/kb-sweep.js +161 -38
  120. package/engine/keep-process-sweep.js +43 -3
  121. package/engine/lifecycle.js +1066 -165
  122. package/engine/llm.js +4 -0
  123. package/engine/managed-spawn.js +463 -48
  124. package/engine/meeting.js +197 -34
  125. package/engine/memory-retrieval.js +280 -0
  126. package/engine/memory-store.js +821 -38
  127. package/engine/model-discovery.js +17 -3
  128. package/engine/pipeline.js +802 -14
  129. package/engine/plan-prd-validation.js +745 -0
  130. package/engine/playbook.js +206 -17
  131. package/engine/pooled-agent-process.js +6 -1
  132. package/engine/pr-action.js +1 -1
  133. package/engine/pr-issue-validation.js +653 -0
  134. package/engine/pr-resolve.js +75 -13
  135. package/engine/prd-store.js +39 -6
  136. package/engine/preflight.js +7 -2
  137. package/engine/process-utils.js +79 -31
  138. package/engine/projects.js +198 -12
  139. package/engine/promotion.js +371 -0
  140. package/engine/qa-from-prd.js +3 -0
  141. package/engine/qa-process-validation.js +572 -0
  142. package/engine/qa-runbooks.js +41 -37
  143. package/engine/qa-runners/maestro.js +11 -7
  144. package/engine/qa-runners/playwright.js +37 -14
  145. package/engine/qa-runners.js +9 -10
  146. package/engine/qa-runs.js +124 -11
  147. package/engine/qa-sessions.js +139 -40
  148. package/engine/quarantine-refs.js +81 -11
  149. package/engine/queries.js +163 -9
  150. package/engine/review-learning-backfill.js +482 -0
  151. package/engine/review-learning.js +1236 -0
  152. package/engine/runtimes/claude.js +60 -2
  153. package/engine/runtimes/codex.js +57 -16
  154. package/engine/runtimes/contract.js +21 -0
  155. package/engine/runtimes/copilot.js +51 -3
  156. package/engine/runtimes/index.js +1 -0
  157. package/engine/scheduler.js +201 -32
  158. package/engine/settings-validation.js +909 -0
  159. package/engine/shared.js +705 -208
  160. package/engine/spawn-agent.js +48 -21
  161. package/engine/steering-constraints.js +31 -0
  162. package/engine/steering-store.js +10 -2
  163. package/engine/steering.js +14 -2
  164. package/engine/timeout.js +404 -111
  165. package/engine/untrusted-fence.js +24 -10
  166. package/engine/watch-actions.js +7 -2
  167. package/engine/watches.js +353 -51
  168. package/engine/work-item-validation.js +561 -0
  169. package/engine/work-items-store.js +61 -1
  170. package/engine/worktree-gc.js +656 -37
  171. package/engine/worktree-preflight.js +154 -0
  172. package/engine.js +2068 -342
  173. package/package.json +1 -1
  174. package/playbooks/_pr-description-audit.md +88 -41
  175. package/playbooks/build-fix-complex.md +3 -3
  176. package/playbooks/docs.md +2 -2
  177. package/playbooks/fix.md +18 -18
  178. package/playbooks/implement.md +18 -18
  179. package/playbooks/qa-session-draft.md +10 -12
  180. package/playbooks/qa-session-execute.md +16 -12
  181. package/playbooks/qa-validate.md +8 -7
  182. package/playbooks/shared-rules.md +45 -0
  183. package/playbooks/test.md +4 -0
  184. package/prompts/cc-system.md +1 -1
  185. package/skills/check-self-authored-review-comment/SKILL.md +2 -2
@@ -0,0 +1,212 @@
1
+ # Internal install & state migration (ISS ProjectFeed-ISS)
2
+
3
+ **This is the supported installation path for OPG customers.** One command
4
+ installs or upgrades the internal Minions package (`@opg-microsoft/minions`) from
5
+ the **ISS `ProjectFeed-ISS` Azure Artifacts npm registry** using your existing
6
+ Azure CLI login, then migrates the existing runtime in place — preserving config,
7
+ SQLite state, notes, plans, knowledge, and project links.
8
+
9
+ The registry is the feed's **base** npm registry:
10
+
11
+ ```
12
+ https://pkgs.dev.azure.com/office/ISS/_packaging/ProjectFeed-ISS/npm/registry/
13
+ ```
14
+
15
+ Packages live in the feed's Local view, so do **not** point at a view-qualified
16
+ registry such as `ProjectFeed-ISS@Release`.
17
+
18
+ No manually created PAT is required, accepted, or stored.
19
+
20
+ ## One command
21
+
22
+ ```powershell
23
+ # Windows (PowerShell)
24
+ scripts\install-internal-minions.ps1
25
+ ```
26
+
27
+ ```bash
28
+ # Linux / macOS
29
+ ./scripts/install-internal-minions.sh
30
+ ```
31
+
32
+ ```bash
33
+ # Any platform, directly (also works from an installed package root)
34
+ node bin/install-internal-minions.js
35
+ ```
36
+
37
+ All three entry points are thin wrappers over `bin/install-internal-minions.js`,
38
+ so behavior cannot drift between platforms.
39
+
40
+ ## Prerequisites
41
+
42
+ | Requirement | Check | Notes |
43
+ |---|---|---|
44
+ | Azure CLI, signed in | `az account show` | Run `az login` first. The script acquires a short-lived token per run. |
45
+ | Node.js >= 22.5 with npm | `node -v` / `npm -v` | Matches `package.json#engines` (the `node:sqlite` runtime backing the state DB). |
46
+ | Read access to `ProjectFeed-ISS` | The script's own `validate-feed` step | Feed access is proven **before** anything is removed or replaced. |
47
+
48
+ ## Options
49
+
50
+ | Flag | Default | Purpose |
51
+ |---|---|---|
52
+ | `--version <spec>` | `latest` | Version or dist-tag to install. Resolved to a concrete version before install, so a stale npm metadata cache cannot silently reinstall an older build. |
53
+ | `--registry <url>` | the ISS `ProjectFeed-ISS` feed | Override the Azure Artifacts npm registry. Must be `https`. |
54
+ | `--package <name>` | `@opg-microsoft/minions` | Override the internal package name. Must be scoped. |
55
+ | `--backup-dir <dir>` | `<runtime root>/backups/internal-install-<timestamp>` | Where the pre-migration backup is written. |
56
+ | `--keep-public` | off | Leave an existing `@yemi33/minions` global install in place instead of replacing it. |
57
+ | `--no-restart` | off | Sync runtime files but skip the health-verified restart. |
58
+ | `--force` | off | Proceed even while agents are active (see [Active agents](#active-agents)). |
59
+ | `--dry-run` | off | Print the resolved plan and the exact commands; change nothing. |
60
+ | `--help` | — | Usage. |
61
+
62
+ Exit codes: `0` success, `1` failure, `2` usage error, `3` refused because agents
63
+ are active.
64
+
65
+ ## What it does, in order
66
+
67
+ The ordering is the safety contract, not a formality. `planSteps()` in
68
+ `bin/install-internal-minions.js` is the single source of truth and is asserted
69
+ by `test/unit/install-internal-minions.test.js`.
70
+
71
+ 1. **`acquire-token`** — `az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798`
72
+ (the same ADO resource id `engine/ado-token.js` uses).
73
+ 2. **`validate-feed`** — `npm view <package>@<spec> version` against the feed, and
74
+ resolve `latest` to a concrete version. **A feed that is unreachable, or a
75
+ version that does not exist, fails here — before anything is removed.**
76
+ 3. **`download-artifact`** — `npm pack <package>@<resolved-version> --pack-destination <temp>`
77
+ downloads the tarball without installing it. **This is what makes the cutover
78
+ safe:** the artifact is on local disk before the public package is removed, so
79
+ a feed, network, or auth failure during the global install is recoverable
80
+ offline. Skipped only when no install will run (see step 6).
81
+ 4. **`backup-state`** — checkpoints and copies the SQLite state
82
+ (`engine/state-operations.js#backupState`: `PRAGMA wal_checkpoint(TRUNCATE)` +
83
+ `VACUUM INTO`), then copies `config.json`, `routing.md`, `pinned.md`, parks a
84
+ copy of the downloaded tarball beside the backup, and writes a `manifest.json`
85
+ describing the from/to packages, the artifact, and the preserved paths.
86
+ Skipped on a machine with no existing runtime.
87
+ The backup runs against the **runtime's own** `engine/state-operations.js`,
88
+ which `minions init` copies into the runtime root and which is therefore always
89
+ present and version-matched to that runtime's `engine/state.db`. It does not
90
+ depend on a globally installed CLI: `minions init` deliberately excludes `bin/`
91
+ from the runtime-root copy, and the published public package predates the
92
+ `minions state` command. An installed CLI's `minions state backup` is kept only
93
+ as a fallback for runtime roots that predate the SQL store layout.
94
+ 5. **`uninstall-public`** — removes an existing global `@yemi33/minions` so the two
95
+ packages never race for the same `minions` bin shim. **Gated:** it runs only
96
+ once `assessCutoverReadiness()` confirms the internal artifact is downloaded
97
+ (or already installed at the target version) *and* a state backup exists
98
+ whenever there was a runtime to back up. Skipped with `--keep-public`, or when
99
+ no public install is present.
100
+ 6. **`install-internal`** — `npm install -g <package>@<resolved-version>` against the
101
+ feed. **If that fails, the script installs the already-downloaded tarball**
102
+ (`npm install -g <backup-dir>/<package>.tgz` — no registry, no token, so it
103
+ still works when the feed is exactly what failed) rather than leaving the
104
+ machine with no CLI. This is also the only step that (re-)links the `minions`
105
+ bin shim, so it is skipped as idempotent only when the resolved version is
106
+ already installed **and** `minions` already resolves to it **and** no
107
+ `uninstall-public` is planned. `npm uninstall -g` takes the shim with the
108
+ package that owns it, so skipping the install alongside an uninstall would
109
+ remove the command with nothing to restore it.
110
+ 7. **`verify-install`** — re-reads the installed `package.json` from disk and fails
111
+ loudly if npm did not actually land the resolved version.
112
+ 8. **`verify-shim`** — resolves the global npm prefix and proves the `minions`
113
+ command itself dispatches into the internal package (`minions.cmd` /
114
+ `minions.ps1` / the sh shim on Windows, the `<prefix>/bin/minions` symlink
115
+ elsewhere). Owning the package directory is not the same as owning the
116
+ command: a half-finished cutover can leave `@opg-microsoft/minions` installed
117
+ while `minions` still runs the public build. A shim still pointing at
118
+ `@yemi33/minions` is a hard failure with the repair commands printed.
119
+ 9. **`sync-init`** — `minions init --force --skip-start`, the supported runtime
120
+ synchronization. It overwrites `.js`/`.html` runtime files and preserves
121
+ user-modified `.md` files.
122
+ 10. **`restart`** — `minions restart`, which is health-verified
123
+ (`engine/restart-health.js`: PID + HTTP probe). Skipped with `--no-restart`.
124
+ 11. **`cleanup`** — always runs, on success and on every failure path. The
125
+ temporary npm config always goes; the downloaded artifact is retained (and its
126
+ path printed) when the run ended with the machine still needing it.
127
+
128
+ After `sync-init` the script re-checks every runtime path that existed
129
+ beforehand (`config.json`, `engine/state.db`, `notes/`, `notes.md`, `plans/`,
130
+ `knowledge/`, `projects/`, `pinned.md`). A path that existed before and is
131
+ missing after is a hard failure pointing at the backup, not a silent data loss.
132
+
133
+ ## Token handling
134
+
135
+ - The ADO token is acquired **per run** and is short-lived.
136
+ - It is written **only** into a `0600` temporary npm userconfig inside the OS temp
137
+ directory. It never reaches `argv`, the process environment, stdout, the
138
+ runtime root, or the repository.
139
+ - Your existing user `.npmrc` is copied into that temporary config first, so a
140
+ custom `prefix`, proxy, or other global-install setting keeps applying —
141
+ replacing the userconfig wholesale would silently relocate a `-g` install.
142
+ - Every line of child-process output and every error message is passed through a
143
+ redactor that scrubs both the raw token and its base64 form.
144
+ - The temporary config directory is removed in a `finally`, so it is cleaned up on
145
+ success **and** on every failure path.
146
+
147
+ ## Active agents
148
+
149
+ Replacing the runtime package rewrites the engine code that running agents are
150
+ executing. The engine's restart/reattachment contract covers an engine restart —
151
+ it does **not** cover rewriting the files underneath a live dispatch.
152
+
153
+ So the script counts live agent PID files under `<runtime root>/engine/tmp/`
154
+ (both the per-dispatch directory layout and the legacy flat layout, matching
155
+ `engine/shared.js#forEachPidFile`) and **defers with exit code 3** when any are
156
+ alive. Stale PID files from a crashed run do not block anything — each PID is
157
+ liveness-checked.
158
+
159
+ Wait for `minions status` to go idle, or pass `--force` to override.
160
+
161
+ ## Idempotency
162
+
163
+ Re-running is safe. When the resolved version is already installed, `minions`
164
+ already resolves to it, and there is no public package left to remove, the
165
+ download and install steps are skipped and the run still converges the runtime
166
+ (`init --force`) and proves health (`restart`). Nothing is uninstalled twice, and
167
+ the temporary npm config is removed either way.
168
+
169
+ Re-running is also the **repair** path: if a previous run left the internal
170
+ package on disk while `minions` still resolved elsewhere (or nowhere), the plan
171
+ reinstates `download-artifact` + `install-internal` so the shim is re-linked.
172
+
173
+ ## Relationship to `minions update`
174
+
175
+ `minions update` is the in-place updater for whichever package is already
176
+ installed: it resolves the active package name from the installed manifest and
177
+ reinstalls *that* package, so an internal install upgrades itself instead of
178
+ pulling in the public one.
179
+
180
+ It does **not** configure a registry. `minions update` shells out to plain
181
+ `npm view <pkg> version` / `npm install -g <pkg>@<version>`
182
+ (`engine/shared.js#buildNpmViewVersionCommand` / `#buildNpmGlobalInstallCommand`),
183
+ so on the internal channel it only reaches `ProjectFeed-ISS` when your **own**
184
+ npm configuration already has a persistent scoped registry entry and credentials
185
+ for the feed — for example `@opg-microsoft:registry=<base feed URL>` in your user
186
+ `.npmrc`. This script's npm config is deliberately temporary and is deleted after
187
+ every run, so it leaves nothing behind for `minions update` to reuse.
188
+
189
+ Re-running this script is therefore the upgrade path that always works: it
190
+ acquires its own short-lived token per run and is idempotent. It is also the
191
+ **channel bootstrap** — what moves a machine onto the internal ProjectFeed-ISS
192
+ channel (including replacing a public `@yemi33/minions` install) and what installs
193
+ the internal package on a machine that has no Minions at all.
194
+
195
+ ## Troubleshooting
196
+
197
+ | Symptom | Cause | Fix |
198
+ |---|---|---|
199
+ | `could not acquire an Azure DevOps token` | Not signed in, or no subscription selected | `az login`, then `az account set --subscription <id>` |
200
+ | `could not read <pkg>@<spec> from the feed` | No feed read permission, or the version does not exist | Request Azure Artifacts read on `ProjectFeed-ISS`; check `--version`. Nothing was uninstalled. |
201
+ | `REFUSED: N agent process(es) are still running` | Active dispatches | Wait for idle, or re-run with `--force` |
202
+ | `expected <pkg>@<v> on disk, found …` | Stale npm metadata cache | `npm cache clean --force`, then re-run |
203
+ | `refusing to uninstall @yemi33/minions — …` | The artifact or the backup is missing | Nothing was removed. Re-run; the message names which precondition failed. |
204
+ | `no way to back up the existing runtime state was found` | The runtime root has neither `engine/state-operations.js` nor a resolvable CLI | Nothing was uninstalled. The error lists every path that was probed; run `minions init --force` against the existing install to restore its engine files, then re-run. |
205
+ | `the minions shim … still points at @yemi33/minions` | A previous half-finished cutover left the public shim in place | `npm uninstall -g @yemi33/minions`, then re-run. The install commands are printed with the error. |
206
+ | Feed install failed after the public package was removed | Feed/network failure mid-install | Handled automatically — the script reinstalls from the tarball it downloaded before the uninstall. If that also fails, the retained artifact path and the offline `npm install -g <tarball>` command are printed. |
207
+
208
+ ## See also
209
+
210
+ - [distribution.md](distribution.md) — publish channels and the fork sync contract
211
+ - [design-state-storage.md](design-state-storage.md) — the SQLite state authority
212
+ - [engine-restart.md](engine-restart.md) — the health-verified restart contract
@@ -0,0 +1,16 @@
1
+ # KB PR #3223 - Cascade Archiving of PRDs on Markdown File Archive
2
+
3
+ > Historical implementation note. PRD persistence moved to SQLite after this
4
+ > change; filesystem reader, sidecar, and structural-test guidance from the
5
+ > original implementation is no longer current.
6
+
7
+ ## Durable contract
8
+
9
+ - `source_plan` is a plan Markdown basename.
10
+ - Plan archive responses retain their documented compatibility fields.
11
+ - PRD archive and cascade updates use `engine/prd-store.js` transactions.
12
+ - Work-item cancellation uses scoped SQL work-item mutations.
13
+
14
+ Use the current `handlePlansArchive` implementation and its behavioral tests as
15
+ the source of truth. Do not reintroduce PRD file scanning or backup-sidecar
16
+ logic.
@@ -0,0 +1,23 @@
1
+ # KB PR #696 – Merge Conflict Resolution in KB-Sweep Documentation
2
+
3
+ PR #696 resolved a merge conflict in `docs/kb-sweep.md:97-103` where both branch and main branches cited stale line numbers to `engine/kb-sweep.js`. Upstream code shifts had invalidated both references. Resolution consolidated the "Pass 1, 1.5, and 2" structure and verified the correct current location of `NORMALIZE_CONCURRENCY = 5` at `engine/kb-sweep.js:30`.
4
+
5
+ ## Key Findings
6
+
7
+ - Merge conflict in `docs/kb-sweep.md:97-103` ("Pass 3 — Per-Entry Rewrite" section) with stale line citations
8
+ - Branch cited `engine/kb-sweep.js:L26`, main cited `L30` with outdated "Pass 1 and 2" wording
9
+ - Root cause: upstream commits shifted line numbers; neither reference remained valid post-merge
10
+ - Resolved by merging branch's "Pass 1, 1.5, and 2" structure with main's corrected line reference to `engine/kb-sweep.js:30`
11
+ - Verified `NORMALIZE_CONCURRENCY = 5` present at `engine/kb-sweep.js:30` in merged state
12
+ - Syntax validation passed for `engine/shared.js`, `engine/kb-sweep.js`, `engine.js`, `dashboard.js`
13
+
14
+ ## Action Items
15
+
16
+ - When resolving doc citation conflicts, re-verify current line numbers in merged source rather than trusting either branch's reference
17
+
18
+ ## References
19
+
20
+ - PR #696: https://github.com/opg-microsoft/minions/pull/696
21
+ - Merge commit: b91cb386
22
+ - Fix comment: https://github.com/opg-microsoft/minions/pull/696#issuecomment-4905945906
23
+ - Correct citation: `engine/kb-sweep.js:30` (`NORMALIZE_CONCURRENCY = 5`)
package/docs/kb-sweep.md CHANGED
@@ -177,9 +177,9 @@ Sweep liveness is coordinated through `engine/kb-sweep-state.json` so the dashbo
177
177
 
178
178
  The state file plus runner PID liveness is the source of truth; the detached runner has no dashboard-owned in-memory lifecycle (source: [`engine/kb-sweep.js:747-778`](../engine/kb-sweep.js#L747), [`dashboard.js:7642-7654`](../dashboard.js#L7642)). A separate `engine/kb-swept.json` is written after each successful non-dry-run sweep with the human-readable summary shown by the dashboard's "swept N days ago" badge (source: [`engine/kb-sweep.js:1019-1024`](../engine/kb-sweep.js#L1019)).
179
179
 
180
- ## Automatic Periodic Sweep (opt-in)
180
+ ## Automatic Periodic Sweep
181
181
 
182
- The engine tick loop can also auto-spawn the KB sweep without dashboard interaction. Gated by `engine.autoConsolidateMemory` (default `false` — source: [`engine/shared.js`](../engine/shared.js) `ENGINE_DEFAULTS.autoConsolidateMemory`):
182
+ The engine tick loop can also auto-spawn the KB sweep without dashboard interaction. Gated by `engine.autoConsolidateMemory` (default `true`; set `false` to disable — source: [`engine/shared.js`](../engine/shared.js) `ENGINE_DEFAULTS.autoConsolidateMemory`):
183
183
 
184
184
  - When `engine.autoConsolidateMemory: true`, every tick the engine consults `shouldAutoSweep()` from [`engine/kb-sweep.js`](../engine/kb-sweep.js) and, when the 4-hour cadence has elapsed since the last completion, calls `spawnSweepRunnerDetached()` to fire-and-forget a fresh `engine/kb-sweep-runner.js` process (source: [`engine.js`](../engine.js) tick step 2.1).
185
185
  - The inbox→`notes.md` consolidation runs every tick *regardless* of this flag via `consolidateInbox()`; `autoConsolidateMemory` controls **only** the heavier `knowledge/` sweep.
@@ -35,7 +35,7 @@ Set `meta.keep_processes: true` on the WI; agent writes `agents/<id>/keep-pids.j
35
35
  ## Lifecycle
36
36
 
37
37
  - **Validation:** sidecar shape + workdir checked in `onAgentClose`. Failure → non-retryable `failure_class: invalid-keep-processes-{workdir,schema}`.
38
- - **Sweep:** [`engine/keep-process-sweep.js`](../engine/keep-process-sweep.js) reaps at boot and every 30 ticks. Dead PIDs are pruned; expired TTL → process killed via `shared.killGracefully` then `killImmediate`.
38
+ - **Sweep:** [`engine/keep-process-sweep.js`](../engine/keep-process-sweep.js) reaps at boot and every 180 ticks. Dead PIDs are pruned; expired TTL → process killed via `shared.killGracefully` then `killImmediate`.
39
39
  - **No healthcheck:** unlike managed-spawn, `keep_processes` does not gate WI completion on first-healthy. If the child crashes immediately the agent still succeeds — by design (ad-hoc helper semantics).
40
40
 
41
41
  ## Caps
@@ -43,6 +43,13 @@ Set `meta.keep_processes: true` on the WI; agent writes `agents/<id>/keep-pids.j
43
43
  - **PIDs:** ≤5 per sidecar.
44
44
  - **TTL:** ≤1440 min (24h). Default 60.
45
45
  - **Cwd:** must exist, resolve inside a git worktree, and stay at or below the current dispatch root from `MINIONS_AGENT_CWD`. Monorepo subdirs are allowed. In worktree mode, pointing at `project.localPath` is rejected before the wrapper decides which descendants survive. `keep_processes` dispatches use the cold spawn wrapper rather than the ACP pool so descendant ownership remains enforceable.
46
+ - **Manual kill API:** `POST /api/keep-processes/kill` accepts only a safe
47
+ `agentId` and a numeric positive PID declared by a currently valid sidecar;
48
+ rejected requests do not kill a process or rewrite the file. The endpoint
49
+ atomically claims the declaration, verifies the OS process start identity,
50
+ and restores the claimed record if identity changes or termination fails.
51
+ Its filesystem-mtime identity anchor is preserved after both rejected and
52
+ successful partial-PID updates.
46
53
 
47
54
  After acceptance, the engine adds project/work-type/checkout-mode/dispatch-root
48
55
  provenance to the sidecar. Boot sweep uses it to kill and unlink any retained
@@ -355,7 +355,7 @@ The engine has no opinion about local branches; this hygiene is the operator's r
355
355
  Live-checkout mode is deliberately small. These are NOT supported and will not be added:
356
356
 
357
357
  - **No `auto` mode.** The choice between `worktree` and `live` is per-project and operator-set. The engine will not auto-detect submodules / `repo` workspaces and silently switch modes.
358
- - **No auto-stash on dirty refusal _by default_.** Out of the box the engine refuses and exits; it never `git stash`es to "make room" for a dispatch, because that silently mutates the operator's tree and conflates engine state with operator state. The operator can **opt in** per-project (`project.liveCheckoutAutoStash`) or fleet-wide (`engine.liveCheckoutAutoStash`) to auto-stash instead of refusing — see [2b](#2b-opt-in-auto-stash-on-dirty-w-mqtvnnj1000357fa). Even then the engine never **pops** the stash on the operator's behalf. (The `liveCheckoutAutoReset` escape hatch — **OFF by default** as of W-mrawgw4q000a6bff, and even when enabled now only runs as a last-resort fallback *after* auto-stash fails or is disabled — **discards** rather than stashes; set it to `true` per-project / fleet-wide to opt in. See [§2b](#2b-opt-in-auto-reset-on-dirty-livecheckoutautoreset-w-mqvejug6000eeb20).)
358
+ - **Auto-stash is ON fleet-wide by default (W-mrawiym8000c42c9).** Out of the box a dirty tree is `git stash push --include-untracked`'d before dispatch instead of refusing, because the stash is non-destructive and recoverable via `git stash pop` see [2b](#2b-auto-stash-on-dirty-w-mqtvnnj1000357fa). The operator can **opt out** per-project (`project.liveCheckoutAutoStash: false`) or fleet-wide (`engine.liveCheckoutAutoStash: false`) to restore the terminal dirty-tree refusal instead. Even with auto-stash on, the engine never **pops** the stash on the operator's behalf. (The `liveCheckoutAutoReset` escape hatch — **OFF by default** as of W-mrawgw4q000a6bff, and even when enabled now only runs as a last-resort fallback *after* auto-stash fails or is disabled — **discards** rather than stashes; set it to `true` per-project / fleet-wide to opt in. See [§2b](#2b-opt-in-auto-reset-on-dirty-livecheckoutautoreset-w-mqvejug6000eeb20).)
359
359
  - **No concurrent dispatches per project.** The cap is 1; raising it would require per-WI subdirectories, which live mode explicitly does not provide.
360
360
  - **No per-WI subdirectory isolation.** Live mode is one-checkout-per-project by design. If you need isolation, use `checkoutMode: 'worktree'` (the default).
361
361
  - **No per-WI override.** `checkoutMode` is per-project only. There is no `meta.checkoutMode` on a work item that overrides the project setting.
@@ -57,7 +57,12 @@ The sidecar lives at `<MINIONS_DIR>/agents/<agentId>/managed-spawn.json` and is
57
57
  }
58
58
  ```
59
59
 
60
- The renderer in [`buildManagedSpawnHint`](../engine/managed-spawn.js) at `engine/managed-spawn.js:419` emits this exact shape (with allowlist + cap reminders) into the agent's prompt whenever the work item has `meta.managed_spawn: true`. Treat the rendered hint as the source of truth — if this doc and the hint drift, the hint wins.
60
+ The renderer in [`buildManagedSpawnHint`](../engine/managed-spawn.js) emits this exact shape (with allowlist + cap reminders) into the agent's prompt whenever the work item has `meta.managed_spawn: true`. Treat the rendered hint as the source of truth — if this doc and the hint drift, the hint wins.
61
+
62
+ For an opted-in dispatch, the sidecar is mandatory. Completion acceptance reads
63
+ only the canonical running agent's directory and requires `written_by` and
64
+ `wi_id` to match that agent and work item exactly; a missing file or stale
65
+ identity fails with `invalid-managed-spawn` instead of completing successfully.
61
66
 
62
67
  The engine also confines every spec to the dispatch root: `cwd` must resolve at
63
68
  or below `MINIONS_AGENT_CWD`. In worktree mode, `project.localPath` is rejected
@@ -176,8 +181,9 @@ Single quotes (`'…'`) work the same way. No `powershell -Command "& '<path>' <
176
181
 
177
182
  ┌───────────────────────────────────────────────────────────────────┐
178
183
  │ 2. evaluateManagedSpawnAcceptance(agentId) │
179
- │ - Validates schema, allowlists, caps
180
- │ - Rejects ERROR + alert + sidecar deleted
184
+ │ - Requires the canonical agent/WI sidecar
185
+ │ - Validates identity, schema, allowlists, caps
186
+ │ - Rejects → ERROR + alert (+ delete when present) │
181
187
  │ failure_class: invalid-managed-spawn (non-retryable) │
182
188
  └───────────────────────────────────┬───────────────────────────────┘
183
189
  │ accepted
@@ -247,6 +253,9 @@ Outcome: if WI 2 fails, the spec stays alive (TTL-managed) and the next dispatch
247
253
  | Dashboard | http://localhost:7331/engine → "Managed Processes" |
248
254
 
249
255
  The list endpoint returns an ETag; pass it as `If-None-Match` on follow-up polls to get `304 Not Modified` when nothing changed. The dashboard panel does this automatically.
256
+ API process names use the same kebab-case/length validator as sidecar specs,
257
+ project filters must name a configured project, and log-stream `tail` is a
258
+ single integer from 1 byte through 1 MiB (default 64 KiB).
250
259
 
251
260
  ### Force a restart / kill
252
261
 
@@ -255,6 +264,15 @@ The list endpoint returns an ETag; pass it as `If-None-Match` on follow-up polls
255
264
  | Kill (PID terminated, removed from state) | `POST /api/managed-processes/kill` `{"name":"…"}` | Per-row "Kill" button |
256
265
  | Restart (kill old PID, respawn from saved state, kick first healthcheck) | `POST /api/managed-processes/restart` `{"name":"…"}` | Per-row "Restart" button |
257
266
 
267
+ Both controls bind the request to the selected row's `pid` + `started_at`
268
+ generation and verify the live OS process start identity before killing. A
269
+ concurrent replacement, recycled PID, or failed kill returns `409` without
270
+ deleting the surviving generation; restart also reserves the name before
271
+ spawning so concurrent calls cannot orphan duplicate generations. Engine batch
272
+ spawns use the same reservation protocol, first-health and boot-probe writes
273
+ must match the reserved generation, and failed rollback kills remain as
274
+ immediately-expired tracked rows for the sweep to retry.
275
+
258
276
  Killing a spec from outside Minions (raw `Stop-Process`) leaves a stale SQL row until the next 30-tick sweep notices the dead PID. Prefer the API.
259
277
 
260
278
  ### View logs
@@ -83,8 +83,8 @@ defaults (`WORKSPACE_MANIFEST_DEFAULTS` in `engine/shared.js`):
83
83
  | `memory_scope` | `'shared'` | One of `private`, `shared`, `read-only-shared`. |
84
84
 
85
85
  Enforcement helpers (also in `engine/shared.js`): `validateWorkspaceManifest`,
86
- `resolveAgentManifest`, `agentCanUseRepo`, `agentCanUseTool`, `agentCanFetchUrl`,
87
- `mergeManifestAllowedTools`. Today the engine actively enforces (a) the
86
+ `resolveAgentManifest`, `agentCanUseRepo`, and `mergeManifestAllowedTools`. Today the
87
+ engine actively enforces (a) the
88
88
  **repo gate** at dispatch time in `engine.js spawnAgent`
89
89
  (`FAILURE_CLASS.WORKSPACE_MANIFEST_REPO`, non-retryable) and (b) the **tool merge** into the
90
90
  runtime `--allowedTools` flag at spawn time. Defaults are permissive — an agent with no
@@ -105,6 +105,7 @@ Routing maps a `work_type` to a `preferred` agent and a `fallback`:
105
105
  | implement:large | rebecca | dallas |
106
106
  | review | ripley | lambert |
107
107
  | fix | `_author_` | `_any_` |
108
+ | build-fix-complex | `_author_` | dallas |
108
109
  | plan | ripley | rebecca |
109
110
  | plan-to-prd | lambert | rebecca |
110
111
  | explore | ripley | rebecca |
@@ -10,15 +10,41 @@ completed first dispatch. For deeper, progressive exercises, use the
10
10
  - Git
11
11
  - One supported runtime CLI with working authentication
12
12
  - A local Git repository you are comfortable allowing an agent to change
13
+ - For the internal (OPG) install: Azure CLI signed in (`az login`) and Azure
14
+ Artifacts **read** permission on the ISS `ProjectFeed-ISS` feed
13
15
 
14
16
  Minions defaults to GitHub Copilot CLI. Claude Code and Codex are also
15
17
  supported.
16
18
 
17
19
  ## 1. Install and initialize
18
20
 
21
+ Install the internal package `@opg-microsoft/minions` from the ISS
22
+ `ProjectFeed-ISS` Azure Artifacts feed with the repository's one-command
23
+ installer. It installs the package and runs `minions init --force` for you:
24
+
25
+ ```powershell
26
+ scripts\install-internal-minions.ps1 # Windows
27
+ ```
28
+
29
+ ```bash
30
+ ./scripts/install-internal-minions.sh # Linux / macOS
31
+ ```
32
+
33
+ The installer acquires a short-lived token from your existing `az` login — no PAT
34
+ is created, accepted, or stored. Full options and troubleshooting:
35
+ [internal-install.md](internal-install.md).
36
+
37
+ If you do not have access to the ISS `ProjectFeed-ISS` feed, install the public
38
+ package from npm instead (separate release channel, not the OPG path):
39
+
19
40
  ```bash
20
41
  npm install -g @yemi33/minions
21
42
  minions init
43
+ ```
44
+
45
+ Either way, verify the host next:
46
+
47
+ ```bash
22
48
  minions doctor
23
49
  ```
24
50
 
@@ -9,12 +9,12 @@ How plans go from idea to verified, running code.
9
9
  → agent writes plan markdown (plans/plan-*.md)
10
10
  → human reviews and explicitly runs plan-to-prd
11
11
  → agent converts plan into structured PRD items with acceptance criteria
12
- → engine materializes PRD items as work items (PL-W001, PL-W002, ...)
12
+ → engine materializes each PRD item under the same id as a work item (P-001, P-002, ...)
13
13
  → engine dispatches work items respecting dependency order
14
14
  → agents implement each item, create PRs
15
15
  → engine auto-reviews PRs, handles feedback loops
16
- → all items done → engine creates VERIFY task
17
- → verify agent builds everything, starts webapp, writes testing guide
16
+ → all items terminal → engine creates VERIFY task(s) for completed work
17
+ → verify agent builds everything, starts a webapp if applicable, writes testing guide
18
18
  → human archives the PRD/plan from the dashboard when ready
19
19
  ```
20
20
 
@@ -26,29 +26,29 @@ PRD items can declare `depends_on: ["P001", "P003"]`. The engine won't dispatch
26
26
 
27
27
  ### Branch Merging at Spawn
28
28
 
29
- When an agent is spawned for a work item with dependencies, the engine merges the dependency PR branches into the worktree **before the agent starts**. This solves the problem where dependencies have PRs but haven't been merged to `main` yet.
29
+ When an agent is spawned for a work item with dependencies, the engine merges same-project dependency PR branches into the worktree **before the agent starts**. Cross-repo dependencies are exposed as advisory refs instead of being merged. This lets later items inspect prerequisite code that has not reached the target repo's main branch.
30
30
 
31
31
  ```
32
- Agent gets work item PL-W006 (plan item P009)
32
+ Agent gets work item P009
33
33
  depends_on: ["P006", "P007"]
34
34
 
35
35
  spawnAgent():
36
36
  1. Create worktree from main:
37
- git worktree add ../worktrees/work/PL-W006 -b work/PL-W006 main
37
+ git worktree add ../worktrees/work/P009 -b work/P009 main
38
38
 
39
39
  2. Resolve dependencies:
40
- P006 → work item PL-W001 → PR-4970100 → branch work/PL-W001
41
- P007 → work item PL-W002 → PR-4970101 → branch work/PL-W002
40
+ P006 → work item P006 → PR-4970100 → branch work/P006
41
+ P007 → work item P007 → PR-4970101 → branch work/P007
42
42
 
43
43
  3. Merge dependency branches:
44
- git fetch origin work/PL-W001 work/PL-W002
45
- git merge origin/work/PL-W001 --no-edit
46
- git merge origin/work/PL-W002 --no-edit
44
+ git fetch origin work/P006 work/P007
45
+ git merge origin/work/P006 --no-edit
46
+ git merge origin/work/P007 --no-edit
47
47
 
48
48
  4. Agent starts with all dependency changes present
49
49
  ```
50
50
 
51
- If a merge conflict occurs, it's logged as a warning. The agent will see conflict markers and can resolve them, or the task will fail and get retried after the dependency PRs are merged to `main`.
51
+ If dependency merging still conflicts after the engine's clean reset/re-merge attempt, the engine aborts the partial merge and fails the dispatch **before spawning the runtime** with `FAILURE_CLASS.MERGE_CONFLICT`. When it can identify the conflicting dependency branch it also queues a conflict-fix work item on that branch; the dependent item waits for the branch to become mergeable.
52
52
 
53
53
  ### Resolution Chain
54
54
 
@@ -57,17 +57,17 @@ depends_on: ["P-43e5ac28"]
57
57
  → find work items where id = "P-43e5ac28" (across all projects)
58
58
  → find PRs where prdItems includes "P-43e5ac28"
59
59
  → extract branch names from those PRs
60
- → fetch + merge into worktree
60
+ → fetch + merge into worktree (same project), or expose an advisory ref (cross-repo)
61
61
  ```
62
62
 
63
63
  ## Plan Completion
64
64
 
65
- When all PRD items reach `done` or `failed` status, `checkPlanCompletion()` fires:
65
+ When every materialized PRD item reaches a `PLAN_TERMINAL_STATUSES` value (`done`/legacy-done, `failed`, or `cancelled`), `checkPlanCompletion()` fires:
66
66
 
67
67
  1. **Completion summary** written to `notes/inbox/` with results, timing, and PR list
68
- 2. **Verification task** created (type `verify`, priority `high`) — see below
68
+ 2. **Verification task(s)** created (type `verify`, priority `high`) when at least one item completed one per touched project; see below
69
69
  3. **PR work item** created for shared-branch plans (to merge the feature branch)
70
- 4. **PRD status** persisted as `completed` with `_completionNotified`; files stay active until manual archive
70
+ 4. **PRD status** persisted as `completed` with `_completionNotified`; the SQL record stays active until manual archive
71
71
 
72
72
  `checkPlanCompletion()` also **self-heals a stale `completed` PRD**: if a completed plan later gains an unmaterialized item or one of its items regresses off a terminal status, the PRD is reverted to `active` (status flipped, `_completionNotified` cleared) so the materializer recreates the missing work item and the normal completion flow can run again.
73
73
 
@@ -75,16 +75,16 @@ When all PRD items reach `done` or `failed` status, `checkPlanCompletion()` fire
75
75
 
76
76
  ## Verification Task
77
77
 
78
- The verification task (`planItemId: "VERIFY"`) is the final step. It:
78
+ The verification task (`itemType: "verify"`, `type: "verify"`) is the final step. It:
79
79
 
80
- 1. **Creates one worktree per affected project** with all PR branches merged in not separate worktrees per branch. This means the agent builds and tests from a single directory per project with all changes combined.
80
+ 1. **Creates one worktree per affected project.** Parallel-branch plans merge that project's PR branches into it; shared-branch plans check out `origin/<feature_branch>` without merging PR branches.
81
81
 
82
82
  2. **Builds and tests** every affected project from its worktree.
83
83
 
84
- 3. **Starts the webapp** on localhost if applicable, and keeps it running so the user can see it.
84
+ 3. **Starts and smoke-checks the app** on localhost when applicable, leaving it running only when it must survive verification.
85
85
 
86
- 4. **Writes a canonical manual testing guide** (`prd/guides/verify-*.md`) plus
87
- an inbox copy (`notes/inbox/verify-*.md`) for merge decisions, containing:
86
+ 4. **Writes a canonical manual testing guide** (`prd/guides/verify-*.md`) and,
87
+ only after successful verification, an inbox copy (`notes/inbox/verify-*.md`) for merge decisions, containing:
88
88
  - Build/test status table per project
89
89
  - Feature-by-feature testing steps based on acceptance criteria
90
90
  - Integration points to verify across projects
@@ -97,20 +97,20 @@ The verification task (`planItemId: "VERIFY"`) is the final step. It:
97
97
  ```
98
98
  # project-a — 3 PRs merged into one worktree
99
99
  cd ~/project-a
100
- git fetch origin "work/PL-W001" "work/PL-W002" "work/PL-W003" "main"
101
- git worktree add "../worktrees/verify-my-plan-2026-03-15" "origin/main"
102
- cd "../worktrees/verify-my-plan-2026-03-15"
103
- git merge "origin/work/PL-W001" --no-edit
104
- git merge "origin/work/PL-W002" --no-edit
105
- git merge "origin/work/PL-W003" --no-edit
100
+ git fetch origin "work/P001" "work/P002" "work/P003" "main"
101
+ git worktree add "../worktrees/verify-project-a-my-plan-<uid>" "origin/main"
102
+ cd "../worktrees/verify-project-a-my-plan-<uid>"
103
+ git merge "origin/work/P001" --no-edit
104
+ git merge "origin/work/P002" --no-edit
105
+ git merge "origin/work/P003" --no-edit
106
106
 
107
107
  # project-b — 2 PRs merged into one worktree
108
108
  cd ~/project-b
109
- git fetch origin "feat/PL-W004" "feat/PL-W005" "master"
110
- git worktree add "../worktrees/verify-my-plan-2026-03-15" "origin/master"
111
- cd "../worktrees/verify-my-plan-2026-03-15"
112
- git merge "origin/feat/PL-W004" --no-edit
113
- git merge "origin/feat/PL-W005" --no-edit
109
+ git fetch origin "work/P004" "work/P005" "master"
110
+ git worktree add "../worktrees/verify-project-b-my-plan-<uid>" "origin/master"
111
+ cd "../worktrees/verify-project-b-my-plan-<uid>"
112
+ git merge "origin/work/P004" --no-edit
113
+ git merge "origin/work/P005" --no-edit
114
114
  ```
115
115
 
116
116
  The verify agent and the user can then build and run from these paths.