@yemi33/minions 0.1.2447 → 0.1.2449
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/cli-api-client.js +1 -1
- package/bin/install-internal-minions.js +1382 -44
- package/bin/install-layout.js +150 -0
- package/bin/minions.js +460 -167
- package/dashboard/docs/typography.md +65 -12
- package/dashboard/js/command-center.js +66 -7
- package/dashboard/js/detail-panel.js +36 -0
- package/dashboard/js/memory-panel.js +59 -12
- package/dashboard/js/qa.js +186 -45
- package/dashboard/js/refresh.js +148 -12
- package/dashboard/js/render-dispatch.js +3 -4
- package/dashboard/js/render-inbox.js +2 -2
- package/dashboard/js/render-other.js +3 -3
- package/dashboard/js/render-pipelines.js +14 -0
- package/dashboard/js/render-plans.js +57 -9
- package/dashboard/js/render-prd.js +132 -23
- package/dashboard/js/render-prs.js +195 -166
- package/dashboard/js/render-schedules.js +63 -3
- package/dashboard/js/render-utils.js +3 -3
- package/dashboard/js/render-watches.js +19 -3
- package/dashboard/js/render-work-items.js +238 -30
- package/dashboard/js/settings.js +205 -54
- package/dashboard/js/utils.js +51 -1
- package/dashboard/pages/home.html +1 -1
- package/dashboard/pages/qa.html +1 -16
- package/dashboard/pages/work.html +40 -0
- package/dashboard/shared/cc-limits.js +79 -0
- package/dashboard/shared/pr-filters.js +21 -38
- package/dashboard/shared/project-git-summary.js +1 -1
- package/dashboard/shared/record-filters.js +169 -0
- package/dashboard/shared/watches-source.js +1 -1
- package/dashboard/shared/welcome-popup.js +1 -1
- package/dashboard/shared/wi-filters.js +302 -0
- package/dashboard/slim/body.html +1 -0
- package/dashboard/slim/js/command-send.js +26 -0
- package/dashboard/slim/js/modals-tiles.js +380 -39
- package/dashboard/slim/js/status.js +13 -21
- package/dashboard/slim/layout.html +1 -0
- package/dashboard/slim/panel-bootstrap.js +6 -2
- package/dashboard/slim/styles.css +38 -0
- package/dashboard/styles.css +159 -55
- package/dashboard-build.js +52 -6
- package/dashboard.js +956 -423
- package/docs/README.md +11 -6
- package/docs/api-errors.md +2 -2
- package/docs/architecture-review-2026-07-09.md +1 -1
- package/docs/architecture.excalidraw +2 -2
- package/docs/auto-discovery.md +18 -9
- package/docs/branch-derivation.md +4 -4
- package/docs/capture-demos.js +39 -2
- package/docs/ci-runner-canary.md +123 -0
- package/docs/claude-md-propagation.md +2 -2
- package/docs/cloud-agent-dispatch.md +204 -0
- package/docs/command-center.md +7 -7
- package/docs/completion-reports.md +43 -20
- package/docs/constants.md +10 -3
- package/docs/constellation-bridge.md +134 -6
- package/docs/constellation-style-telemetry.md +4 -4
- package/docs/contracts/capability-protocol.v1.json +165 -0
- package/docs/cooldown-merge-semantics.md +12 -12
- package/docs/copilot-cli-schema.md +7 -7
- package/docs/cross-repo-plans.md +10 -10
- package/docs/dead-code-audit-retractions.md +5 -5
- package/docs/default-branch-ci.md +173 -0
- package/docs/deprecated.json +31 -31
- package/docs/design-inbox-entries-schema.md +3 -3
- package/docs/design-language.md +1051 -0
- package/docs/design-state-storage.md +11 -11
- package/docs/diagnostics-crash-reports.md +9 -9
- package/docs/diagnostics-memory.md +5 -5
- package/docs/documentation-audit-2026-07-09.md +7 -7
- package/docs/engine-restart.md +90 -5
- package/docs/harness-mode.md +1 -1
- package/docs/internal-install.md +338 -39
- package/docs/kb-dedup-duplicate-pair-investigation.md +5 -5
- package/docs/kb-pr3223-cascade-archiving.md +1 -1
- package/docs/kb-pr696-merge-conflict-docs.md +6 -6
- package/docs/kb-sweep.md +35 -35
- package/docs/keep-processes.md +1 -1
- package/docs/live-checkout-mode.md +30 -30
- package/docs/managed-spawn.md +18 -14
- package/docs/named-agents.md +7 -7
- package/docs/plan-lifecycle.md +69 -2
- package/docs/pr-author-identity.md +114 -0
- package/docs/pr-auto-fix-dispatch.md +19 -4
- package/docs/pr-comment-followup.md +6 -6
- package/docs/pr-review-fix-loop.md +59 -10
- package/docs/process-termination.md +40 -0
- package/docs/proposals/repo-pool-for-live-checkout.md +13 -13
- package/docs/qa-runbook-lifecycle.md +367 -17
- package/docs/qa-runbooks.md +3 -3
- package/docs/rfc-completion-json.md +18 -18
- package/docs/runtime-adapters.md +26 -21
- package/docs/security.md +6 -6
- package/docs/self-improvement.md +4 -4
- package/docs/shared-lifecycle-module-map.md +473 -472
- package/docs/skills.md +52 -3
- package/docs/slim-ux/concepts.md +121 -116
- package/docs/specs/agent-configurability.md +18 -18
- package/docs/specs/agent-rename.md +18 -18
- package/docs/team-memory.md +38 -21
- package/docs/timeouts-and-liveness.md +118 -10
- package/docs/tutorials/01-install-and-connect.md +1 -1
- package/docs/watches.md +40 -39
- package/docs/workspace-manifests.md +4 -4
- package/docs/worktree-lifecycle.md +293 -14
- package/engine/README.md +46 -0
- package/engine/{ado-comment.js → ado/comment.js} +8 -8
- package/engine/{ado-git-auth.js → ado/git-auth.js} +4 -4
- package/engine/{ado.js → ado/index.js} +417 -63
- package/engine/{ado-status.js → ado/status.js} +6 -8
- package/engine/{ado-token.js → ado/token.js} +1 -1
- package/engine/{acp-transport.js → agents/acp-transport.js} +62 -22
- package/engine/{agent-worker-pool.js → agents/agent-worker-pool.js} +17 -8
- package/engine/{cc-worker-pool.js → agents/cc-worker-pool.js} +16 -6
- package/engine/{claude-md-context.js → agents/claude-md-context.js} +5 -5
- package/engine/{harness-context.js → agents/harness-context.js} +5 -5
- package/engine/{harness.js → agents/harness.js} +3 -3
- package/engine/{llm.js → agents/llm.js} +18 -14
- package/engine/{model-discovery.js → agents/model-discovery.js} +2 -2
- package/engine/{playbook.js → agents/playbook.js} +155 -22
- package/engine/{pooled-agent-process.js → agents/pooled-agent-process.js} +14 -12
- package/engine/{preflight.js → agents/preflight.js} +29 -10
- package/engine/{spawn-agent.js → agents/spawn-agent.js} +25 -14
- package/engine/{spawn-phase-watchdog.js → agents/spawn-phase-watchdog.js} +16 -7
- package/engine/{steering.js → agents/steering.js} +5 -5
- package/engine/{tools-inventory.js → agents/tools-inventory.js} +2 -2
- package/engine/{agent-api-validation.js → api/agent-api-validation.js} +2 -2
- package/engine/{api-validation.js → api/api-validation.js} +1 -1
- package/engine/api/bridge.js +787 -0
- package/engine/{cc-api-validation.js → api/cc-api-validation.js} +1 -1
- package/engine/api/companion.js +560 -0
- package/engine/{content-api-validation.js → api/content-api-validation.js} +2 -2
- package/engine/{pr-issue-validation.js → api/pr-issue-validation.js} +33 -6
- package/engine/{settings-validation.js → api/settings-validation.js} +32 -4
- package/engine/api-contracts/agent-content.js +4 -4
- package/engine/api-contracts/capability-manifest.js +236 -0
- package/engine/api-contracts/capability-protocol.js +333 -0
- package/engine/api-contracts/cc-ops.js +1 -1
- package/engine/api-contracts/config-runtime.js +5 -0
- package/engine/api-contracts/core.js +28 -1
- package/engine/api-contracts/index.js +100 -0
- package/engine/api-contracts/orchestration.js +18 -5
- package/engine/api-contracts/pull-requests.js +37 -6
- package/engine/api-contracts/qa-process.js +29 -6
- package/engine/api-contracts/work-plan-prd.js +21 -1
- package/engine/cloud/contract.js +212 -0
- package/engine/cloud/index.js +159 -0
- package/engine/{execution-model.js → core/execution-model.js} +1 -1
- package/engine/{features.js → core/features.js} +4 -4
- package/engine/{operator-identity.js → core/operator-identity.js} +1 -1
- package/engine/{queries.js → core/queries.js} +201 -36
- package/engine/{safe-expr.js → core/safe-expr.js} +1 -1
- package/engine/{shared.js → core/shared.js} +1637 -175
- package/engine/{stdio-timestamps.js → core/stdio-timestamps.js} +1 -1
- package/engine/{untrusted-fence.js → core/untrusted-fence.js} +3 -3
- package/engine/db/index.js +11 -2
- package/engine/db/migrations/002-dispatches.js +3 -3
- package/engine/db/migrations/003-work-items.js +1 -1
- package/engine/db/migrations/004-pull-requests.js +1 -1
- package/engine/db/migrations/006-metrics.js +1 -1
- package/engine/db/migrations/007-watches.js +2 -2
- package/engine/db/migrations/008-small-state.js +1 -1
- package/engine/db/migrations/009-qa.js +1 -1
- package/engine/db/migrations/010-pr-links.js +1 -1
- package/engine/db/migrations/011-remaining-state.js +1 -1
- package/engine/db/migrations/012-steering-deliveries.js +2 -2
- package/engine/db/migrations/013-backfill-broken-note-links.js +1 -1
- package/engine/db/migrations/014-pr-fix-target-prefs.js +2 -2
- package/engine/db/migrations/015-plans-prds.js +0 -0
- package/engine/db/migrations/018-sql-only-cutover.js +2 -2
- package/engine/db/migrations/021-archived-work-items.js +1 -1
- package/engine/db/migrations/022-global-cc-session.js +1 -1
- package/engine/db/migrations/023-engine-state.js +1 -1
- package/engine/db/migrations/025-malformed-work-item-phantoms.js +1 -1
- package/engine/db/migrations/027-review-learning-lifecycle.js +1 -1
- package/engine/db/migrations/029-repair-reused-versions.js +20 -0
- package/engine/db/migrations/031-pr-author-identity.js +137 -0
- package/engine/{consolidation.js → memory/consolidation.js} +6 -6
- package/engine/{kb-sweep-runner.js → memory/kb-sweep-runner.js} +2 -2
- package/engine/{kb-sweep.js → memory/kb-sweep.js} +9 -7
- package/engine/{memory-retrieval.js → memory/memory-retrieval.js} +46 -4
- package/engine/{memory-store.js → memory/memory-store.js} +3 -3
- package/engine/{promotion.js → memory/promotion.js} +3 -3
- package/engine/{review-learning-backfill.js → memory/review-learning-backfill.js} +6 -6
- package/engine/{review-learning.js → memory/review-learning.js} +10 -5
- package/engine/{diagnostics-memory.js → observability/diagnostics-memory.js} +1 -1
- package/engine/{logs-store.js → observability/logs-store.js} +5 -5
- package/engine/{metrics-store.js → observability/metrics-store.js} +4 -4
- package/engine/{check-status.js → operations/check-status.js} +3 -3
- package/engine/{cli.js → operations/cli.js} +271 -113
- package/engine/{distribution.js → operations/distribution.js} +5 -6
- package/engine/{cleanup.js → orchestration/cleanup.js} +72 -45
- package/engine/{cooldown.js → orchestration/cooldown.js} +5 -5
- package/engine/{dispatch-events.js → orchestration/dispatch-events.js} +2 -2
- package/engine/{dispatch.js → orchestration/dispatch.js} +129 -36
- package/engine/orchestration/failed-scheduled-cleanup.js +274 -0
- package/engine/{lifecycle.js → orchestration/lifecycle.js} +198 -90
- package/engine/{meeting.js → orchestration/meeting.js} +6 -16
- package/engine/{pipeline.js → orchestration/pipeline.js} +12 -12
- package/engine/{pre-dispatch-eval.js → orchestration/pre-dispatch-eval.js} +10 -9
- package/engine/{routing.js → orchestration/routing.js} +3 -3
- package/engine/{schedule-bootstrap.js → orchestration/schedule-bootstrap.js} +4 -4
- package/engine/{scheduler.js → orchestration/scheduler.js} +38 -8
- package/engine/{timeout.js → orchestration/timeout.js} +158 -109
- package/engine/{db-events.js → persistence/db-events.js} +2 -2
- package/engine/{dispatch-store.js → persistence/dispatch-store.js} +7 -7
- package/engine/{inbox-store.js → persistence/inbox-store.js} +2 -2
- package/engine/{note-link-backfill.js → persistence/note-link-backfill.js} +4 -4
- package/engine/{pr-fix-target-store.js → persistence/pr-fix-target-store.js} +8 -8
- package/engine/{pull-requests-store.js → persistence/pull-requests-store.js} +21 -7
- package/engine/{small-state-store.js → persistence/small-state-store.js} +31 -31
- package/engine/persistence/state-operations.js +350 -0
- package/engine/{steering-store.js → persistence/steering-store.js} +6 -6
- package/engine/{issues.js → planning/issues.js} +2 -2
- package/engine/{plan-prd-validation.js → planning/plan-prd-validation.js} +8 -2
- package/engine/planning/prd-result-sidecar.js +190 -0
- package/engine/{prd-store.js → planning/prd-store.js} +17 -17
- package/engine/{project-discovery.js → planning/project-discovery.js} +5 -5
- package/engine/{projects.js → planning/projects.js} +10 -10
- package/engine/{resolve-area.js → planning/resolve-area.js} +1 -1
- package/engine/{work-item-validation.js → planning/work-item-validation.js} +39 -3
- package/engine/{work-items-store.js → planning/work-items-store.js} +29 -21
- package/engine/{keep-process-sweep.js → processes/keep-process-sweep.js} +57 -17
- package/engine/{managed-spawn-launcher.js → processes/managed-spawn-launcher.js} +3 -3
- package/engine/{managed-spawn.js → processes/managed-spawn.js} +97 -46
- package/engine/{process-utils.js → processes/process-utils.js} +599 -55
- package/engine/{abandoned-pr-reconciliation.js → providers/abandoned-pr-reconciliation.js} +17 -7
- package/engine/{comment-classifier.js → providers/comment-classifier.js} +85 -17
- package/engine/{comment-format.js → providers/comment-format.js} +5 -5
- package/engine/{gh-comment.js → providers/gh-comment.js} +15 -15
- package/engine/{gh-token.js → providers/gh-token.js} +4 -4
- package/engine/{github.js → providers/github.js} +131 -54
- package/engine/{pr-action.js → providers/pr-action.js} +13 -12
- package/engine/{pr-clone-keep.js → providers/pr-clone-keep.js} +7 -7
- package/engine/{pr-devbox.js → providers/pr-devbox.js} +6 -6
- package/engine/{pr-fix-target.js → providers/pr-fix-target.js} +13 -13
- package/engine/{pr-remote-patch.js → providers/pr-remote-patch.js} +4 -4
- package/engine/{pr-resolve.js → providers/pr-resolve.js} +7 -7
- package/engine/{pr-temp-clone.js → providers/pr-temp-clone.js} +5 -5
- package/engine/{pr-track.js → providers/pr-track.js} +11 -13
- package/engine/{shared-branch-pr-reconcile.js → providers/shared-branch-pr-reconcile.js} +4 -4
- package/engine/qa/auto-prd-qa.js +313 -0
- package/engine/{qa-from-prd.js → qa/from-prd.js} +42 -12
- package/engine/qa/prd-session.js +240 -0
- package/engine/{qa-process-validation.js → qa/process-validation.js} +14 -9
- package/engine/{qa-runbooks.js → qa/runbooks.js} +1 -1
- package/engine/{qa-runs.js → qa/runs.js} +286 -15
- package/engine/{qa-sessions.js → qa/sessions.js} +595 -49
- package/engine/qa/visual-journey.js +654 -0
- package/engine/{qa-runners.js → qa-runners/index.js} +7 -7
- package/engine/qa-runners/maestro.js +3 -3
- package/engine/qa-runners/playwright.js +2 -2
- package/engine/{restart-health.js → recovery/restart-health.js} +48 -4
- package/engine/recovery/stop-stack.js +607 -0
- package/engine/{supervisor.js → recovery/supervisor.js} +105 -175
- package/engine/{watchdog.js → recovery/watchdog.js} +136 -13
- package/engine/runtimes/claude.js +14 -12
- package/engine/runtimes/codex.js +8 -6
- package/engine/runtimes/copilot.js +17 -16
- package/engine/{watch-actions.js → watches/actions.js} +13 -13
- package/engine/{watches.js → watches/index.js} +43 -32
- package/engine/{watches-store.js → watches/store.js} +4 -4
- package/engine/{create-pr-worktree.js → worktrees/create-pr.js} +1 -1
- package/engine/{worktree-gc.js → worktrees/gc.js} +70 -22
- package/engine/worktrees/inventory.js +671 -0
- package/engine/{live-checkout.js → worktrees/live-checkout.js} +4 -4
- package/engine/{worktree-pool.js → worktrees/pool.js} +2 -2
- package/engine/{worktree-preflight.js → worktrees/preflight.js} +1 -0
- package/engine/worktrees/quarantine-refs.js +173 -0
- package/engine.js +1137 -208
- package/minions.js +147 -77
- package/package.json +10 -6
- package/playbooks/_pr-description-audit.md +110 -78
- package/playbooks/build-fix-complex.md +2 -0
- package/playbooks/fix.md +16 -12
- package/playbooks/implement-shared.md +2 -0
- package/playbooks/implement.md +19 -20
- package/playbooks/plan-to-prd.md +18 -3
- package/playbooks/qa-session-draft.md +136 -1
- package/playbooks/qa-session-execute.md +80 -2
- package/playbooks/qa-session-setup.md +17 -1
- package/playbooks/qa-validate.md +1 -1
- package/playbooks/setup.md +2 -0
- package/playbooks/shared-rules.md +25 -32
- package/playbooks/templates/followup-dispatch.md +4 -3
- package/playbooks/verify.md +1 -1
- package/prompts/cc-system.md +19 -27
- package/watch-plugins/README.md +92 -0
- package/watch-plugins/ado-author-prs.js +336 -0
- package/watch-plugins/gh-author-prs.js +375 -0
- package/watch-plugins/http.js +474 -0
- package/watch-plugins/teams-channel.js +869 -0
- package/docs/dev-composite-workflow.md +0 -101
- package/docs/pr-screenshots/pr-886/after-single-header.png +0 -0
- package/docs/pr-screenshots/pr-886/before-duplicate-header.png +0 -0
- package/docs/pr-screenshots/pr-895/01-cancellation-reason-detail.png +0 -0
- package/docs/pr-screenshots/pr-899/worker-pool-worktrees-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-899/worker-pool-worktrees-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-901/projects-tab-default.png +0 -0
- package/docs/pr-screenshots/pr-901/projects-tab-fmf-selected.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-AFTER-crop.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-BEFORE-crop.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-916/model-picker-dropdown-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-979/auto-fix-pane-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-979/auto-fix-pane-BEFORE.png +0 -0
- package/docs/pr-screenshots/pr-985/pr-column-em-dash-AFTER.png +0 -0
- package/docs/pr-screenshots/pr-985/pr-column-em-dash-BEFORE.png +0 -0
- package/docs/visual-evidence-ci.md +0 -103
- package/engine/bridge.js +0 -379
- package/engine/quarantine-refs.js +0 -103
- package/engine/state-operations.js +0 -178
- /package/engine/{steering-constraints.js → agents/steering-constraints.js} +0 -0
package/docs/README.md
CHANGED
|
@@ -31,7 +31,9 @@ Architecture, design proposals, and lifecycle references for people working on t
|
|
|
31
31
|
|
|
32
32
|
- [api-errors.md](api-errors.md) — Dashboard API error contract: the stable `{error, code, field, …}` envelope, the 400/404/409/422/5xx status taxonomy, the safe (bounded + secret-redacted) rejected-value policy, alias/enum compatibility rules, and the self-correct-4xx / don't-blindly-retry-5xx behavior. Contracts are discoverable via `GET /api/routes` and the `engine/api-contracts` route-to-validation matrix.
|
|
33
33
|
- [branch-derivation.md](branch-derivation.md) — Engine-side branch fallback (`work/<wi-id>`) vs. agent-authored long form, the structured-vs-loose PR-pointer extractors, and the canonical PR-fix duplication incident.
|
|
34
|
+
- [ci-runner-canary.md](ci-runner-canary.md) — The hourly hosted-runner canary: why a self-hosted outage produces stalled runs instead of failed ones (so failure-only health checks report "all green" while CI is dark), the properties that keep the canary out of that failure domain, and why the runner-inventory check is unavailable to `GITHUB_TOKEN`.
|
|
34
35
|
- [claude-md-propagation.md](claude-md-propagation.md) — Propagating repo-authored `CLAUDE.md` instructions to runtimes that don't auto-load it (Copilot/Codex): the `claudeMdNativeDiscovery` capability flag, the bounded nearest-applicable walk-up discovery, the `propagateClaudeMdForNonClaudeRuntimes` config knob, and why it's orthogonal to each runtime's native `AGENTS.md` discovery.
|
|
36
|
+
- [cloud-agent-dispatch.md](cloud-agent-dispatch.md) — The `cloud` execution surface: handing a work item to a REMOTE coding agent (Agency / Copilot cloud) that authors its own PR. Covers why a cloud provider is not a runtime adapter, the `engine/cloud` provider contract, the PR-producing eligibility allowlist (and why `review`/`verify` are refused), and the fail-closed gating that refuses a cloud dispatch rather than silently running it locally.
|
|
35
37
|
- [command-center.md](command-center.md) — Command Center (CC) chat panel: configured-runtime sessions, resume semantics, system-prompt invalidation, and per-tab session storage.
|
|
36
38
|
- [specs/agent-rename.md](specs/agent-rename.md) — Design spec for **agent rename & name decoupling** — the prerequisite for the Role/Agent Library. Formalizes the stable opaque agent id, makes charters name-agnostic, and adds `POST /api/agents/rename` (display name + emoji). Feature-flagged (`agent-rename`) and fully backward-compatible.
|
|
37
39
|
- [specs/agent-configurability.md](specs/agent-configurability.md) — Design spec for the user-configurable Role / Agent Library, feature-flagged behind `agent-library` and fully backward-compatible. Builds on `agent-rename.md`. Role = the reusable durable charter; agent = a thin instance (identity + variable expertise + role pointer). Phase 0 renames `skills`→`expertise`; Phase 1 exposes/edits role charters + per-agent expertise; Phase 2 adds role/agent CRUD with builtin delete-protection.
|
|
@@ -43,38 +45,41 @@ Architecture, design proposals, and lifecycle references for people working on t
|
|
|
43
45
|
- [copilot-cli-schema.md](copilot-cli-schema.md) — Behavior and schema reference for the GitHub Copilot CLI adapter (capability flags, stdin vs `-p`, model discovery, effort levels).
|
|
44
46
|
- [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.
|
|
45
47
|
- [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.
|
|
48
|
+
- [default-branch-ci.md](default-branch-ci.md) — The post-merge default-branch gate: why a `pull_request` gate cannot catch merge-order defects (two green PRs that break only in combination), why the post-merge workflow *calls* the PR gate rather than copying it or inverting the direction (the ruleset requires the `Unit Tests` context by exact string), the cost controls, and the evaluated-but-rejected merge-queue alternative.
|
|
46
49
|
- [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.
|
|
47
50
|
- [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.
|
|
51
|
+
- [design-language.md](design-language.md) — Code-derived Minions design-language specification: color tokens, typography, spacing, component primitives (buttons/badges/tables/modals/Command Center), status→class→color maps, Classic vs Slim shared-vs-different foundations, a migration playbook, and an objective audit rubric — all traceable to `dashboard/` CSS/JS with file+line citations.
|
|
48
52
|
- [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).
|
|
49
|
-
- [dev-composite-workflow.md](dev-composite-workflow.md) — The recurring "rebuild the composite branch from all my open PRs and relaunch the dev dashboard" workflow, and the `rebuild-composite` skill + `scripts/rebuild-composite.ps1` that automate it.
|
|
50
53
|
- [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.
|
|
51
54
|
- [harness-propagation.md](harness-propagation.md) — The native runtime
|
|
52
55
|
contract for repository instructions, skills, commands, and MCPs.
|
|
53
56
|
- [kb-dedup-duplicate-pair-investigation.md](kb-dedup-duplicate-pair-investigation.md) — Investigation-only pass diffing suspected duplicate KB filename groups (content-hash dedup for agent-authored reviews/build-reports) to confirm true full-body duplication before any fix is proposed.
|
|
54
57
|
- [kb-pr3223-cascade-archiving.md](kb-pr3223-cascade-archiving.md) — Findings from PR #3223: cascade-archiving PRDs when their linked markdown plan is archived, including the per-concern try/catch pattern and `source_plan` basename-matching invariant in `handlePlansArchive` (`dashboard.js`).
|
|
55
|
-
- [kb-pr696-merge-conflict-docs.md](kb-pr696-merge-conflict-docs.md) — Findings from PR #696: resolving a merge conflict in `docs/kb-sweep.md` with stale line-number citations to `engine/kb-sweep.js`.
|
|
56
|
-
- [keep-processes.md](keep-processes.md) — `meta.keep_processes` sidecar contract: when to use it vs managed-spawn, sidecar schema, caps, and the [`engine/keep-process-sweep.js`](../engine/keep-process-sweep.js) lifecycle.
|
|
58
|
+
- [kb-pr696-merge-conflict-docs.md](kb-pr696-merge-conflict-docs.md) — Findings from PR #696: resolving a merge conflict in `docs/kb-sweep.md` with stale line-number citations to `engine/memory/kb-sweep.js`.
|
|
59
|
+
- [keep-processes.md](keep-processes.md) — `meta.keep_processes` sidecar contract: when to use it vs managed-spawn, sidecar schema, caps, and the [`engine/processes/keep-process-sweep.js`](../engine/processes/keep-process-sweep.js) lifecycle.
|
|
57
60
|
- [live-checkout-mode.md](live-checkout-mode.md) — Per-project opt-in `checkoutMode: 'live'`: skips `git worktree add` and dispatches in-place inside `project.localPath` for `repo`-managed trees, submodule-heavy repos, deep Windows paths, and native build state. Includes the refuse-on-dirty contract and the per-project mutating-concurrency cap of 1.
|
|
58
61
|
- [managed-spawn.md](managed-spawn.md) — Engine-owned long-running services (managed-spawn primitive): sidecar schema, healthcheck examples, lifecycle, dashboard API, and the WI 1 (build) → WI 2 (test) chained-validation pattern.
|
|
59
62
|
- [named-agents.md](named-agents.md) — The named-agent roster (Ripley / Dallas / Lambert / Rebecca / Ralph): per-agent `config.json` shape, the per-agent → `engine.*` → runtime resolution chain, how `routing.md` (not the `role`/`skills` metadata) drives dispatch, descriptive vs runtime skills, and per-agent memory files.
|
|
60
63
|
- [plan-lifecycle.md](plan-lifecycle.md) — Full plan pipeline from `/plan` through PRD materialization, dispatch with dependency gating, verify task, and human archive.
|
|
61
64
|
- [pr-auto-fix-dispatch.md](pr-auto-fix-dispatch.md) — Short reference table mapping each PR auto-fix / review dispatch site in `engine.js#discoverFromPrs` to its gate flag, plus the `pollingPaused` / `autoFixPaused` master kill-switches and the per-provider polling gates.
|
|
65
|
+
- [pr-author-identity.md](pr-author-identity.md) — Separating a PR's real author identity (`pr.author`, provider-linked) from the Minions agent that owns the automated work (`pr.agent`): the structured author shape, the provider builders, centralized merge, migration 031, and the dashboard Author column.
|
|
62
66
|
- [pr-comment-followup.md](pr-comment-followup.md) — PR-comment follow-up dispatch contract: fix/review agents may spin off a new WI via `POST /api/work-items` with `meta.pr_followup` instead of broadening the current PR or rebutting the comment.
|
|
63
67
|
- [pr-review-fix-loop.md](pr-review-fix-loop.md) — How the engine moves a PR from creation through review, fix dispatch, and re-review, including stale-status guards.
|
|
68
|
+
- [process-termination.md](process-termination.md) — The `terminateProcess` gateway: `PROCESS_TERMINATION_SITES` is the authoritative site inventory (mode + ownership proof per entry), how to print it, what the gateway test enforces, and the signal-0 liveness exemption.
|
|
64
69
|
- [proposals/repo-pool-for-live-checkout.md](proposals/repo-pool-for-live-checkout.md) — Review-only artifact reproducing the approved plan + PRD for a repo pool covering live-checkout projects (multi-enlistment dispatch), so the design has a git-tracked surface for human comment before the dependent implementation work items land as code PRs.
|
|
65
70
|
- [qa-runbook-lifecycle.md](qa-runbook-lifecycle.md) — End-to-end QA runbook lifecycle (W-mpeiwz6k0005bf34): runbook + run-record storage, `POST /api/qa/runbooks/run` dispatch into the `qa-validate` playbook, artifact contract, and how the `/qa` page mirrors managed-spawn observability.
|
|
66
71
|
- [qa-runbooks.md](qa-runbooks.md) — Per-project QA runbook schema, storage layout (`projects/<name>/runbooks/<id>.json`), CRUD endpoints, run-record lifecycle, and the `qa-validate` agent sidecar contract.
|
|
67
72
|
- [rfc-completion-json.md](rfc-completion-json.md) — RFC for replacing stdout regex-scraping with a structured `completion.json` control-plane protocol.
|
|
68
73
|
- [runtime-adapters.md](runtime-adapters.md) — Runtime adapter contract (`engine/runtimes/*`): how the engine talks to Claude Code, Copilot CLI, and future CLIs through a single capability-flagged interface.
|
|
69
74
|
- [self-improvement.md](self-improvement.md) — The six self-improvement mechanisms (learnings inbox, per-agent history, review feedback, quality metrics, etc.) that form Minions' continuous feedback loop, including structured review learning (durable, always-on lessons from verified review findings).
|
|
70
|
-
- [shared-lifecycle-module-map.md](shared-lifecycle-module-map.md) — Documentation-only module-boundary audit of `engine/shared.js` / `engine/lifecycle.js`: function inventory, cross-file call graph, and a proposed split map (no code moved).
|
|
75
|
+
- [shared-lifecycle-module-map.md](shared-lifecycle-module-map.md) — Documentation-only module-boundary audit of `engine/core/shared.js` / `engine/orchestration/lifecycle.js`: function inventory, cross-file call graph, and a proposed split map (no code moved).
|
|
71
76
|
- [skills.md](skills.md) — Skill block format: how agents emit reusable `\`\`\`skill` blocks and how the engine extracts them into native personal-skill directories.
|
|
72
77
|
- [slim-ux/concepts.md](slim-ux/concepts.md) — Slim-UX design notes: simplified surface concepts driving the project picker, inline project link, and decoupled folder picker.
|
|
73
78
|
- [slim-ux/architecture-suggestions.md](slim-ux/architecture-suggestions.md) — Slim-UX follow-up architecture suggestions paired with `concepts.md`.
|
|
74
79
|
- [team-memory.md](team-memory.md) — End-to-end hybrid memory system: file-backed inputs and consolidation, SQL/FTS5 records, retrieval and fallback, prompt bounds, episodic capture, the review-learning lifecycle (capture/recall/promotion/contradiction/diagnostics) and its rollout history + acceptance measurement, security, APIs, and operations.
|
|
75
80
|
- [timeouts-and-liveness.md](timeouts-and-liveness.md) — What kills (or doesn't kill) a live tracked agent: the wall-clock vs steering kill invariants, spawn-phase watchdog gates, steering safety nets, and stale-orphan detection ladder.
|
|
76
81
|
- [visual-evidence-ci.md](visual-evidence-ci.md) — GitHub Actions before/after dashboard capture: path and label triggers, deterministic base/head fixtures, artifact/comment lifecycle, trust boundary, and local reproduction.
|
|
77
|
-
- [watches.md](watches.md) — Persistent monitoring jobs: target-type registry, conditions, follow-up actions, and the `
|
|
82
|
+
- [watches.md](watches.md) — Persistent monitoring jobs: target-type registry, conditions, follow-up actions, and the `watch-plugins/` extension folder.
|
|
78
83
|
- [workspace-manifests.md](workspace-manifests.md) — Declarative per-agent permission scoping: `allowed_tools` / `allowed_repos` / `allowed_external_urls` / `memory_scope`, dispatch-time repo gate, and runtime `--allowedTools` narrowing.
|
|
79
84
|
- [worktree-lifecycle.md](worktree-lifecycle.md) — Worktree pool recycling, the live-dispatch guard that prevents wiping an agent's unpushed work, the dirty/divergent quarantine path, and the Windows EPERM/EBUSY file-lock retry footgun.
|
|
80
85
|
|
|
@@ -87,7 +92,7 @@ Operational runbooks for engine operators and fleet maintainers.
|
|
|
87
92
|
- [diagnostics-crash-reports.md](diagnostics-crash-reports.md) — Proactive Node crash-diagnostics reports (`--report-on-fatalerror --report-on-signal --diagnostic-dir=...`) for the engine.js process on Windows: where reports land, config/opt-out, and retention.
|
|
88
93
|
- [engine-restart.md](engine-restart.md) — How agents survive an engine restart: state persistence, the 20-minute startup grace period, and orphan reattachment via PID files and `live-output.log`.
|
|
89
94
|
- [human-vs-automated.md](human-vs-automated.md) — Quick reference table of which features humans start, run, decide, and recover, and the two human approval gates.
|
|
90
|
-
- [kb-sweep.md](kb-sweep.md) — Knowledge-base sweep runbook: how `engine/kb-sweep.js` consolidates `notes/inbox/` into `knowledge/` and survives `minions restart`.
|
|
95
|
+
- [kb-sweep.md](kb-sweep.md) — Knowledge-base sweep runbook: how `engine/memory/kb-sweep.js` consolidates `notes/inbox/` into `knowledge/` and survives `minions restart`.
|
|
91
96
|
- [preflight.md](preflight.md) — `minions doctor` and the internal initialization/startup preflight: what each non-self-explanatory row (permission bypass, runtime detection, drive-root, etc.) is asserting.
|
|
92
97
|
- [security.md](security.md) — Threat model: single-user/loopback deployment assumptions, dashboard Origin gate, data-flow trust boundaries, secret handling, and known residual risks (CSRF sweep, prompt injection, log-redactor audit).
|
|
93
98
|
|
package/docs/api-errors.md
CHANGED
|
@@ -38,7 +38,7 @@ immediately in the plan verification guide.
|
|
|
38
38
|
## Stable error envelope
|
|
39
39
|
|
|
40
40
|
Every rejected request returns a JSON body with a stable shape (built by
|
|
41
|
-
`engine/api-validation.js#toApiErrorResponse` / `exposedEnvelope`):
|
|
41
|
+
`engine/api/api-validation.js#toApiErrorResponse` / `exposedEnvelope`):
|
|
42
42
|
|
|
43
43
|
```json
|
|
44
44
|
{
|
|
@@ -83,7 +83,7 @@ reach the client.
|
|
|
83
83
|
## Safe rejected-value policy
|
|
84
84
|
|
|
85
85
|
Echoing back the value that was rejected is convenient for debugging but is a
|
|
86
|
-
data-exfiltration and log-poisoning risk. `engine/api-validation.js` enforces a
|
|
86
|
+
data-exfiltration and log-poisoning risk. `engine/api/api-validation.js` enforces a
|
|
87
87
|
uniform **safe rejected-value policy**:
|
|
88
88
|
|
|
89
89
|
- **Strings** are bounded (default cap) before being echoed.
|
|
@@ -81,7 +81,7 @@ These require separate focused changes rather than expanding this PR:
|
|
|
81
81
|
frequently while the runtime is alive.
|
|
82
82
|
6. **Supervisor stale PID reuse (medium).** Startup trusts any live PID in
|
|
83
83
|
`supervisor.pid`. Validate the command line against this checkout's
|
|
84
|
-
`engine/supervisor.js` before suppressing startup.
|
|
84
|
+
`engine/recovery/supervisor.js` before suppressing startup.
|
|
85
85
|
|
|
86
86
|
## Healthy areas
|
|
87
87
|
|
|
@@ -1268,11 +1268,11 @@
|
|
|
1268
1268
|
"versionNonce": 1339287385,
|
|
1269
1269
|
"fontSize": 13,
|
|
1270
1270
|
"fontFamily": 3,
|
|
1271
|
-
"text": "PR integrations\n\nengine/github.js \u00b7 engine/ado.js\
|
|
1271
|
+
"text": "PR integrations\n\nengine/providers/github.js \u00b7 engine/ado/index.js\nproviders/gh-token.js \u00b7 ado/token.js\n\n\u2022 status + comment polling\n\u2022 reconciliation\n\u2022 verdict-flip reset",
|
|
1272
1272
|
"textAlign": "center",
|
|
1273
1273
|
"verticalAlign": "middle",
|
|
1274
1274
|
"containerId": "P5ocuAQmXTFm8tYonVs7",
|
|
1275
|
-
"originalText": "PR integrations\n\nengine/github.js \u00b7 engine/ado.js\
|
|
1275
|
+
"originalText": "PR integrations\n\nengine/providers/github.js \u00b7 engine/ado/index.js\nproviders/gh-token.js \u00b7 ado/token.js\n\n\u2022 status + comment polling\n\u2022 reconciliation\n\u2022 verdict-flip reset",
|
|
1276
1276
|
"lineHeight": 1.25,
|
|
1277
1277
|
"autoResize": false
|
|
1278
1278
|
},
|
package/docs/auto-discovery.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Auto-Discovery & Execution Pipeline
|
|
2
2
|
|
|
3
|
-
> Last verified: 2026-07-21 against `engine.js` `tickInner()`, `engine/shared.js`, and `routing.md`.
|
|
3
|
+
> Last verified: 2026-07-21 against `engine.js` `tickInner()`, `engine/core/shared.js`, and `routing.md`.
|
|
4
4
|
|
|
5
5
|
How the minions engine finds work and dispatches agents automatically.
|
|
6
6
|
|
|
@@ -72,11 +72,11 @@ Skips PRs where `status !== "active"`.
|
|
|
72
72
|
|
|
73
73
|
Inside `discoverFromPrs()`, ADO and GitHub projects first resolve their own provider poll gate (`adoPollEnabled` or `ghPollEnabled`). PR-derived automation is inert when that provider's polling is off, so cached build, vote, conflict, and comment state cannot trigger new dispatches. The shared dispatch toggles (`autoReviewPrs`, `autoReReviewPrs`, `autoFixReviewFeedback`, `autoFixHumanComments`, `autoFixBuilds`, and `autoFixConflicts`) apply to both providers. `evalLoop` gates the minion review loop: initial minion reviews, minion re-reviews, and minion review-feedback fixes. Human-feedback fixes are evaluated outside `evalLoop`. Conflict fixes are additionally gated by `!fixDispatched`, so an earlier successful human/review/build fix dispatch in the same PR discovery pass suppresses the conflict fix until a later pass.
|
|
74
74
|
|
|
75
|
-
**`autoReReviewPrs` gates both re-review paths (`P-e8b1c4d2`).** Re-reviews fire from two places: (1) the open-loop **discovery** path in `engine.js:discoverFromPrs` (PR shows `reviewStatus=waiting` after a fix push), and (2) the **closure-loop** in `engine/lifecycle.js:dispatchReReviewForFix` (a fix WI completes whose meta carries `addresses_review_wi`, queuing the next review against the same PR). The `engine.autoReReviewPrs` toggle is read at BOTH sites so flipping it OFF mutes the entire re-review cycle — not just the discovery sweep. Default ON; flip via Dashboard → Settings →
|
|
75
|
+
**`autoReReviewPrs` gates both re-review paths (`P-e8b1c4d2`).** Re-reviews fire from two places: (1) the open-loop **discovery** path in `engine.js:discoverFromPrs` (PR shows `reviewStatus=waiting` after a fix push), and (2) the **closure-loop** in `engine/orchestration/lifecycle.js:dispatchReReviewForFix` (a fix WI completes whose meta carries `addresses_review_wi`, queuing the next review against the same PR). The `engine.autoReReviewPrs` toggle is read at BOTH sites so flipping it OFF mutes the entire re-review cycle — not just the discovery sweep. Default ON; flip via Dashboard → Settings → Plan & PR Workflow → Monitor, or `engine.autoReReviewPrs: false` in `config.json`.
|
|
76
76
|
|
|
77
77
|
**Hard-stop kill-switch (`pollingPaused`).** `engine.pollingPaused: true` is a master override that wins over both `adoPollEnabled` and `ghPollEnabled`. When ON, section 2.6/2.7 of the tick cycle skips `pollPrStatus` and `pollPrHumanComments` for both providers, `discoverFromPrs` forces `pollEnabled=false` for every project so every per-PR auto-dispatch gate (`autoReviewPrs` / `autoFixBuilds` / `autoFixConflicts` / `autoFixReviewFeedback` / `autoFixHumanComments`) becomes inert, and — since W-ms5eljc60090f0d5 — the reconcile tail (`reconcilePrs`, `ghReconcilePrs`, `reconcileSharedBranchPrs`) is skipped too. Reconciliation was previously exempt as a "recovery sweep", but those sweeps walk every tracked PR and issue provider API calls, so the documented emergency pause did not actually stop provider network traffic. The per-provider `*PrReconcileEnabled` flags remain independent whenever the master switch is OFF. The engine logs `[engine] PR polling paused — …` once on the transition from unpaused → paused; routine PR poll log lines resume when cleared. Flip via Dashboard → Settings → Polling, `POST /api/engine/polling/pause`, or set `engine.pollingPaused: true` in `config.json`. Default OFF — fresh installs behave identically to before this knob existed.
|
|
78
78
|
|
|
79
|
-
**Hard-stop kill-switch (`autoFixPaused`).** `engine.autoFixPaused: true` is a narrower master override that wins over every auto-fix dispatch gate. When ON, `discoverFromPrs` forces `autoFixBuilds` / `autoFixConflicts` / `autoFixReviewFeedback` / `autoFixHumanComments` to false for every project, so no fix agent is auto-dispatched against any PR. Review dispatch (`autoReviewPrs` / `autoReReviewPrs`), PR status / human-comment polling, and reconciliation are intentionally not gated — operators can pause a fix-storm during an incident while still seeing fresh review verdicts and build status. The engine logs `[engine] auto-fix paused — …` once on the transition from unpaused → paused; routine discovery resumes when cleared. Flip via Dashboard → Settings →
|
|
79
|
+
**Hard-stop kill-switch (`autoFixPaused`).** `engine.autoFixPaused: true` is a narrower master override that wins over every auto-fix dispatch gate. When ON, `discoverFromPrs` forces `autoFixBuilds` / `autoFixConflicts` / `autoFixReviewFeedback` / `autoFixHumanComments` to false for every project, so no fix agent is auto-dispatched against any PR. Review dispatch (`autoReviewPrs` / `autoReReviewPrs`), PR status / human-comment polling, and reconciliation are intentionally not gated — operators can pause a fix-storm during an incident while still seeing fresh review verdicts and build status. The engine logs `[engine] auto-fix paused — …` once on the transition from unpaused → paused; routine discovery resumes when cleared. Flip via Dashboard → Settings → Plan & PR Workflow → Monitor, or set `engine.autoFixPaused: true` in `config.json`. Default OFF — fresh installs behave identically to before this knob existed.
|
|
80
80
|
|
|
81
81
|
**Granular per-poller flags (`P-c4d8e1a3`).** The legacy `adoPollEnabled` / `ghPollEnabled` macros are bundle toggles that silence three axes at once (status, comments, reconcile) when set to `false`. To turn off only one axis, set the matching granular flag in `config.engine`:
|
|
82
82
|
|
|
@@ -167,10 +167,19 @@ This means a single work item like "Add telemetry to the document creation pipel
|
|
|
167
167
|
|
|
168
168
|
**Reads:** `config.schedules[]` and persistent schedule-run state.
|
|
169
169
|
|
|
170
|
-
Enabled schedules whose three-field cron expression matches the current minute produce work through `engine/scheduler.js`. Ordinary tasks and tri-agent harness missions are written to the central SQL work-item scope with `_scheduleId` metadata; meeting schedules create meeting records directly. The persisted `lastRun` value prevents a schedule from firing twice in the same calendar minute.
|
|
170
|
+
Enabled schedules whose three-field cron expression matches the current minute produce work through `engine/orchestration/scheduler.js`. Ordinary tasks and tri-agent harness missions are written to the central SQL work-item scope with `_scheduleId` metadata; meeting schedules create meeting records directly. The persisted `lastRun` value prevents a schedule from firing twice in the same calendar minute.
|
|
171
|
+
|
|
172
|
+
#### Scheduled-failure retention (`pruneSupersededFailedScheduledItems`)
|
|
173
|
+
|
|
174
|
+
Machine-generated scheduled runs fail routinely (an hourly review/fetch sweep with a transient auth or network error), so without a retention policy their **failed** work items accumulate a week of duplicates. `engine/orchestration/failed-scheduled-cleanup.js` runs a conservative daily sweep inside `runCleanup` (step 21) to age them out:
|
|
175
|
+
|
|
176
|
+
- **Targets only provable scheduled runs.** An item qualifies via structured provenance (`createdBy === 'scheduler'` **and** `_scheduleId`) or the canonical legacy `sched-<scheduleId>-<ts>` id prefix. Classification is **never** by title/description prose, so a human-authored item that merely mentions "scheduled" is untouched.
|
|
177
|
+
- **Groups failures by originating schedule.** The **newest** failure per schedule is retained long enough to diagnose the current failure; **superseded** (older) failures are pruned once past the diagnostic window (`DIAGNOSTIC_RETENTION_MS`, 24h). A later **successful** run lets the newest failure be pruned too, once that window has elapsed. An absolute threshold (`ABSOLUTE_RETENTION_MS`, 7d) prunes stale failures regardless.
|
|
178
|
+
- **Fails open.** Non-scheduled / human-authored failures, items with plan/PRD/decomposition/followup lineage (`parent_id`, `_prdItemId`), and any item referenced by a live (pending/active/review) dispatch are skipped, never deleted. This is destructive retention and is deliberately separate from the non-destructive navigation-badge age-out for user failures.
|
|
179
|
+
- **Cadence, concurrency, idempotency.** Although `runCleanup` fires every ~10 min, a persisted `lastFailedScheduledPruneAt` marker in the engine small-state store gates the sweep to at most once per `PRUNE_INTERVAL_MS` (daily); the marker is claimed inside a single small-state transaction so overlapping ticks or a restart race cannot double-run it. Deletions go through `mutateWorkItems` and re-validate status/provenance against the fresh SQL row, so a re-run prunes nothing further. Pruned counts are logged once per sweep with the per-schedule breakdown — no per-tick noise. The policy is a documented shared default (no `engine.*` knob), so there is no Settings toggle to configure.
|
|
171
180
|
|
|
172
181
|
`engine.bootstrapDefaultSchedules` defaults to `true` and is configurable under
|
|
173
|
-
Dashboard → Settings → Workflow
|
|
182
|
+
Dashboard → Settings → Plan & PR Workflow → Monitor. `engine/orchestration/schedule-bootstrap.js`
|
|
174
183
|
idempotently creates a read-only per-project git-fetch schedule (title-derived
|
|
175
184
|
`keep-branch-fresh-git-fetch-origin-…` id, `0 */12 *`, `explore`) and one shared
|
|
176
185
|
`harness-sweep-all-projects` schedule (`0 6 *`, `explore`, low priority).
|
|
@@ -202,7 +211,7 @@ Both write to the SQL work-item store and are picked up by Source 2 on the same
|
|
|
202
211
|
|
|
203
212
|
## PR Status Polling (`pollPrStatus`)
|
|
204
213
|
|
|
205
|
-
**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`.
|
|
214
|
+
**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/index.js`; GitHub polling lives in `engine/providers/github.js` — both run in parallel each cycle (`Promise.allSettled`) and write the shared SQL PR schema. Replaces the retired agent-based `pr-sync`.
|
|
206
215
|
|
|
207
216
|
The engine directly polls host REST APIs for **all** PR metadata: build/CI status, human review votes, and completion state. No agent dispatch is needed.
|
|
208
217
|
|
|
@@ -220,7 +229,7 @@ The engine directly polls host REST APIs for **all** PR metadata: build/CI statu
|
|
|
220
229
|
| `buildStatus` | ADO builds or GitHub check-runs | `passing` / `failing` / `running` / `none` |
|
|
221
230
|
| `buildFailReason` | Failed build/check name | Set on failure, cleared otherwise |
|
|
222
231
|
|
|
223
|
-
**Auth:** Bearer token via shared `engine/ado
|
|
232
|
+
**Auth:** Bearer token via shared `engine/ado/token.js`: prefer `az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv`, then fall back to `azureauth ado token --mode iwa --mode broker --output token --timeout 1` (cached 30 minutes). The `--timeout 1` flag is required — without it, azureauth can hang indefinitely in headless sessions. GitHub polling resolves a repo-scoped token through `engine/providers/gh-token.js` and threads it as `GH_TOKEN` per call; it never switches global `gh` auth.
|
|
224
233
|
|
|
225
234
|
This feeds `discoverFromPrs` — when `buildStatus` flips to `"failing"`, the next discovery tick dispatches a fix agent. When `status` becomes `"merged"`, the PR drops out of active polling.
|
|
226
235
|
|
|
@@ -342,8 +351,8 @@ memory are used. Human/LLM-authored appendices are wrapped as untrusted input.
|
|
|
342
351
|
The engine resolves `resolveRuntime(resolveAgentCli(...))`; the selected adapter
|
|
343
352
|
owns binary discovery, argv, prompt delivery, workspace preparation, and output
|
|
344
353
|
parsing. Cold agent dispatches use the runtime-neutral
|
|
345
|
-
`engine/spawn-agent.js`; opt-in Copilot fleet dispatch can use the ACP worker
|
|
346
|
-
pool. CC/doc-chat use direct `engine/llm.js` calls.
|
|
354
|
+
`engine/agents/spawn-agent.js`; opt-in Copilot fleet dispatch can use the ACP worker
|
|
355
|
+
pool. CC/doc-chat use direct `engine/agents/llm.js` calls.
|
|
347
356
|
|
|
348
357
|
- Process runs in the resolved worktree/live checkout (or `MINIONS_DIR` for
|
|
349
358
|
project-less read-only work)
|
|
@@ -4,7 +4,7 @@ How the engine decides which branch a dispatch is going to push to.
|
|
|
4
4
|
CLAUDE.md → Branch Naming holds the one-line summary; the structured
|
|
5
5
|
vs. loose-extractor rules and the canonical PR-fix incident live here.
|
|
6
6
|
|
|
7
|
-
> Source of truth: `engine/shared.js`
|
|
7
|
+
> Source of truth: `engine/core/shared.js`
|
|
8
8
|
> (`deriveWorkItemBranchName`, `extractStructuredWorkItemPrRef`,
|
|
9
9
|
> `extractWorkItemPrRef`, `copyWorkItemPrFields`),
|
|
10
10
|
> `engine.js#getWorkItemPrRef` + `getStructuredWorkItemPrRef`,
|
|
@@ -78,9 +78,9 @@ stamping:
|
|
|
78
78
|
2. **Loose (description/title-scanned) refs on a fix WI** are confirmed via:
|
|
79
79
|
- an already-tracked SQL PR record for the ref (cheap, no
|
|
80
80
|
network), else
|
|
81
|
-
- a host existence check — `engine/github.js#prExists` (`gh api
|
|
82
|
-
repos/:owner/:repo/pulls/NNN`; 404 ⇒ issue) or `engine/ado.js#prExists`
|
|
83
|
-
(`…/pullrequests/NNN`), routed via `engine/gh-token.js` per-account token.
|
|
81
|
+
- a host existence check — `engine/providers/github.js#prExists` (`gh api
|
|
82
|
+
repos/:owner/:repo/pulls/NNN`; 404 ⇒ issue) or `engine/ado/index.js#prExists`
|
|
83
|
+
(`…/pullrequests/NNN`), routed via `engine/providers/gh-token.js` per-account token.
|
|
84
84
|
`shared.classifyPrRefForVerification(prRef, project)` does the pure host/slug
|
|
85
85
|
/number routing; the result is TTL-cached.
|
|
86
86
|
3. **Fail-safe:** when existence can't be confirmed (issue, 404, network/auth
|
package/docs/capture-demos.js
CHANGED
|
@@ -3,13 +3,14 @@
|
|
|
3
3
|
* Capture dashboard screenshots for GitHub Pages.
|
|
4
4
|
* Seeds demo data, captures all pages, then cleans up.
|
|
5
5
|
*
|
|
6
|
-
* Run: node docs/capture-demos.js
|
|
7
|
-
* Requires: dashboard
|
|
6
|
+
* Run: node docs/capture-demos.js --state-dir <isolated-state> --base-url <url>
|
|
7
|
+
* Requires: an isolated dashboard using the same state dir, and Playwright chromium
|
|
8
8
|
*/
|
|
9
9
|
const { chromium } = require('@playwright/test');
|
|
10
10
|
const { execFileSync } = require('child_process');
|
|
11
11
|
const fs = require('fs');
|
|
12
12
|
const path = require('path');
|
|
13
|
+
const { canonicalPath, pathsOverlap } = require('../.github/scripts/owned-directory');
|
|
13
14
|
|
|
14
15
|
const DEMO_DIR = path.join(__dirname, 'demo');
|
|
15
16
|
const DEFAULT_BASE_URL = 'http://localhost:7331';
|
|
@@ -32,6 +33,7 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
32
33
|
baseUrl: DEFAULT_BASE_URL,
|
|
33
34
|
outputDir: DEMO_DIR,
|
|
34
35
|
stateDir: null,
|
|
36
|
+
expectedStateDir: null,
|
|
35
37
|
skipSeed: false,
|
|
36
38
|
fixedTime: null,
|
|
37
39
|
};
|
|
@@ -55,6 +57,10 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
55
57
|
options.stateDir = path.resolve(valueFor(argv[i], i));
|
|
56
58
|
i++;
|
|
57
59
|
break;
|
|
60
|
+
case '--expected-state-dir':
|
|
61
|
+
options.expectedStateDir = valueFor(argv[i], i);
|
|
62
|
+
i++;
|
|
63
|
+
break;
|
|
58
64
|
case '--fixed-time':
|
|
59
65
|
options.fixedTime = valueFor(argv[i], i);
|
|
60
66
|
if (!Number.isFinite(Date.parse(options.fixedTime))) {
|
|
@@ -69,9 +75,33 @@ function parseArgs(argv = process.argv.slice(2)) {
|
|
|
69
75
|
throw new Error(`Unknown argument: ${argv[i]}`);
|
|
70
76
|
}
|
|
71
77
|
}
|
|
78
|
+
if (!options.stateDir) {
|
|
79
|
+
throw new Error('--state-dir is required so capture cannot target live Minions state');
|
|
80
|
+
}
|
|
81
|
+
if (!options.expectedStateDir) options.expectedStateDir = options.stateDir;
|
|
72
82
|
return options;
|
|
73
83
|
}
|
|
74
84
|
|
|
85
|
+
function assertOwnedStateDir(stateDir) {
|
|
86
|
+
if (pathsOverlap(stateDir, ROOT)) {
|
|
87
|
+
throw new Error(`Demo state directory must not overlap the source checkout: ${stateDir}`);
|
|
88
|
+
}
|
|
89
|
+
const marker = path.join(stateDir, '.minions-test-fixture');
|
|
90
|
+
if (!fs.existsSync(marker) || !fs.statSync(marker).isFile() || fs.readFileSync(marker, 'utf8') !== '') {
|
|
91
|
+
throw new Error(`Demo state directory is not marker-owned: ${stateDir}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
async function assertDashboardUsesStateDir(baseUrl, expectedStateDir, fetchImpl = globalThis.fetch) {
|
|
96
|
+
const response = await fetchImpl(`${baseUrl.replace(/\/+$/, '')}/api/health`);
|
|
97
|
+
if (!response.ok) throw new Error(`Dashboard health check failed: HTTP ${response.status}`);
|
|
98
|
+
const health = await response.json();
|
|
99
|
+
if (!health.minionsDir) throw new Error('Dashboard health response did not identify its Minions state directory');
|
|
100
|
+
if (canonicalPath(health.minionsDir) !== canonicalPath(expectedStateDir)) {
|
|
101
|
+
throw new Error(`Refusing capture: dashboard uses ${health.minionsDir}, not isolated state ${expectedStateDir}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
75
105
|
function runSeed({ clean = false, stateDir = null } = {}) {
|
|
76
106
|
const args = [path.join(ROOT, 'test', 'seed-demo-data.js')];
|
|
77
107
|
if (clean) args.push('--clean');
|
|
@@ -84,9 +114,14 @@ async function capture(options = {}) {
|
|
|
84
114
|
baseUrl = DEFAULT_BASE_URL,
|
|
85
115
|
outputDir = DEMO_DIR,
|
|
86
116
|
stateDir = null,
|
|
117
|
+
expectedStateDir = stateDir,
|
|
87
118
|
skipSeed = false,
|
|
88
119
|
fixedTime = null,
|
|
120
|
+
fetchImpl = globalThis.fetch,
|
|
89
121
|
} = options;
|
|
122
|
+
if (!stateDir) throw new Error('stateDir is required so capture cannot target live Minions state');
|
|
123
|
+
assertOwnedStateDir(stateDir);
|
|
124
|
+
await assertDashboardUsesStateDir(baseUrl, expectedStateDir, fetchImpl);
|
|
90
125
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
91
126
|
|
|
92
127
|
let browser;
|
|
@@ -287,4 +322,6 @@ module.exports = {
|
|
|
287
322
|
SCREENSHOT_FILES,
|
|
288
323
|
parseArgs,
|
|
289
324
|
capture,
|
|
325
|
+
assertOwnedStateDir,
|
|
326
|
+
assertDashboardUsesStateDir,
|
|
290
327
|
};
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# CI runner canary
|
|
2
|
+
|
|
3
|
+
`.github/workflows/ci-runner-canary.yml` answers one question every hour: **is
|
|
4
|
+
this repository's CI actually able to run anything?**
|
|
5
|
+
|
|
6
|
+
## The failure it exists for
|
|
7
|
+
|
|
8
|
+
On 2026-07-30 both self-hosted Windows runners on `yemi33/minions` went
|
|
9
|
+
offline. Every automated workflow on that fork ultimately targets that one host
|
|
10
|
+
label, so the effects cascaded:
|
|
11
|
+
|
|
12
|
+
- `Publish to npm` could never allocate a runner for its `validate` job. Its
|
|
13
|
+
run-level concurrency group (`cancel-in-progress: false`) therefore never
|
|
14
|
+
released, and ~59 runs piled up at `status=pending` with **zero jobs
|
|
15
|
+
created**. Bringing the runners back online did **not** drain them — they are
|
|
16
|
+
blocked at RUN level, before a job exists.
|
|
17
|
+
- `PR Tests` sat `queued` for days.
|
|
18
|
+
- The `Rerun stale PR CI` watchdog is itself self-hosted, so the watchdog was
|
|
19
|
+
dark too.
|
|
20
|
+
|
|
21
|
+
The critical property: **none of that ever becomes a failure.** A run with no
|
|
22
|
+
job never reaches a `failure` or `startup_failure` conclusion, and GitHub's 24h
|
|
23
|
+
queue timeout cannot fire on a run that never created a job to time out. The
|
|
24
|
+
hourly CI-health check lists only `--status failure` and `--status
|
|
25
|
+
startup_failure`, so it reported "all green" for ~2.5 days while CI was
|
|
26
|
+
completely dark and npm releases were blocked.
|
|
27
|
+
|
|
28
|
+
A canary that shares any part of that failure domain reports nothing. This one
|
|
29
|
+
is built not to.
|
|
30
|
+
|
|
31
|
+
## What makes it survivable
|
|
32
|
+
|
|
33
|
+
| Property | Why |
|
|
34
|
+
| --- | --- |
|
|
35
|
+
| `runs-on: windows-latest` | A GitHub-**hosted** runner, so a self-hosted outage cannot stall it. Not `ubuntu-latest`: the yemi33 account cannot provision Linux hosted runners (dual-CI topology). `windows-latest` is proven on both forks — `publish.yml`'s `publish` job already uses it. |
|
|
36
|
+
| No `needs:` | Waiting on another job re-imports that job's ability to stall. |
|
|
37
|
+
| Its own concurrency group, `cancel-in-progress: true` | Sharing `npm-publish-*` or `windows-test-heavy-*` would make the canary queue behind the stall it reports. Cancelling in progress means a canary can never itself become the stalled run. |
|
|
38
|
+
| Nothing hardcoded to one fork | `.github/workflows/` is excluded from the backport, so the two forks sync this file by hand; every fork-specific literal is a drift surface. The default branch is read from the API (`master` on yemi33, `main` on opg) and the self-hosted label sets are derived from the workflows actually checked in. |
|
|
39
|
+
|
|
40
|
+
`test/unit/ci-runner-canary.test.js` pins each of these, because every one of
|
|
41
|
+
them is a way the canary could be quietly neutered back into silence.
|
|
42
|
+
|
|
43
|
+
### Editing the `run:` script
|
|
44
|
+
|
|
45
|
+
GitHub substitutes `${{ … }}` expressions **anywhere** in a workflow file, a
|
|
46
|
+
`run:` block scalar included, before the script is handed to the shell. This
|
|
47
|
+
workflow parses other workflows' `runs-on:` values, so it has to *talk about*
|
|
48
|
+
that syntax — and therefore must never spell the opening delimiter out. It
|
|
49
|
+
assembles it at runtime instead (`$exprOpen = '$' + '{{'`).
|
|
50
|
+
|
|
51
|
+
Getting this wrong is silent in both directions:
|
|
52
|
+
|
|
53
|
+
- A **malformed** expression is rejected at parse time. The run reports
|
|
54
|
+
`conclusion=failure` with **zero jobs and no check run**, so `gh pr checks`
|
|
55
|
+
shows all-green and nothing observes that the workflow never ran. That is not
|
|
56
|
+
hypothetical — it is how [run 30754622581][rejected] shipped through review.
|
|
57
|
+
- A **well-formed** one is substituted, silently rewriting the script.
|
|
58
|
+
|
|
59
|
+
The unit test covers both: it parses every expression in every workflow the way
|
|
60
|
+
GitHub does, and it fails if the canary's `run:` block contains the literal
|
|
61
|
+
delimiter at all.
|
|
62
|
+
|
|
63
|
+
[rejected]: https://github.com/opg-microsoft/minions/actions/runs/30754622581
|
|
64
|
+
|
|
65
|
+
## What it checks
|
|
66
|
+
|
|
67
|
+
**(a) Self-hosted fleet health.** Applicability is derived from the workflows
|
|
68
|
+
on disk, not from which runners happen to be registered. Registration is the
|
|
69
|
+
wrong source: if the fleet de-registers itself during a host rebuild, the repo
|
|
70
|
+
has zero runners carrying the label, and "no runners registered" would read as
|
|
71
|
+
"not applicable" at the exact moment every self-hosted job hangs forever. For
|
|
72
|
+
each `runs-on` label set containing `self-hosted`, the canary fails when no
|
|
73
|
+
registered runner carrying that whole set is `online`. Label matching is
|
|
74
|
+
case-insensitive, because workflows ask for `windows` while runners register
|
|
75
|
+
`Windows`.
|
|
76
|
+
|
|
77
|
+
**(b) Stalled runs on the default branch.** Any run `pending` or `queued`
|
|
78
|
+
longer than the threshold fails the canary. This is the load-bearing check: a
|
|
79
|
+
dark fleet always surfaces here, and it needs only `actions: read`.
|
|
80
|
+
|
|
81
|
+
Both emit an actionable job summary — which runners are offline, and the oldest
|
|
82
|
+
stalled run's id, workflow name, age, and URL.
|
|
83
|
+
|
|
84
|
+
## Condition (a) is off by default
|
|
85
|
+
|
|
86
|
+
`GITHUB_TOKEN` **cannot** list self-hosted runners. That endpoint needs
|
|
87
|
+
`administration:read`, and `administration` is not a grantable key in a
|
|
88
|
+
workflow `permissions:` block; the request comes back `404`, which is how
|
|
89
|
+
GitHub masks an unauthorized read here.
|
|
90
|
+
|
|
91
|
+
So condition (a) reports itself as **UNAVAILABLE** — in the log, as a
|
|
92
|
+
`::warning` annotation, in the job summary, and in the closing verdict. It is
|
|
93
|
+
never treated as a pass. To enable it, add a repository secret
|
|
94
|
+
`RUNNER_STATUS_TOKEN` holding a PAT with repo `administration:read`; the
|
|
95
|
+
workflow prefers it over `GITHUB_TOKEN` automatically.
|
|
96
|
+
|
|
97
|
+
Until then, condition (b) still catches the outage, because a fleet that cannot
|
|
98
|
+
allocate runners always produces runs stuck pending or queued.
|
|
99
|
+
|
|
100
|
+
## Tuning and operating
|
|
101
|
+
|
|
102
|
+
- Threshold: `stall_hours` (`workflow_dispatch` input), default **2**.
|
|
103
|
+
- Cadence: hourly, at `:23`.
|
|
104
|
+
- Manual run: `gh workflow run "CI runner canary" --repo <owner>/<repo>`, or
|
|
105
|
+
with an override, `-f stall_hours=6`.
|
|
106
|
+
|
|
107
|
+
### When it goes red
|
|
108
|
+
|
|
109
|
+
1. **Fleet offline** — the failing repo's runners need an operator on the host;
|
|
110
|
+
no code change can bring them back. Restart the Actions runner service.
|
|
111
|
+
2. **Stalled runs** — check whether a run-level `concurrency` group is holding
|
|
112
|
+
the queue. Runs blocked at RUN level do **not** drain on their own once
|
|
113
|
+
runners return; cancel the backlog explicitly:
|
|
114
|
+
|
|
115
|
+
```bash
|
|
116
|
+
gh run list --repo <owner>/<repo> --branch <default> --status pending \
|
|
117
|
+
--limit 100 --json databaseId --jq '.[].databaseId' |
|
|
118
|
+
xargs -n1 gh run cancel --repo <owner>/<repo>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Related: [default-branch-ci.md](default-branch-ci.md) covers the post-merge
|
|
122
|
+
gate, which answers "is the merged tree green?" — a different question from
|
|
123
|
+
"can CI run at all?".
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
**Work item:** W-mrdon0pe000l045a
|
|
4
4
|
**Config flag:** `engine.propagateClaudeMdForNonClaudeRuntimes` (default `true`)
|
|
5
5
|
**Per-project override:** `project.propagateClaudeMdForNonClaudeRuntimes`
|
|
6
|
-
**Module:** `engine/claude-md-context.js` · **Injection:** `engine/playbook.js`
|
|
6
|
+
**Module:** `engine/agents/claude-md-context.js` · **Injection:** `engine/agents/playbook.js`
|
|
7
7
|
|
|
8
8
|
## Problem
|
|
9
9
|
|
|
@@ -84,7 +84,7 @@ does not meaningfully slow dispatch even in a monorepo.
|
|
|
84
84
|
|
|
85
85
|
## Injection & byte cap
|
|
86
86
|
|
|
87
|
-
`engine/playbook.js#renderPlaybook` adds `CLAUDE.md` propagation as a context
|
|
87
|
+
`engine/agents/playbook.js#renderPlaybook` adds `CLAUDE.md` propagation as a context
|
|
88
88
|
layer alongside the existing `pinned.md` → `notes.md` →
|
|
89
89
|
`knowledge/agents/<agentId>.md` layers:
|
|
90
90
|
|