@yemi33/minions 0.1.2448 → 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 +58 -4
- package/dashboard/js/detail-panel.js +36 -0
- package/dashboard/js/memory-panel.js +59 -12
- package/dashboard/js/qa.js +179 -20
- 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 +13 -2
- 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
|
@@ -1,14 +1,24 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* engine/abandoned-pr-reconciliation.js — One-shot startup reconciliation pass
|
|
2
|
+
* engine/providers/abandoned-pr-reconciliation.js — One-shot startup reconciliation pass
|
|
3
3
|
* for `abandoned` PRs. Pairs with W-mp5trwh60008386d's forward-looking 404
|
|
4
|
-
* hardening in engine/github.js: that fix prevents *future* false-flips, but
|
|
4
|
+
* hardening in engine/providers/github.js: that fix prevents *future* false-flips, but
|
|
5
5
|
* does nothing for PRs already wrongly marked `abandoned` before it shipped
|
|
6
6
|
* (e.g. the 16 PRs hit by the 2026-05-14 gh-auth-flip incident).
|
|
7
7
|
*
|
|
8
|
-
* `pollPrStatus` only iterates
|
|
9
|
-
* (engine/shared.js), so once a PR is `abandoned` the regular poll loop never
|
|
8
|
+
* `pollPrStatus` only iterates `PR_POLLABLE_STATUSES = {active, linked}`
|
|
9
|
+
* (engine/core/shared.js), so once a PR is `abandoned` the regular poll loop never
|
|
10
10
|
* visits it again. This module is the explicit one-time re-probe.
|
|
11
11
|
*
|
|
12
|
+
* ## Scope after W-msav5edk00g81710
|
|
13
|
+
*
|
|
14
|
+
* That WI gave abandoned records a BOUNDED re-probe window in the normal status
|
|
15
|
+
* poll (`shared.isPrPollable` + `engine.abandonedPrRepollWindowMs`, default 7
|
|
16
|
+
* days), because `abandoned` is the one terminal status a PR can legitimately
|
|
17
|
+
* leave — a reopened PR was otherwise invisible to the pollers forever. That
|
|
18
|
+
* covers the recent case. This module still owns everything OUTSIDE the window:
|
|
19
|
+
* historical false-flips and records with no usable abandonment anchor, which
|
|
20
|
+
* the poller deliberately fails CLOSED on.
|
|
21
|
+
*
|
|
12
22
|
* ## Why one-shot, not periodic?
|
|
13
23
|
*
|
|
14
24
|
* Periodic re-probing of terminal-status PRs has real costs:
|
|
@@ -33,11 +43,11 @@
|
|
|
33
43
|
*
|
|
34
44
|
* ## Boot wiring
|
|
35
45
|
*
|
|
36
|
-
* Called from engine/cli.js between the recovery sweep and the initial tick.
|
|
46
|
+
* Called from engine/operations/cli.js between the recovery sweep and the initial tick.
|
|
37
47
|
* Errors here must NOT block boot — the catch in cli.js logs and continues.
|
|
38
48
|
*/
|
|
39
49
|
|
|
40
|
-
const shared = require('
|
|
50
|
+
const shared = require('../core/shared');
|
|
41
51
|
|
|
42
52
|
const { ENGINE_DEFAULTS, log, mutateEngineState, readEngineState } = shared;
|
|
43
53
|
|
|
@@ -70,7 +80,7 @@ async function runStartupReconciliation(config, options = {}) {
|
|
|
70
80
|
}
|
|
71
81
|
|
|
72
82
|
const github = options.githubModule || require('./github');
|
|
73
|
-
const ado = options.adoModule || require('
|
|
83
|
+
const ado = options.adoModule || require('../ado');
|
|
74
84
|
|
|
75
85
|
// Pre-count abandoned PRs (only those without the confirmed-404 marker) so
|
|
76
86
|
// the start-of-pass log line is meaningful. Wrapped in try/catch — the
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* engine/comment-classifier.js — P-f23classifier (F2 + F3)
|
|
2
|
+
* engine/providers/comment-classifier.js — P-f23classifier (F2 + F3)
|
|
3
3
|
*
|
|
4
|
-
* Host-agnostic PR-comment body classifiers shared by engine/github.js and
|
|
5
|
-
* engine/ado.js pollers. Three pure body-only predicates:
|
|
4
|
+
* Host-agnostic PR-comment body classifiers shared by engine/providers/github.js and
|
|
5
|
+
* engine/ado/index.js pollers. Three pure body-only predicates:
|
|
6
6
|
*
|
|
7
7
|
* isPreviewStatusBody(body) — Firebase / Appetize / Deploy / Preview bot
|
|
8
8
|
* signatures + Coverage/Build/Test/Deploy/Pipeline report headings +
|
|
9
|
-
* shields.io-style badge images. Ported from engine/github.js
|
|
9
|
+
* shields.io-style badge images. Ported from engine/providers/github.js
|
|
10
10
|
* `_isPreviewStatusComment` body checks. ADO has no `user.type === 'bot'`
|
|
11
11
|
* equivalent, so only the narrower `_isPreviewStatusComment` helper keeps
|
|
12
12
|
* a GH-side bot-author gate; both pollers consume this body match directly.
|
|
@@ -35,24 +35,42 @@
|
|
|
35
35
|
* so a copied marker cannot suppress actionable feedback.
|
|
36
36
|
*
|
|
37
37
|
* IMPORTANT — author identity is intentionally NOT consulted by the three
|
|
38
|
-
* body-only predicates above. Callers
|
|
39
|
-
*
|
|
38
|
+
* body-only predicates above. Callers resolve marker authorship through
|
|
39
|
+
* `classifyMarkerAuthorship()`, which combines `hasMinionsMarker()` with the
|
|
40
|
+
* caller's own host-specific identity signal:
|
|
40
41
|
*
|
|
41
|
-
* GitHub: `comment.viewerDidAuthor
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
* marker non-spoofable on GH.
|
|
42
|
+
* GitHub: `comment.viewerDidAuthor`, backfilled via `gh api user` by
|
|
43
|
+
* engine/providers/github.js `_backfillViewerDidAuthor`. Available
|
|
44
|
+
* when the field is a strict boolean.
|
|
45
45
|
*
|
|
46
46
|
* ADO: `comment.author.uniqueName` (or displayName / id / descriptor)
|
|
47
47
|
* matched case-insensitively against
|
|
48
|
-
* `config.engine.minionsAdoIdentities`. ADO has no
|
|
49
|
-
*
|
|
50
|
-
* would otherwise be misclassified as agent-authored. The combined
|
|
51
|
-
* gate (`isMinionsAdoAuthor && hasMinionsMarker`) is the
|
|
52
|
-
* structural complement that prevents marker spoofing.
|
|
48
|
+
* `config.engine.minionsAdoIdentities`. ADO has no `viewerDidAuthor`
|
|
49
|
+
* equivalent. Available only when that allowlist is non-empty.
|
|
53
50
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
51
|
+
* W-msbf1kf6033f46cb — the identity gate distinguishes "identity says this is
|
|
52
|
+
* someone else" from "there is no identity signal at all", and those two must
|
|
53
|
+
* NOT collapse to the same answer:
|
|
54
|
+
*
|
|
55
|
+
* - MISMATCH → not agent-authored. This is the spoof guard at full
|
|
56
|
+
* strength: a human who pasted our marker keeps their
|
|
57
|
+
* feedback actionable.
|
|
58
|
+
* - UNAVAILABLE → agent-authored (fail-SAFE). Previously this collapsed
|
|
59
|
+
* into "not agent-authored", which on ADO (where the
|
|
60
|
+
* allowlist is empty by default) gave the marker ZERO
|
|
61
|
+
* filtering power: every agent fix-summary was reclassified
|
|
62
|
+
* as new human feedback and re-triggered a fix dispatch on
|
|
63
|
+
* the same PR. Observed on ADO PR 5530936 as ten
|
|
64
|
+
* consecutive zero-change dispatches.
|
|
65
|
+
*
|
|
66
|
+
* The fail-safe direction is chosen on cost asymmetry. Failing open produced
|
|
67
|
+
* an unbounded, self-sustaining dispatch loop that burns agent capacity and
|
|
68
|
+
* is triggered by the engine's own traffic. Failing safe can at worst drop a
|
|
69
|
+
* human comment whose FIRST line is a verbatim copy of our HTML marker — a
|
|
70
|
+
* body shape `hasMinionsMarker` already restricts hard (own first line, no
|
|
71
|
+
* blockquote, no trailing content) and that carries no independent feedback
|
|
72
|
+
* signal. Callers that fail safe should say so out loud (see the ADO
|
|
73
|
+
* poller's one-time spoof-guard warning).
|
|
56
74
|
*/
|
|
57
75
|
|
|
58
76
|
const { MINIONS_COMMENT_MARKER_RE } = require('./gh-comment');
|
|
@@ -210,10 +228,60 @@ function hasVerdictPrefix(body) {
|
|
|
210
228
|
return _VERDICT_PREFIX_RE.test(String(body || ''));
|
|
211
229
|
}
|
|
212
230
|
|
|
231
|
+
// ── Marker authorship (marker + host identity signal) ──────────────────────
|
|
232
|
+
//
|
|
233
|
+
// W-msbf1kf6033f46cb — the single seam both pollers use to answer "did a
|
|
234
|
+
// Minions agent author this comment?". Kept here rather than duplicated in
|
|
235
|
+
// each poller so the ADO and GitHub answers cannot drift (see the
|
|
236
|
+
// mirror-ado-github-poll-fix convention).
|
|
237
|
+
const MARKER_AUTHORSHIP = Object.freeze({
|
|
238
|
+
// No engine-owned marker on the body's own first line.
|
|
239
|
+
NOT_MARKED: 'not-marked',
|
|
240
|
+
// Marker + the host identity signal confirms our own identity.
|
|
241
|
+
IDENTITY_CONFIRMED: 'identity-confirmed',
|
|
242
|
+
// Marker + the host identity signal names someone else → spoof guard.
|
|
243
|
+
IDENTITY_MISMATCH: 'identity-mismatch',
|
|
244
|
+
// Marker + no usable identity signal → fail-safe, trust the marker.
|
|
245
|
+
IDENTITY_UNAVAILABLE: 'identity-unavailable',
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
const _MARKER_AUTHORED_STATES = new Set([
|
|
249
|
+
MARKER_AUTHORSHIP.IDENTITY_CONFIRMED,
|
|
250
|
+
MARKER_AUTHORSHIP.IDENTITY_UNAVAILABLE,
|
|
251
|
+
]);
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Resolve marker authorship for one comment.
|
|
255
|
+
*
|
|
256
|
+
* @param {object} opts
|
|
257
|
+
* @param {string} opts.body Raw comment body.
|
|
258
|
+
* @param {boolean} opts.identityAvailable Whether the caller has a usable
|
|
259
|
+
* identity signal at all (GH: viewerDidAuthor is a strict boolean;
|
|
260
|
+
* ADO: config.engine.minionsAdoIdentities is non-empty).
|
|
261
|
+
* @param {boolean} opts.identityMatches Whether that signal names us.
|
|
262
|
+
* Ignored when `identityAvailable` is false.
|
|
263
|
+
* @returns {string} one of MARKER_AUTHORSHIP.
|
|
264
|
+
*/
|
|
265
|
+
function classifyMarkerAuthorship({ body, identityAvailable, identityMatches } = {}) {
|
|
266
|
+
if (!hasMinionsMarker(body)) return MARKER_AUTHORSHIP.NOT_MARKED;
|
|
267
|
+
if (identityAvailable !== true) return MARKER_AUTHORSHIP.IDENTITY_UNAVAILABLE;
|
|
268
|
+
return identityMatches === true
|
|
269
|
+
? MARKER_AUTHORSHIP.IDENTITY_CONFIRMED
|
|
270
|
+
: MARKER_AUTHORSHIP.IDENTITY_MISMATCH;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
/** True only for the two states that mean "a Minions agent wrote this". */
|
|
274
|
+
function isMarkerAuthored(state) {
|
|
275
|
+
return _MARKER_AUTHORED_STATES.has(state);
|
|
276
|
+
}
|
|
277
|
+
|
|
213
278
|
module.exports = {
|
|
214
279
|
isPreviewStatusBody,
|
|
215
280
|
hasMinionsMarker,
|
|
216
281
|
hasVerdictPrefix,
|
|
282
|
+
classifyMarkerAuthorship,
|
|
283
|
+
isMarkerAuthored,
|
|
284
|
+
MARKER_AUTHORSHIP,
|
|
217
285
|
classifyNonActionableAutomationComment,
|
|
218
286
|
NON_ACTIONABLE_AUTOMATION_REASONS,
|
|
219
287
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* engine/comment-format.js — platform-neutral PR-comment body fragments.
|
|
2
|
+
* engine/providers/comment-format.js — platform-neutral PR-comment body fragments.
|
|
3
3
|
*
|
|
4
4
|
* Owns the platform-neutral Minions marker and brand-link formatting shared by
|
|
5
5
|
* GitHub and Azure DevOps comment transports.
|
|
@@ -41,8 +41,8 @@ function linkifyBrandTrailer(text) {
|
|
|
41
41
|
// ── Minions marker + neutral comment-body builder ───────────────────────────
|
|
42
42
|
//
|
|
43
43
|
// The hidden HTML-comment marker and the body composition (marker + harness
|
|
44
|
-
// brand link) are platform-NEUTRAL: GitHub (engine/gh-comment.js) and
|
|
45
|
-
// Azure DevOps (engine/ado
|
|
44
|
+
// brand link) are platform-NEUTRAL: GitHub (engine/providers/gh-comment.js) and
|
|
45
|
+
// Azure DevOps (engine/ado/comment.js) both post the byte-identical body built
|
|
46
46
|
// here, so there is one builder and no drift. The host modules own only the
|
|
47
47
|
// transport (gh CLI vs ADO REST) and host-specific validation (repo slug vs
|
|
48
48
|
// org/project/repoId).
|
|
@@ -57,7 +57,7 @@ function linkifyBrandTrailer(text) {
|
|
|
57
57
|
// - model concrete runtime execution model (optional)
|
|
58
58
|
// - no field may contain `--` (would close the HTML comment early)
|
|
59
59
|
|
|
60
|
-
const { normalizeExecutionModel, UNKNOWN_MODEL } = require('
|
|
60
|
+
const { normalizeExecutionModel, UNKNOWN_MODEL } = require('../core/execution-model');
|
|
61
61
|
|
|
62
62
|
const AGENT_ID_RE = /^[a-z][a-z0-9-]{0,30}$/;
|
|
63
63
|
const KIND_RE = /^[a-z][a-z0-9-]{0,30}$/;
|
|
@@ -218,7 +218,7 @@ module.exports = {
|
|
|
218
218
|
linkifyBrandTrailer,
|
|
219
219
|
stampExecutionModel,
|
|
220
220
|
MINIONS_BRAND_URL,
|
|
221
|
-
// Neutral marker + body builder (consumed by gh-comment.js and ado
|
|
221
|
+
// Neutral marker + body builder (consumed by gh-comment.js and engine/ado/comment.js).
|
|
222
222
|
buildMinionsCommentBody,
|
|
223
223
|
parseMinionsMarker,
|
|
224
224
|
MINIONS_COMMENT_MARKER,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* engine/gh-comment.js — wraps `gh pr comment` / `gh pr review` with a hidden
|
|
3
|
-
* HTML-comment marker so downstream classifiers (engine/github.js) can identify
|
|
2
|
+
* engine/providers/gh-comment.js — wraps `gh pr comment` / `gh pr review` with a hidden
|
|
3
|
+
* HTML-comment marker so downstream classifiers (engine/providers/github.js) can identify
|
|
4
4
|
* minions-authored PR comments by structure rather than by body shape.
|
|
5
5
|
*
|
|
6
6
|
* Marker format (single line, ASCII):
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
* backticks, or `$(…)`. Temp files are cleaned up in `finally`.
|
|
29
29
|
*
|
|
30
30
|
* Per-slug PAT routing (P-bfa2a): each public function resolves a per-slug
|
|
31
|
-
* GitHub token via `engine/gh-token.js#resolveTokenForSlug(repo)` and threads
|
|
31
|
+
* GitHub token via `engine/providers/gh-token.js#resolveTokenForSlug(repo)` and threads
|
|
32
32
|
* it into the spawned `gh` process via `env.GH_TOKEN`. When the slug has no
|
|
33
33
|
* mapping in `engine.ghAccounts`, we fall back to the ambient `gh` identity
|
|
34
34
|
* (inherited via `process.env`) and emit a one-shot `console.warn` per slug
|
|
@@ -46,15 +46,15 @@ const {
|
|
|
46
46
|
linkifyBrandTrailer,
|
|
47
47
|
MINIONS_BRAND_URL,
|
|
48
48
|
// Neutral marker + body builder now lives in comment-format.js so the GitHub
|
|
49
|
-
// (this module) and ADO (engine/ado
|
|
50
|
-
buildMinionsCommentBody, // re-export of engine/comment-format.js (neutral builder)
|
|
51
|
-
parseMinionsMarker, // re-export of engine/comment-format.js
|
|
52
|
-
MINIONS_COMMENT_MARKER, // re-export of engine/comment-format.js
|
|
53
|
-
MINIONS_COMMENT_MARKER_RE, // re-export of engine/comment-format.js
|
|
54
|
-
AGENT_ID_RE, // re-export of engine/comment-format.js
|
|
55
|
-
KIND_RE, // re-export of engine/comment-format.js
|
|
56
|
-
WORK_ITEM_ID_RE, // re-export of engine/comment-format.js
|
|
57
|
-
_buildMarker, // re-export of engine/comment-format.js
|
|
49
|
+
// (this module) and ADO (engine/ado/comment.js) posters share one builder.
|
|
50
|
+
buildMinionsCommentBody, // re-export of engine/providers/comment-format.js (neutral builder)
|
|
51
|
+
parseMinionsMarker, // re-export of engine/providers/comment-format.js
|
|
52
|
+
MINIONS_COMMENT_MARKER, // re-export of engine/providers/comment-format.js
|
|
53
|
+
MINIONS_COMMENT_MARKER_RE, // re-export of engine/providers/comment-format.js
|
|
54
|
+
AGENT_ID_RE, // re-export of engine/providers/comment-format.js
|
|
55
|
+
KIND_RE, // re-export of engine/providers/comment-format.js
|
|
56
|
+
WORK_ITEM_ID_RE, // re-export of engine/providers/comment-format.js
|
|
57
|
+
_buildMarker, // re-export of engine/providers/comment-format.js
|
|
58
58
|
} = require('./comment-format');
|
|
59
59
|
|
|
60
60
|
// Module-level dedupe set so the "no token mapping for <slug>" warning fires
|
|
@@ -65,7 +65,7 @@ const _warnedUnresolvedSlugs = new Set();
|
|
|
65
65
|
|
|
66
66
|
// ── Validation (GitHub-specific) ─────────────────────────────────────────────
|
|
67
67
|
// The marker field validators + neutral body builder now live in
|
|
68
|
-
// engine/comment-format.js (shared with engine/ado
|
|
68
|
+
// engine/providers/comment-format.js (shared with engine/ado/comment.js). Only the
|
|
69
69
|
// GitHub repo-slug + PR-number validators remain host-specific here.
|
|
70
70
|
|
|
71
71
|
const REPO_SLUG_RE = /^[A-Za-z0-9._-]+\/[A-Za-z0-9._-]+$/;
|
|
@@ -210,8 +210,8 @@ function postPrReviewComment({
|
|
|
210
210
|
module.exports = {
|
|
211
211
|
// Builders / parsers (pure functions — usable from anywhere)
|
|
212
212
|
buildMinionsCommentBody,
|
|
213
|
-
linkifyBrandTrailer, // re-export of engine/comment-format.js for comment callers
|
|
214
|
-
MINIONS_BRAND_URL, // re-export of engine/comment-format.js for comment callers
|
|
213
|
+
linkifyBrandTrailer, // re-export of engine/providers/comment-format.js for comment callers
|
|
214
|
+
MINIONS_BRAND_URL, // re-export of engine/providers/comment-format.js for comment callers
|
|
215
215
|
parseMinionsMarker,
|
|
216
216
|
MINIONS_COMMENT_MARKER,
|
|
217
217
|
MINIONS_COMMENT_MARKER_RE,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* engine/gh-token.js — Per-slug GitHub PAT resolution.
|
|
2
|
+
* engine/providers/gh-token.js — Per-slug GitHub PAT resolution.
|
|
3
3
|
*
|
|
4
4
|
* Resolves the PAT for a given owner/repo slug by consulting
|
|
5
5
|
* `config.engine.ghAccounts` and shelling out to `gh auth token --user <account>
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
* 4. null → caller falls back to the ambient `gh` identity, preserving
|
|
14
14
|
* legacy behavior for unmapped slugs.
|
|
15
15
|
*
|
|
16
|
-
* Mirrors the shape of `engine/ado
|
|
16
|
+
* Mirrors the shape of `engine/ado/token.js` (separate sync token acquisition
|
|
17
17
|
* helper, in-memory cache, narrow exec timeout). Tests can prime the cache
|
|
18
18
|
* via `_setTokenForTest(slug, token)` and clear it via `_clearTokenCache()`.
|
|
19
19
|
*/
|
|
20
20
|
|
|
21
21
|
const { execFileSync } = require('child_process');
|
|
22
22
|
const path = require('path');
|
|
23
|
-
const shared = require('
|
|
23
|
+
const shared = require('../core/shared');
|
|
24
24
|
const { safeJsonObj, MINIONS_DIR, log } = shared;
|
|
25
25
|
|
|
26
26
|
const TOKEN_TTL_MS = 30 * 60 * 1000; // 30 minutes
|
|
@@ -112,7 +112,7 @@ function resolveTokenForSlug(slug, opts = {}) {
|
|
|
112
112
|
/**
|
|
113
113
|
* Resolve a GitHub PAT for a named account directly (bypassing slug→account
|
|
114
114
|
* mapping). Used by the projectless PR resolver's unknown-slug fallback
|
|
115
|
-
* (engine/pr-resolve.js) to try each authed account in turn WITHOUT touching
|
|
115
|
+
* (engine/providers/pr-resolve.js) to try each authed account in turn WITHOUT touching
|
|
116
116
|
* the global active `gh auth` profile. Returns the token string or null.
|
|
117
117
|
*/
|
|
118
118
|
function tokenForAccount(account, opts = {}) {
|