@yemi33/minions 0.1.2378 → 0.1.2380
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 +19 -9
- package/dashboard/js/refresh.js +2 -3
- package/dashboard/js/render-prd.js +1 -1
- package/dashboard/js/render-work-items.js +13 -6
- package/dashboard.js +393 -721
- package/docs/README.md +1 -0
- package/docs/architecture-review-2026-07-09.md +2 -4
- package/docs/auto-discovery.md +36 -49
- package/docs/blog-first-successful-dispatch.md +1 -1
- package/docs/branch-derivation.md +2 -2
- package/docs/command-center.md +1 -1
- package/docs/completion-reports.md +14 -4
- package/docs/constellation-bridge.md +59 -10
- package/docs/constellation-style-telemetry.md +6 -6
- package/docs/cooldown-merge-semantics.md +4 -0
- package/docs/copilot-cli-schema.md +3 -3
- package/docs/cross-repo-plans.md +17 -17
- package/docs/deprecated.json +2 -2
- package/docs/design-inbox-entries-schema.md +31 -39
- package/docs/design-state-storage.md +1 -1
- package/docs/documentation-audit-2026-07-09.md +2 -2
- package/docs/engine-restart.md +20 -8
- package/docs/harness-mode.md +1 -1
- package/docs/managed-spawn.md +4 -4
- package/docs/onboarding.md +1 -2
- package/docs/pr-comment-followup.md +3 -3
- package/docs/pr-review-fix-loop.md +1 -1
- package/docs/proposals/repo-pool-for-live-checkout.md +1 -2
- package/docs/qa-runbook-lifecycle.md +4 -4
- package/docs/qa-runbooks.md +2 -2
- package/docs/rfc-completion-json.md +4 -1
- package/docs/runtime-adapters.md +1 -1
- package/docs/self-improvement.md +4 -5
- package/docs/shared-lifecycle-module-map.md +3 -1
- package/docs/slim-ux/architecture-suggestions.md +5 -6
- package/docs/slim-ux/concepts.md +23 -25
- package/docs/watches.md +7 -7
- package/docs/workspace-manifests.md +1 -1
- package/docs/worktree-lifecycle.md +1 -1
- package/engine/abandoned-pr-reconciliation.js +4 -5
- package/engine/acp-transport.js +49 -8
- package/engine/ado-status.js +5 -5
- package/engine/ado.js +20 -25
- package/engine/agent-worker-pool.js +124 -15
- package/engine/bridge.js +260 -5
- package/engine/cleanup.js +48 -131
- package/engine/cli.js +125 -83
- package/engine/cooldown.js +9 -16
- package/engine/db/index.js +22 -9
- package/engine/db/migrations/009-qa.js +1 -1
- package/engine/db/migrations/020-qa-session-scopes.js +23 -0
- package/engine/db/migrations/021-archived-work-items.js +72 -0
- package/engine/db/migrations/022-global-cc-session.js +31 -0
- package/engine/db/migrations/023-engine-state.js +30 -0
- package/engine/db/migrations/024-prd-ghost-collisions.js +53 -0
- package/engine/db/migrations/025-malformed-work-item-phantoms.js +33 -0
- package/engine/dispatch-store.js +2 -7
- package/engine/dispatch.js +34 -41
- package/engine/github.js +20 -27
- package/engine/lifecycle.js +221 -283
- package/engine/llm.js +1 -1
- package/engine/logs-store.js +2 -2
- package/engine/managed-spawn.js +2 -23
- package/engine/meeting.js +6 -6
- package/engine/metrics-store.js +2 -2
- package/engine/note-link-backfill.js +6 -11
- package/engine/pipeline.js +18 -36
- package/engine/playbook.js +1 -1
- package/engine/pooled-agent-process.js +46 -26
- package/engine/prd-store.js +73 -54
- package/engine/preflight.js +2 -5
- package/engine/projects.js +15 -62
- package/engine/pull-requests-store.js +0 -17
- package/engine/qa-runbooks.js +2 -2
- package/engine/qa-runs.js +1 -8
- package/engine/qa-sessions.js +41 -64
- package/engine/queries.js +120 -219
- package/engine/routing.js +3 -5
- package/engine/scheduler.js +0 -4
- package/engine/shared-branch-pr-reconcile.js +2 -3
- package/engine/shared.js +132 -637
- package/engine/small-state-store.js +89 -10
- package/engine/state-operations.js +16 -4
- package/engine/stdio-timestamps.js +1 -1
- package/engine/timeout.js +5 -12
- package/engine/watch-actions.js +20 -22
- package/engine/watches-store.js +1 -1
- package/engine/watches.js +6 -10
- package/engine/work-item-validation.js +52 -0
- package/engine/work-items-store.js +127 -29
- package/engine/worktree-gc.js +2 -2
- package/engine/worktree-pool.js +8 -18
- package/engine.js +167 -349
- package/minions.js +2 -2
- package/package.json +1 -1
- package/playbooks/plan-to-prd.md +2 -2
- package/playbooks/shared-rules.md +3 -3
- package/playbooks/templates/followup-dispatch.md +1 -1
- package/playbooks/verify.md +1 -1
- package/prompts/cc-system.md +2 -2
package/docs/README.md
CHANGED
|
@@ -41,6 +41,7 @@ Architecture, design proposals, and lifecycle references for people working on t
|
|
|
41
41
|
- [cross-repo-plans.md](cross-repo-plans.md) — Cross-repo plans: a single plan whose work items ship into two or more configured projects — per-item `project` field, per-project work-item fan-out, and one verify work item per touched repo.
|
|
42
42
|
- [dead-code-audit-retractions.md](dead-code-audit-retractions.md) — Retracted dead-code-audit findings (false positives) that future audits MUST read before re-citing.
|
|
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
|
+
- [design-inbox-entries-schema.md](design-inbox-entries-schema.md) — Implemented SQL schema and store contract for the future operator/agent inbox queue, including current indexes, mutators, event emission, and integration status.
|
|
44
45
|
- [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
46
|
- [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
47
|
- [harness-propagation.md](harness-propagation.md) — The native runtime
|
|
@@ -61,10 +61,8 @@ cancellation.
|
|
|
61
61
|
|
|
62
62
|
These require separate focused changes rather than expanding this PR:
|
|
63
63
|
|
|
64
|
-
1. **Dispatch
|
|
65
|
-
|
|
66
|
-
The durable fix is a mirror-generation/hash marker or removal of the legacy
|
|
67
|
-
fallback, not moving filesystem writes inside a SQLite transaction.
|
|
64
|
+
1. **Dispatch empty-state resurrection (resolved).** The SQL-only cutover removed
|
|
65
|
+
the legacy fallback; an empty dispatch table now stays empty.
|
|
68
66
|
2. **Pipeline task terminal-state model (high).** Task stages use a boolean
|
|
69
67
|
completion check and promote failed work items to a completed pipeline stage;
|
|
70
68
|
cancelled/review-blocked work can wedge indefinitely. Replace the boolean
|
package/docs/auto-discovery.md
CHANGED
|
@@ -46,11 +46,11 @@ tick()
|
|
|
46
46
|
|
|
47
47
|
`discoverWork()` iterates every project in `config.projects[]` and runs four core discovery sources: pull requests, per-project work items, central work items, and pipeline/scheduled tasks. Results are prioritized: fixes > reviews > implements > work-items.
|
|
48
48
|
|
|
49
|
-
Before scanning, the engine materializes plans and specs into project
|
|
49
|
+
Before scanning, the engine materializes plans and specs into project-scoped SQL work items, so they're picked up by the work-items source below.
|
|
50
50
|
|
|
51
51
|
### Source 1: Pull Requests (`discoverFromPrs`)
|
|
52
52
|
|
|
53
|
-
**Reads:**
|
|
53
|
+
**Reads:** project-scoped `pull_requests` rows in `engine/state.db`
|
|
54
54
|
|
|
55
55
|
| PR State | Action | Dispatch Type |
|
|
56
56
|
|----------|--------|---------------|
|
|
@@ -92,8 +92,8 @@ Flip via Dashboard → Settings → Polling → "Granular per-poller controls" c
|
|
|
92
92
|
| Flag | Default | Phase inside `discoverWork()` |
|
|
93
93
|
|------|---------|--------------------------------|
|
|
94
94
|
| `prDiscoveryEnabled` | `true` | Per-project `discoverFromPrs(config, project)` — PR-derived fix / review / build-test work |
|
|
95
|
-
| `workItemsDiscoveryEnabled` | `true` | Per-project `discoverFromWorkItems(config, project)` — project
|
|
96
|
-
| `centralWorkDiscoveryEnabled` | `true` | `discoverCentralWorkItems(config)` —
|
|
95
|
+
| `workItemsDiscoveryEnabled` | `true` | Per-project `discoverFromWorkItems(config, project)` — project SQL scope |
|
|
96
|
+
| `centralWorkDiscoveryEnabled` | `true` | `discoverCentralWorkItems(config)` — central SQL scope |
|
|
97
97
|
| `scheduledWorkDiscoveryEnabled` | `true` | `discoverScheduledWork(config)` — cron-style scheduled tasks + scheduled meetings |
|
|
98
98
|
| `planMaterializationEnabled` | `true` | `reconcilePrdStatuses(config)` + `materializePlansAsWorkItems(config)` (paired side-effect passes) |
|
|
99
99
|
|
|
@@ -116,7 +116,7 @@ PRD items flow through `materializePlansAsWorkItems()`, which queries SQL PRDs f
|
|
|
116
116
|
|
|
117
117
|
### Source 3: Per-Project Work Items (`discoverFromWorkItems`)
|
|
118
118
|
|
|
119
|
-
**Reads:**
|
|
119
|
+
**Reads:** the project's `work_items` SQL scope
|
|
120
120
|
|
|
121
121
|
| Item State | Action | Dispatch Type |
|
|
122
122
|
|------------|--------|---------------|
|
|
@@ -126,7 +126,7 @@ After dispatching, the engine writes `status: "dispatched"` back to the item. Th
|
|
|
126
126
|
|
|
127
127
|
### Source 4: Central Work Items (`discoverCentralWorkItems`)
|
|
128
128
|
|
|
129
|
-
**Reads:**
|
|
129
|
+
**Reads:** the central `work_items` SQL scope
|
|
130
130
|
|
|
131
131
|
These are tasks where the agent decides which project to work in. The engine builds a prompt that includes a list of all linked projects with their paths and repo config. The agent then navigates to the appropriate project directory based on the task.
|
|
132
132
|
|
|
@@ -163,7 +163,7 @@ This means a single work item like "Add telemetry to the document creation pipel
|
|
|
163
163
|
**Adding central work items:**
|
|
164
164
|
- Dashboard Command Center → type your intent (no `#project` = central queue)
|
|
165
165
|
- CLI: `node engine.js work "task title"` (defaults to central queue)
|
|
166
|
-
-
|
|
166
|
+
- API: `POST /api/work-items` with no project
|
|
167
167
|
|
|
168
168
|
### Materialization: Specs and Plans → Work Items
|
|
169
169
|
|
|
@@ -184,11 +184,11 @@ priority: high
|
|
|
184
184
|
|
|
185
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
|
-
Both write to
|
|
187
|
+
Both write to the SQL work-item store and are picked up by Source 3 on the same or next tick.
|
|
188
188
|
|
|
189
189
|
## PR Status Polling (`pollPrStatus`)
|
|
190
190
|
|
|
191
|
-
**Runs:** On a wall-clock cadence derived from `prPollStatusEvery × engine.tickInterval` (default 72 × 10s, ≈ 12 minutes), independently of work discovery
|
|
191
|
+
**Runs:** On a wall-clock cadence derived from `prPollStatusEvery × engine.tickInterval` (default 72 × 10s, ≈ 12 minutes), independently of work discovery. ADO polling lives in `engine/ado.js`; GitHub polling lives in `engine/github.js` — both run in parallel each cycle (`Promise.allSettled`) and write the shared SQL PR schema. Replaces the retired agent-based `pr-sync`.
|
|
192
192
|
|
|
193
193
|
The engine directly polls the host REST API for **all** PR metadata: build/CI status, human review votes, and completion state. Two API calls per PR — no agent dispatch needed.
|
|
194
194
|
|
|
@@ -196,7 +196,7 @@ The engine directly polls the host REST API for **all** PR metadata: build/CI st
|
|
|
196
196
|
1. `GET pullrequests/{id}` → `status` (active/completed/abandoned), `mergeStatus`, `reviewers[].vote`
|
|
197
197
|
2. `GET pullrequests/{id}/statuses` → CI pipeline results
|
|
198
198
|
|
|
199
|
-
**Fields updated in
|
|
199
|
+
**Fields updated in the PR store:**
|
|
200
200
|
|
|
201
201
|
| Field | Source | Values |
|
|
202
202
|
|-------|--------|--------|
|
|
@@ -259,7 +259,7 @@ Resolution order:
|
|
|
259
259
|
|
|
260
260
|
## Dispatch Queue
|
|
261
261
|
|
|
262
|
-
Discovered items land in
|
|
262
|
+
Discovered items land in the SQL dispatch store, exposed as:
|
|
263
263
|
|
|
264
264
|
```json
|
|
265
265
|
{
|
|
@@ -330,8 +330,8 @@ claude -p --system-prompt-file <sysprompt-file> \
|
|
|
330
330
|
- CLAUDECODE env vars stripped to allow nested sessions
|
|
331
331
|
|
|
332
332
|
### 6. Track State
|
|
333
|
-
- Agent status derived from dispatch
|
|
334
|
-
- Dispatch item → moved from `pending` to `active`
|
|
333
|
+
- Agent status derived from SQL dispatch state
|
|
334
|
+
- Dispatch item → moved from `pending` to `active` transactionally
|
|
335
335
|
- Process tracked in `activeProcesses` Map for timeout monitoring
|
|
336
336
|
|
|
337
337
|
## Post-Completion
|
|
@@ -347,10 +347,10 @@ proc.on('close')
|
|
|
347
347
|
│
|
|
348
348
|
├─ Move dispatch item: active → completed
|
|
349
349
|
│
|
|
350
|
-
├─ Sync PRs from output (scan for PR URLs →
|
|
350
|
+
├─ Sync PRs from output (scan for PR URLs → SQL PR store)
|
|
351
351
|
│
|
|
352
352
|
├─ Post-completion hooks:
|
|
353
|
-
│ review → update PR minionsReview in
|
|
353
|
+
│ review → update PR minionsReview in SQL, vote on ADO
|
|
354
354
|
│ fix → set PR minionsReview back to "waiting"
|
|
355
355
|
│ build-test → record verification result and findings
|
|
356
356
|
│
|
|
@@ -386,39 +386,26 @@ Work type is auto-detected from keywords (fix, explore, test, review → impleme
|
|
|
386
386
|
│
|
|
387
387
|
┌──────────┼──────────┐
|
|
388
388
|
▼ ▼ ▼
|
|
389
|
-
work
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
▼ ▼ ▼
|
|
410
|
-
worktree claude CLI dispatch.json
|
|
411
|
-
(in project (max 100 (active/completed)
|
|
412
|
-
repo dir) turns)
|
|
413
|
-
│
|
|
414
|
-
on exit:
|
|
415
|
-
│
|
|
416
|
-
┌───────────┬───────┼───────┬──────────┐
|
|
417
|
-
▼ ▼ ▼ ▼ ▼
|
|
418
|
-
output.log notes/ PRs work-items localhost
|
|
419
|
-
(per agent) inbox/*.md .json .json (if webapp,
|
|
420
|
-
│ from build
|
|
421
|
-
consolidateInbox() & test)
|
|
389
|
+
SQL work notes/ plans/
|
|
390
|
+
items inbox/*.md *.md
|
|
391
|
+
|
|
392
|
+
Project-scoped SQL ──┐
|
|
393
|
+
Central SQL scope ───┤ discoverWork() ──► SQL dispatch rows
|
|
394
|
+
docs/**/*.md (specs) ┤ │ │
|
|
395
|
+
SQL PRDs ────────────┘ ▼ ▼
|
|
396
|
+
addToDispatch() spawnAgent()
|
|
397
|
+
│
|
|
398
|
+
ADO + GitHub REST ── pollPrStatus() ──► SQL PR rows│
|
|
399
|
+
▼
|
|
400
|
+
worktree + runtime CLI
|
|
401
|
+
│
|
|
402
|
+
on exit:
|
|
403
|
+
│
|
|
404
|
+
┌───────────┬───────────────┼──────────┐
|
|
405
|
+
▼ ▼ ▼ ▼
|
|
406
|
+
output.log notes/inbox SQL state localhost
|
|
407
|
+
│ (if webapp)
|
|
408
|
+
consolidateInbox()
|
|
422
409
|
(at 5+ files)
|
|
423
410
|
│
|
|
424
411
|
▼
|
|
@@ -451,7 +438,7 @@ Lack of stdout/stderr is not treated as a hang while the engine still has a live
|
|
|
451
438
|
| Pull requests | 30 minutes | After dispatching a review, won't re-queue for 30min |
|
|
452
439
|
| Work items | 0 (immediate) | No cooldown, but item status changes to "dispatched" |
|
|
453
440
|
|
|
454
|
-
Cooldowns are persisted
|
|
441
|
+
Cooldowns are persisted in SQLite and reloaded on engine startup. Entries older than 24 hours are pruned. `isAlreadyDispatched()` also checks pending, active, and recently completed SQL dispatch rows.
|
|
455
442
|
|
|
456
443
|
## Configuration Reference
|
|
457
444
|
|
|
@@ -79,7 +79,7 @@ New approach: rely on the tracked process while the engine has a live process ha
|
|
|
79
79
|
|
|
80
80
|
### Engine Restart Orphan Problem
|
|
81
81
|
|
|
82
|
-
When the engine restarts, the in-memory `activeProcesses` Map is lost. Active dispatch
|
|
82
|
+
When the engine restarts, the in-memory `activeProcesses` Map is lost. Active dispatch rows stay in SQLite but the engine has no process handle. Old stale detection (6h threshold) was too slow to catch this. Stale-orphan detection uses recent `live-output.log` activity and catches abandoned dispatches after the restart grace window.
|
|
83
83
|
|
|
84
84
|
## The Successful Run
|
|
85
85
|
|
|
@@ -64,7 +64,7 @@ number namespace, and ADO work items share theirs. Before this guard, a
|
|
|
64
64
|
`type: "fix"` WI titled `Fix github:owner/repo#244: …` where **#244 is an
|
|
65
65
|
issue** got `targetPr` / `pr_id` / `prNumber` stamped by
|
|
66
66
|
`dashboard.js#copyWorkItemPrFields`, which then (a) minted a phantom
|
|
67
|
-
|
|
67
|
+
PR-store record (`agent: 'human'`, went abandoned, polluted the PR
|
|
68
68
|
count) via `shared.autoEnrollPrFromFixWorkItem`, and (b) routed the dispatch
|
|
69
69
|
through the PR-fix path (`targetPr`/`pr_id`/`prNumber`) instead of
|
|
70
70
|
implement-and-open-a-fresh-PR.
|
|
@@ -76,7 +76,7 @@ stamping:
|
|
|
76
76
|
/ `meta.pr_followup.parent_pr_url` are explicit operator intent and stamp
|
|
77
77
|
with **no** network call.
|
|
78
78
|
2. **Loose (description/title-scanned) refs on a fix WI** are confirmed via:
|
|
79
|
-
- an already-tracked
|
|
79
|
+
- an already-tracked SQL PR record for the ref (cheap, no
|
|
80
80
|
network), else
|
|
81
81
|
- a host existence check — `engine/github.js#prExists` (`gh api
|
|
82
82
|
repos/:owner/:repo/pulls/NNN`; 404 ⇒ issue) or `engine/ado.js#prExists`
|
package/docs/command-center.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
The Command Center (CC) is the dashboard's conversational chat panel. It opens from the **CC** button in the top-right header and lets you drive the engine — dispatching work items, saving notes, approving plans, and asking questions about Minions state — through a persistent session on the configured CC runtime.
|
|
4
4
|
|
|
5
|
-
CC is intentionally a thin wrapper around the runtime CLI: state changes happen via tool-driven calls to the dashboard's own REST API, not via parsed delimiter blocks. The end-to-end flow is `dashboard/js/command-center.js` `_ccDoSend()` → `POST /api/command-center` (or `/api/command-center/stream`) in `dashboard.js` (`handleCommandCenter`) → `engine/llm.js` `callLLM({ direct: true })` → runtime session persisted in `engine/state.db` (`cc_sessions
|
|
5
|
+
CC is intentionally a thin wrapper around the runtime CLI: state changes happen via tool-driven calls to the dashboard's own REST API, not via parsed delimiter blocks. The end-to-end flow is `dashboard/js/command-center.js` `_ccDoSend()` → `POST /api/command-center` (or `/api/command-center/stream`) in `dashboard.js` (`handleCommandCenter`) → `engine/llm.js` `callLLM({ direct: true })` → runtime session persisted in `engine/state.db` (`cc_sessions`). Per-turn API mutations are correlated via the `X-CC-Turn-Id` header and surfaced as standalone `role='action'` chips rendered outside the assistant bubble (`_ccActionResultLine` + `addMsg('action', ...)`).
|
|
6
6
|
|
|
7
7
|
For canonical detail (system prompt, session lifecycle, turn-ID surfacing pipeline, doc-chat integration, and CC API contract), read [`CLAUDE.md`](../CLAUDE.md) — see the **CC API Contract** and **Sessions** sections — and the source in [`dashboard/js/command-center.js`](../dashboard/js/command-center.js), [`dashboard.js`](../dashboard.js) (`handleCommandCenter`), and [`prompts/cc-system.md`](../prompts/cc-system.md).
|
|
8
8
|
|
|
@@ -6,9 +6,11 @@ This document is the canonical schema. Playbooks should cross-link here instead
|
|
|
6
6
|
|
|
7
7
|
## Where the report is written
|
|
8
8
|
|
|
9
|
-
The engine
|
|
9
|
+
The engine delivers the absolute path two ways before spawning each agent:
|
|
10
10
|
|
|
11
|
-
- `MINIONS_COMPLETION_REPORT` environment
|
|
11
|
+
- `MINIONS_COMPLETION_REPORT` in the child environment for cold spawns, or the
|
|
12
|
+
same-named authoritative value in the trusted ACP session context for pooled
|
|
13
|
+
spawns
|
|
12
14
|
- The same path appears in the rendered playbook prompt
|
|
13
15
|
|
|
14
16
|
Path shape (resolved by `shared.dispatchCompletionReportPath()` in `engine/shared.js`):
|
|
@@ -21,7 +23,15 @@ The agent must write the JSON to that exact path before exiting. Any character o
|
|
|
21
23
|
|
|
22
24
|
## Trust boundary
|
|
23
25
|
|
|
24
|
-
Each spawn also receives a per-dispatch cryptographic value
|
|
26
|
+
Each spawn also receives a per-dispatch cryptographic value named
|
|
27
|
+
`MINIONS_COMPLETION_NONCE`. Cold spawns receive it in the child environment;
|
|
28
|
+
pooled ACP spawns receive it in trusted, lease-scoped system context so the
|
|
29
|
+
nonce never enters reusable process state or untrusted task content. The engine
|
|
30
|
+
generates it with `crypto.randomBytes(16).toString('hex')` in
|
|
31
|
+
`engine.js:spawnAgent()` and stores it on the in-memory active-process record.
|
|
32
|
+
The agent is required to copy the value verbatim into the report's `nonce`
|
|
33
|
+
field. On parse, `engine/lifecycle.js:runPostCompletionHooks()` compares
|
|
34
|
+
`report.nonce` against the in-memory value:
|
|
25
35
|
|
|
26
36
|
- **Match** — the report is trusted and processed normally.
|
|
27
37
|
- **Mismatch** — the report is treated as forged (a prompt-injected agent or a stale process writing into a sibling dispatch's completion path). Every signal it carries — `status`, `pr`, `noop`, `failure_class`, `retryable`, `needs_rerun`, artifacts, follow-ups — is discarded. The dispatch is failed with `failure_class: 'completion-nonce-mismatch'` and the work item is marked failed (no auto-retry honors the agent's `retryable` claim).
|
|
@@ -263,7 +273,7 @@ optional `followups` array on its completion report:
|
|
|
263
273
|
Engine behavior (`engine/lifecycle.js` `processCompletionFollowups`):
|
|
264
274
|
|
|
265
275
|
- Each entry is logged at `info`: `Followup audit (<agent> wi=<parent>): dispatched <wi_id> — <title> (comment=<id>) — <reason>`.
|
|
266
|
-
- If the claimed `wi_id` does not exist in any project
|
|
276
|
+
- If the claimed `wi_id` does not exist in any project SQL scope at parse time, a `warn` is emitted. This catches dispatches that were deduped to a 409 / 200-duplicate response, reverted, or never actually landed.
|
|
267
277
|
- The `followups` array is **descriptive only** — the engine does not auto-create or auto-link these WIs from the report. Creation happens at the moment the agent calls `POST /api/work-items`; the report is just the auditable record.
|
|
268
278
|
- Malformed entries (non-object, missing `wi_id`) are logged and skipped.
|
|
269
279
|
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
# Constellation bridge
|
|
2
2
|
|
|
3
|
-
Minions ships a
|
|
3
|
+
Minions ships a versioned read-only surface that the [Constellation](https://office.visualstudio.com/DefaultCollection/ISS/_git/constellation) agent polls to mirror a locally-running Minions instance into its cloud HUD. Minions remains the execution and state authority on the DevBox; Constellation stores only the bounded metadata projection documented here.
|
|
4
4
|
|
|
5
|
-
> **The bridge polling logic itself lives in the Constellation repo** (`packages/agent/src/
|
|
5
|
+
> **The bridge polling logic itself lives in the Constellation repo** (`packages/agent/src/orchestrator-bridge/`). Minions owns the snapshot contract, the on/off flag, the marker-file contract, and the `minions bridge` subcommand for local debugging.
|
|
6
6
|
|
|
7
7
|
## Quick start
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
minions bridge status # Show enabled flag + last-seen Constellation agent
|
|
11
|
-
minions bridge health # Probe
|
|
11
|
+
minions bridge health # Probe /api/constellation/v1/snapshot and print its metadata summary
|
|
12
12
|
minions bridge enable # Set engine.constellationBridge.enabled = true
|
|
13
13
|
minions bridge disable # Set engine.constellationBridge.enabled = false
|
|
14
14
|
```
|
|
@@ -38,6 +38,52 @@ minions bridge disable
|
|
|
38
38
|
|
|
39
39
|
Both subcommands write `~/.minions/config.json` atomically via `mutateJsonFileLocked`, so concurrent edits from the engine/dashboard cannot tear the file.
|
|
40
40
|
|
|
41
|
+
## Versioned snapshot contract
|
|
42
|
+
|
|
43
|
+
The Constellation agent polls:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
GET http://127.0.0.1:7331/api/constellation/v1/snapshot
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The endpoint is loopback-only because the Minions dashboard binds `127.0.0.1`. It supports `ETag` and `If-None-Match`; unchanged state returns `304` with no body. A `200` response is a **complete replacement snapshot**, so consumers must remove previously mirrored entities that are absent from the latest response.
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"protocol": "minions.constellation.snapshot",
|
|
54
|
+
"protocolVersion": 1,
|
|
55
|
+
"complete": true,
|
|
56
|
+
"generatedAt": "2026-07-13T08:00:00.000Z",
|
|
57
|
+
"minionsVersion": "0.1.2203",
|
|
58
|
+
"engine": { "state": "running", "pid": 1234 },
|
|
59
|
+
"entities": {
|
|
60
|
+
"work_item": [],
|
|
61
|
+
"pr": [],
|
|
62
|
+
"plan": [],
|
|
63
|
+
"schedule": [],
|
|
64
|
+
"dispatch": [],
|
|
65
|
+
"agent_status": [],
|
|
66
|
+
"device_summary": []
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
`protocolVersion` changes only for a breaking schema change. Additive optional fields do not require a version bump.
|
|
72
|
+
|
|
73
|
+
### Privacy boundary
|
|
74
|
+
|
|
75
|
+
Every entity is rebuilt from an explicit allowlist in `engine/bridge.js`; raw dashboard records are never forwarded. The snapshot excludes task descriptions, prompts, acceptance criteria, completion reports, diffs, comments, human feedback, notes, logs, filesystem paths, environment variables, tokens, and secrets. Strings are length-capped to the matching Constellation schema limits.
|
|
76
|
+
|
|
77
|
+
The entity shapes match `packages/shared/src/orchestrator-messages.ts` in the Constellation repository:
|
|
78
|
+
|
|
79
|
+
- `work_item`: identifiers, title, type/priority/status, project/agent, lifecycle timestamps.
|
|
80
|
+
- `pr`: identifiers, title/status/review status, branch/URL, merge metadata and timestamps.
|
|
81
|
+
- `plan`: identifier, title/status, project/agent and timestamps.
|
|
82
|
+
- `schedule`: identifier, title/type/status, project/agent and run timestamps.
|
|
83
|
+
- `dispatch`: identifier, agent/status/type/project, linked WI/PR and lifecycle timestamps.
|
|
84
|
+
- `agent_status`: agent/status/project, current task identifiers/title and update time.
|
|
85
|
+
- `device_summary`: aggregate counts plus protocol, Minions version and engine health.
|
|
86
|
+
|
|
41
87
|
## Marker-file contract
|
|
42
88
|
|
|
43
89
|
The Constellation agent's bridge writes a marker file on every successful poll. Minions reads it with `minions bridge status` so a local operator can verify the bridge is alive and Constellation is talking to it.
|
|
@@ -67,21 +113,24 @@ Writers MUST use an atomic-replace pattern (`write to tmp + rename`) so a partia
|
|
|
67
113
|
|
|
68
114
|
## `minions bridge health`
|
|
69
115
|
|
|
70
|
-
`bridge health` performs a synchronous probe of the
|
|
116
|
+
`bridge health` performs a synchronous probe of the versioned snapshot endpoint and prints its aggregate metadata. This verifies both dashboard reachability and protocol compatibility.
|
|
71
117
|
|
|
72
118
|
Sample output:
|
|
73
119
|
|
|
74
120
|
```text
|
|
75
121
|
bridge: dashboard reachable on http://127.0.0.1:7331
|
|
76
|
-
|
|
122
|
+
snapshot (same metadata the Constellation bridge mirrors):
|
|
123
|
+
protocolVersion: 1
|
|
124
|
+
minionsVersion: 0.1.2203
|
|
77
125
|
engineState: running
|
|
78
126
|
enginePid: 1234
|
|
79
|
-
minionsVersion: 0.1.1984
|
|
80
127
|
agentCount: 5
|
|
81
128
|
activeAgentCount: 2
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
129
|
+
workItemCount: 18
|
|
130
|
+
pullRequestCount: 4
|
|
131
|
+
planCount: 2
|
|
132
|
+
scheduleCount: 3
|
|
133
|
+
dispatchCount: 14
|
|
85
134
|
projectCount: 3
|
|
86
135
|
```
|
|
87
136
|
|
|
@@ -89,6 +138,6 @@ If the dashboard is not listening, `bridge health` prints `dashboard not running
|
|
|
89
138
|
|
|
90
139
|
## Cross-repo coordination
|
|
91
140
|
|
|
92
|
-
The
|
|
141
|
+
The Minions producer lands before the Constellation consumer. During rollout, Constellation may fall back to the legacy per-endpoint projection only when the versioned endpoint returns `404`; a malformed versioned response must fail closed rather than silently downgrading.
|
|
93
142
|
|
|
94
143
|
The Constellation agent's bridge reads `~/.minions/config.json` directly (no Minions HTTP API call) so config edits propagate without waiting for the engine to restart.
|
|
@@ -62,12 +62,12 @@ Key design properties:
|
|
|
62
62
|
|
|
63
63
|
| Constellation concept | Minions equivalent today |
|
|
64
64
|
|---|---|
|
|
65
|
-
| `metrics_daily` rollups | `
|
|
65
|
+
| `metrics_daily` rollups | SQL metrics `_daily.<YYYY-MM-DD>` → `{costUsd, inputTokens, outputTokens, cacheRead, tasks}` |
|
|
66
66
|
| Per-entity aggregates | Per-agent counters: `tasksCompleted/Errored`, `prsCreated/Approved/Rejected/Merged`, `reviewsDone`, `totalCostUsd`, `totalInputTokens/OutputTokens/CacheRead`, `totalRuntimeMs`, `model`, `timedTasks` |
|
|
67
|
-
| App/engine analytics | `
|
|
67
|
+
| App/engine analytics | SQL metrics `_engine`: `command-center`, `agent-dispatch`, `consolidation`, `agent_memory_reconcile` |
|
|
68
68
|
| Emit helpers | `llm.trackEngineUsage()`, `trackReviewMetric()`, `updateMetrics()` (`engine/lifecycle.js`, `engine/llm.js`, `engine/shared.js`) |
|
|
69
69
|
| Structured error taxonomy | `FAILURE_CLASS` constants (recorded per work-item; not yet aggregated as a metric) |
|
|
70
|
-
| Diagnostic stream |
|
|
70
|
+
| Diagnostic stream | SQL log tail (secret-redacted via `redactSecrets()`) + `engine/dashboard-diagnostics.log` |
|
|
71
71
|
| Admin overview query | `getMetrics()` (`engine/queries.js`) surfaced via `/api/status` |
|
|
72
72
|
|
|
73
73
|
## The gap (the 40% worth building)
|
|
@@ -109,9 +109,9 @@ review verdicts, CC turns. Gitignored runtime file (add to the State Files list
|
|
|
109
109
|
|
|
110
110
|
### Phase 2 — Rollup + retention (small, ~½ day)
|
|
111
111
|
Extend the existing daily-rollup path so it also folds event counts + failure-category tallies into
|
|
112
|
-
`
|
|
112
|
+
SQL metrics `_daily`. Prune `events.jsonl` lines older than `telemetryRetentionDays` **after** the
|
|
113
113
|
rollup write succeeds (Constellation's invariant). Slots into an existing periodic tick phase.
|
|
114
|
-
All
|
|
114
|
+
All metric writes go through the SQL metrics store.
|
|
115
115
|
|
|
116
116
|
### Phase 3 — Usage dashboard page (medium, ~1–1.5 days)
|
|
117
117
|
New sidebar page reading `getMetrics()` + `_daily`: cost/token trend, dispatches-by-type,
|
|
@@ -156,6 +156,6 @@ the other HTML entry points; counters from an in-memory registry, no client libr
|
|
|
156
156
|
`packages/server/src/api/prism.ts`, `packages/dashboard/src/prism/prism-telemetry.ts`
|
|
157
157
|
- Constellation taxonomy/privacy: `packages/shared/src/constants.ts`,
|
|
158
158
|
`packages/shared/src/privacy.ts`
|
|
159
|
-
- Minions today: `engine/
|
|
159
|
+
- Minions today: `engine/state.db` metrics, `getMetrics()` (`engine/queries.js`),
|
|
160
160
|
`trackEngineUsage()` (`engine/llm.js`), `FAILURE_CLASS` (`engine/shared.js`),
|
|
161
161
|
related design doc `design-state-storage.md`.
|
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# `saveCooldowns` merge semantics
|
|
2
2
|
|
|
3
|
+
> **Historical design record:** this predates the SQL-only cutover. Cooldowns now
|
|
4
|
+
> persist through `engine/small-state-store.js`; file and lock references below
|
|
5
|
+
> describe the superseded implementation evaluated by the original PRD.
|
|
6
|
+
|
|
3
7
|
Scoping deliverable for PRD item **P-bfa3a-scope-cooldown-merge** (Wave 3, PR10
|
|
4
8
|
pre-work) of the 2026-05-27 weekly bug-audit plan. Decides the merge strategy
|
|
5
9
|
the implementation PR (**P-bfa3b-cooldown-lost-update**) will apply at
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
| Default | Value |
|
|
32
32
|
|---|---|
|
|
33
33
|
| `copilotStreamMode` (default config field) | `'on'` — preserves incremental UX; the adapter parser tolerates either mode. |
|
|
34
|
-
| `copilotDisableBuiltinMcps` | `true` — github-mcp-server bypasses Minions'
|
|
34
|
+
| `copilotDisableBuiltinMcps` | `true` — github-mcp-server bypasses Minions' SQL PR tracking; default OFF. |
|
|
35
35
|
| `copilotReasoningSummaries` | `false` — opt-in; only some models honor it. |
|
|
36
36
|
|
|
37
37
|
---
|
|
@@ -513,13 +513,13 @@ that default.
|
|
|
513
513
|
server is still *registered* (Copilot inventories it for diagnostics), but the
|
|
514
514
|
agent cannot use its tools. This is the desired behavior — Minions wants the
|
|
515
515
|
server invisible to the agent so all GitHub mutations route through the
|
|
516
|
-
project's
|
|
516
|
+
project's PR store rather than spawning ghost PRs.
|
|
517
517
|
|
|
518
518
|
> **Tooltip text for the dashboard `copilotDisableBuiltinMcps` toggle**
|
|
519
519
|
> (per P-7a5c1f8e):
|
|
520
520
|
>
|
|
521
521
|
> > When OFF, agents can autonomously create PRs / labels / comments via the
|
|
522
|
-
> > github-mcp-server, bypassing Minions'
|
|
522
|
+
> > github-mcp-server, bypassing Minions' PR tracking. Leave
|
|
523
523
|
> > this ON unless you have a specific reason to expose the server.
|
|
524
524
|
|
|
525
525
|
---
|
package/docs/cross-repo-plans.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Cross-repo plans
|
|
2
2
|
|
|
3
|
-
> A cross-repo plan is a single Minions plan whose work items ship into **two or more configured projects**. The plan has no owning project; each `missing_features` item declares its own `project`, the materializer fans
|
|
3
|
+
> A cross-repo plan is a single Minions plan whose work items ship into **two or more configured projects**. The plan has no owning project; each `missing_features` item declares its own `project`, the materializer fans items into per-project SQL scopes, and verify completion fans out into one verify work item per touched repo.
|
|
4
4
|
>
|
|
5
5
|
> Shipped by `PL-cross-repo-coordination` (`prd/minions-opg-2026-06-10-3.json`, items `P-7a3f1c08` … `P-8b5d3e07`). Default plan shape is unchanged for single-project plans — everything in this doc only activates when the plan markdown declares more than one project.
|
|
6
6
|
|
|
@@ -77,22 +77,22 @@ The top-level `project` is empty. Each item names its own repo. `depends_on` may
|
|
|
77
77
|
|
|
78
78
|
## Per-item project routing
|
|
79
79
|
|
|
80
|
-
`engine.js#materializePlansAsWorkItems`
|
|
80
|
+
`engine.js#materializePlansAsWorkItems` groups PRD `missing_features` by `item.project`, then writes each group transactionally to that project's SQL work-item scope. The routing rules:
|
|
81
81
|
|
|
82
82
|
| `item.project` value | Where it lands |
|
|
83
83
|
| --- | --- |
|
|
84
|
-
| Names a configured project | That project's
|
|
84
|
+
| Names a configured project | That project's SQL scope |
|
|
85
85
|
| Names an unknown project | Skipped; PRD item stamped with `_invalidProject: <error>` (see `formatUnknownProjectError`) |
|
|
86
86
|
| Unset, and central WIs disabled | Falls back to the plan-level `defaultProject` (or skipped if neither is resolvable) |
|
|
87
|
-
| Unset, and central WIs enabled | Lands in central
|
|
87
|
+
| Unset, and central WIs enabled | Lands in the central SQL scope |
|
|
88
88
|
|
|
89
|
-
The materializer
|
|
89
|
+
The materializer uses one transaction per project scope (`mutateWorkItems(project, …)`). Cross-project re-opens are queued as `deferredReopens` and executed outside the current project's transaction.
|
|
90
90
|
|
|
91
|
-
**Reconciliation, PRD-removal sync, and `i.projects[]` rollup** all happen per-project under the same loop. Per-item state is owned by exactly one
|
|
91
|
+
**Reconciliation, PRD-removal sync, and `i.projects[]` rollup** all happen per-project under the same loop. Per-item state is owned by exactly one SQL scope at a time.
|
|
92
92
|
|
|
93
93
|
## Cycle detection (runs ONCE over the whole plan)
|
|
94
94
|
|
|
95
|
-
`detectDependencyCycles(plan.missing_features)` (`engine.js:4638`) runs once over the full PRD `missing_features` set **before** the per-project grouping loop, so a cyclic chain that crosses repos (e.g. `P-aaa1` in `minions` → `P-bbb2` in `minions-opg` → `P-aaa1`) is detected and every cyclic item is skipped at materialization time — neither project's
|
|
95
|
+
`detectDependencyCycles(plan.missing_features)` (`engine.js:4638`) runs once over the full PRD `missing_features` set **before** the per-project grouping loop, so a cyclic chain that crosses repos (e.g. `P-aaa1` in `minions` → `P-bbb2` in `minions-opg` → `P-aaa1`) is detected and every cyclic item is skipped at materialization time — neither project's scope receives the cyclic items.
|
|
96
96
|
|
|
97
97
|
Caveat: `detectDependencyCycles` is a partial DFS — 2-cycles (`A → B → A`) are fully detected, but N-cycles ≥ 3 with distinct nodes only flag the back-edge target and recursing parent. Both legs of a 2-cycle and the canonical back-edge of a longer cycle reliably get skipped. Fixing the partial detector is tracked separately; cross-repo plans inherit the same behaviour as single-project plans.
|
|
98
98
|
|
|
@@ -126,7 +126,7 @@ for each project P in itemsByProject (excluding the `_central` bucket):
|
|
|
126
126
|
git push -u origin <branch> # no-op if origin already has the tip
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
-
The block is fully idempotent — `rev-parse --verify` guards the local `git branch` create, and `git push -u origin <branch>` is a no-op when origin already has the tip. Per-project failure isolation is explicit: a broken `localPath` or git config in one project logs a warn and continues to the next. The `_central` pseudo-project bucket
|
|
129
|
+
The block is fully idempotent — `rev-parse --verify` guards the local `git branch` create, and `git push -u origin <branch>` is a no-op when origin already has the tip. Per-project failure isolation is explicit: a broken `localPath` or git config in one project logs a warn and continues to the next. The `_central` pseudo-project bucket is skipped because it has no project root.
|
|
130
130
|
|
|
131
131
|
This is what makes the per-project dispatcher's later `git worktree add ... origin/<branch>` work — each project's origin already has the branch pointing at its own main, and parallel dispatches across repos can each commit + push to the same branch name in their own repo independently.
|
|
132
132
|
|
|
@@ -134,7 +134,7 @@ This is what makes the per-project dispatcher's later `git worktree add ... orig
|
|
|
134
134
|
|
|
135
135
|
## Per-project dispatch (read-side)
|
|
136
136
|
|
|
137
|
-
`engine.js#discoverFromWorkItems(config, project)`
|
|
137
|
+
`engine.js#discoverFromWorkItems(config, project)` reads exactly one project SQL scope per call, routes pending items via `routing.md`, and returns `newWork[]` entries for the dispatcher. Cross-repo plans don't change this loop; the engine iterates all configured projects per tick.
|
|
138
138
|
|
|
139
139
|
Module-level `_claimedAgents` in `engine/routing.js` persists across in-process calls but is cleared per tick (`routing.resetClaims()`), so two items in different projects routed to the same agent in the same tick contend correctly for the single agent slot.
|
|
140
140
|
|
|
@@ -145,7 +145,7 @@ Module-level `_claimedAgents` in `engine/routing.js` persists across in-process
|
|
|
145
145
|
1. Every PRD `missing_features` item has been materialized into a WI.
|
|
146
146
|
2. Every materialized WI is in a terminal state (`DONE_STATUSES` or `cancelled`).
|
|
147
147
|
|
|
148
|
-
When both gates pass, the function groups **active PRs** by project
|
|
148
|
+
When both gates pass, the function groups **active PRs** by project from the SQL PR store and joins them to done items through the `pr_links` table. The result is a `touchedProjects` array: every project that has at least one active PR linked to one of the plan's done items.
|
|
149
149
|
|
|
150
150
|
For each touched project the fan-out (lines 245–415):
|
|
151
151
|
|
|
@@ -155,7 +155,7 @@ For each touched project the fan-out (lines 245–415):
|
|
|
155
155
|
- **Shared-branch plans** reuse `feature_branch` directly — the verify agent checks out the branch in-place in the project's localPath.
|
|
156
156
|
- **Parallel-branch plans** merge each linked PR branch into a per-project worktree at `<localPath>/../worktrees/verify-<projName>-<planSlug>`.
|
|
157
157
|
- Validates every branch ref through `shared.validateGitRef` before splicing into the bash setup commands (P-f3-verify-prompt — defense in depth against shell injection from a crafted `feature_branch` or PR `branch` field).
|
|
158
|
-
- Writes a new verify WI into the touched project's
|
|
158
|
+
- Writes a new verify WI into the touched project's SQL scope with `itemType: 'verify'`, `type: 'verify'`, `priority: 'high'`, `status: 'pending'`, and `project: <projName>`. The title is project-prefixed (`Verify plan (minions-opg): …`) when `touchedProjects.length > 1` to disambiguate the dashboard listing.
|
|
159
159
|
|
|
160
160
|
**Fallback:** when no PRs were ever linked (e.g. items completed without PR records, or legacy state), the fan-out collapses to a single verify WI on the **primary project** (the project with the most completed items) so the plan still gets verified.
|
|
161
161
|
|
|
@@ -240,13 +240,13 @@ Operator approves the plan. Plan-to-prd dispatches against the `minions` project
|
|
|
240
240
|
|
|
241
241
|
Engine ticks once:
|
|
242
242
|
|
|
243
|
-
1. `materializePlansAsWorkItems` groups by project: `{ minions: [P-001], minions-opg: [P-002] }`. Cycle scan runs once over both items, finds nothing. Writes
|
|
243
|
+
1. `materializePlansAsWorkItems` groups by project: `{ minions: [P-001], minions-opg: [P-002] }`. Cycle scan runs once over both items, finds nothing. Writes P-001 and P-002 to their respective SQL scopes. Branch-strategy is `parallel`, so no shared-branch pre-create runs.
|
|
244
244
|
2. `discoverFromWorkItems(config, minions)` picks up P-001, routes it via `routing.md`, dispatches `implement` agent. Worktree created on `work/P-001` off `minions`' main.
|
|
245
245
|
3. `discoverFromWorkItems(config, minions-opg)` picks up P-002. Its `depends_on: ["P-001"]` resolves to a same-project dep? **No** — P-001 lives in the `minions` project, so it's a **cross-repo dep**. The dispatcher fetches P-001's branch into the `minions` rootDir, transfer-fetches it into the `minions-opg` worktree under `refs/cross-repo-deps/work/P-001`, computes a short SHA + changed-file list, and appends a `## Cross-repo dependencies` section to the prompt. The agent inspects via `git show` / `git log` and ships matching code in `minions-opg`.
|
|
246
|
-
4. Both items complete with PRs. `
|
|
246
|
+
4. Both items complete with PRs. SQL `pr_links` rows link each PR to its WI.
|
|
247
247
|
5. Next tick `lifecycle.checkPlanCompletion` runs. Gates pass (every item materialized + done). Groups active PRs by project: `{ minions: [PR for P-001], minions-opg: [PR for P-002] }`. Creates two verify WIs:
|
|
248
|
-
- `(minions)` verify WI in `
|
|
249
|
-
- `(minions-opg)` verify WI in `
|
|
248
|
+
- `(minions)` verify WI in the `minions` scope with `project: 'minions'`.
|
|
249
|
+
- `(minions-opg)` verify WI in the `minions-opg` scope with `project: 'minions-opg'`.
|
|
250
250
|
6. Both verify agents dispatch in parallel. Each builds + tests its own repo. Each writes `prd/guides/verify-cross-repo-launch.md` in its own repo's worktree.
|
|
251
251
|
7. Dashboard plan card shows `minions 2/2 · minions-opg 2/2` rollup pills and two labelled verify badges. Operator archives the plan via `POST /api/plans/archive` when both verifies complete.
|
|
252
252
|
|
|
@@ -267,7 +267,7 @@ When you need to change the cross-repo path, the load-bearing seams are:
|
|
|
267
267
|
| Shared-branch pre-create per project | `engine.js:5318–5356` | Idempotent `rev-parse` → `branch` → `push -u`; per-project failure isolation. |
|
|
268
268
|
| Cross-repo dep partitioning + advisory fetch | `engine.js:2495–2682` (`spawnAgent` dep loop) | `isCrossRepo` split; transfer-fetch via filesystem-path remote into `refs/cross-repo-deps/<branch>`. |
|
|
269
269
|
| Cross-repo dep prompt section | `engine.js:662–710` (`buildCrossRepoDepsSection`) | Renders one section per dep with repo, branch, SHA, files, local ref. |
|
|
270
|
-
| Per-project verify fan-out | `engine/lifecycle.js
|
|
270
|
+
| Per-project verify fan-out | `engine/lifecycle.js` (`checkPlanCompletion`) | Group active PRs by project via SQL links; one verify WI per touched project. |
|
|
271
271
|
| Verify WI creation | `engine/lifecycle.js:387–411` | `itemType:'verify'`, `project: projName`, project-prefixed title when `touchedProjects.length > 1`. |
|
|
272
272
|
| Per-project rollup pills | `dashboard.js#handlePlansList` (P-66b1faec) | Gate `_perProjectProgress.length >= 2`. |
|
|
273
273
|
| Per-project verify badges | `dashboard/js/render-plans.js` (P-d7e592b1) | Gate `verifyWis.length >= 2`. |
|
|
@@ -277,7 +277,7 @@ When you need to change the cross-repo path, the load-bearing seams are:
|
|
|
277
277
|
|
|
278
278
|
`test/integration/cross-repo-plan-e2e.test.js` (P-8b5d3e07) drives the four load-bearing seams against the real engine code in an isolated `MINIONS_TEST_DIR` (no live state touched, no agents spawned):
|
|
279
279
|
|
|
280
|
-
1. PRD with per-item `project` fans into per-project
|
|
280
|
+
1. PRD with per-item `project` fans into per-project SQL scopes (alpha vs beta).
|
|
281
281
|
2. `discoverFromWorkItems(config, project)` returns only the queried project's items.
|
|
282
282
|
3. `checkPlanCompletion` creates one verify WI per touched project when each project has at least one active PR linked to a done WI.
|
|
283
283
|
4. A 3-feature cyclic chain that crosses project boundaries (alpha → beta → alpha) is detected and none of the cyclic items are written.
|
package/docs/deprecated.json
CHANGED
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
"LEGACY_DONE_ALIASES",
|
|
44
44
|
"LEGACY_NEEDS_REVIEW_STATUS"
|
|
45
45
|
],
|
|
46
|
-
"reason": "Read-side tolerance: cleanup sweep auto-migrates four obsolete work-item / PRD status strings ('in-pr', 'implemented', 'complete', 'needs-human-review') to the canonical 'done' / 'failed' values. The aliases are no longer written anywhere in the engine; the constants exist only to repair stale
|
|
46
|
+
"reason": "Read-side tolerance: cleanup sweep auto-migrates four obsolete work-item / PRD status strings ('in-pr', 'implemented', 'complete', 'needs-human-review') to the canonical 'done' / 'failed' values. The aliases are no longer written anywhere in the engine; the constants exist only to repair stale SQL records imported from old engine versions.",
|
|
47
47
|
"status": "active",
|
|
48
48
|
"targetRemovalDate": null,
|
|
49
|
-
"notes": "Keep indefinitely until telemetry
|
|
49
|
+
"notes": "Keep indefinitely until telemetry shows zero migrations for 30 consecutive days across all project scopes and PRDs. At that point the constants and both _migrateLegacyItem branches in engine/cleanup.js can be deleted."
|
|
50
50
|
},
|
|
51
51
|
{
|
|
52
52
|
"id": "config-claude-binary-override",
|