@yemi33/minions 0.1.2424 → 0.1.2425
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/install-internal-minions.js +1209 -0
- package/bin/minions.js +75 -9
- package/dashboard/docs/typography.md +27 -12
- package/dashboard/js/command-center.js +13 -11
- package/dashboard/js/live-stream.js +1 -1
- package/dashboard/js/memory-search.js +388 -43
- package/dashboard/js/modal-qa.js +5 -5
- package/dashboard/js/qa.js +39 -26
- package/dashboard/js/refresh.js +37 -18
- package/dashboard/js/render-agents.js +14 -18
- package/dashboard/js/render-dispatch.js +14 -74
- package/dashboard/js/render-inbox.js +3 -3
- package/dashboard/js/render-meetings.js +8 -8
- package/dashboard/js/render-other.js +45 -20
- package/dashboard/js/render-pipelines.js +6 -6
- package/dashboard/js/render-plans.js +14 -14
- package/dashboard/js/render-prd.js +46 -46
- package/dashboard/js/render-prs.js +9 -65
- package/dashboard/js/render-schedules.js +5 -5
- package/dashboard/js/render-skills.js +6 -6
- package/dashboard/js/render-utils.js +4 -4
- package/dashboard/js/render-watches.js +4 -16
- package/dashboard/js/render-work-items.js +95 -107
- package/dashboard/js/settings.js +175 -74
- package/dashboard/layout.html +3 -2
- package/dashboard/pages/inbox.html +1 -1
- package/dashboard/pages/work.html +1 -1
- package/dashboard/shared/model-display.js +9 -0
- package/dashboard/shared/watches-source.js +43 -0
- package/dashboard/shared/welcome-popup.js +259 -0
- package/dashboard/slim/body.html +6 -6
- package/dashboard/slim/js/chat.js +4 -2
- package/dashboard/slim/js/history.js +10 -3
- package/dashboard/slim/js/modals-tiles.js +85 -16
- package/dashboard/slim/js/status.js +12 -16
- package/dashboard/slim/styles.css +24 -4
- package/dashboard/styles.css +62 -27
- package/dashboard-build.js +8 -2
- package/dashboard.js +3854 -2514
- package/docs/README.md +6 -4
- package/docs/api-errors.md +144 -0
- package/docs/auto-discovery.md +83 -61
- package/docs/capture-demos.js +173 -30
- package/docs/command-center.md +5 -1
- package/docs/completion-reports.md +127 -11
- package/docs/constants.md +15 -3
- package/docs/constellation-style-telemetry.md +2 -2
- package/docs/copilot-cli-schema.md +32 -22
- package/docs/cross-repo-plans.md +30 -30
- package/docs/demo/memory-system.html +1 -1
- package/docs/deprecated.json +132 -18
- package/docs/diagnostics-memory.md +8 -4
- package/docs/human-vs-automated.md +2 -2
- package/docs/internal-install.md +190 -0
- package/docs/kb-pr3223-cascade-archiving.md +16 -0
- package/docs/kb-pr696-merge-conflict-docs.md +23 -0
- package/docs/kb-sweep.md +2 -2
- package/docs/keep-processes.md +8 -1
- package/docs/live-checkout-mode.md +1 -1
- package/docs/managed-spawn.md +21 -3
- package/docs/named-agents.md +3 -2
- package/docs/plan-lifecycle.md +32 -32
- 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-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/qa-runbook-lifecycle.md +67 -51
- package/docs/qa-runbooks.md +2 -2
- package/docs/runtime-adapters.md +101 -50
- package/docs/security.md +28 -0
- package/docs/self-improvement.md +47 -13
- package/docs/skills.md +29 -0
- package/docs/slim-ux/concepts.md +2 -2
- package/docs/specs/agent-configurability.md +43 -41
- package/docs/specs/agent-rename.md +13 -13
- package/docs/team-memory.md +283 -14
- package/docs/tutorials/03-plan-driven-feature.md +3 -3
- package/docs/tutorials/04-runtimes-and-harness.md +18 -21
- package/docs/tutorials/08-operations-and-recovery.md +3 -2
- package/docs/tutorials/README.md +4 -3
- package/docs/visual-evidence-ci.md +103 -0
- package/docs/watches.md +35 -30
- package/docs/worktree-lifecycle.md +151 -13
- package/engine/acp-transport.js +1 -0
- package/engine/ado.js +80 -33
- package/engine/agent-api-validation.js +571 -0
- package/engine/agent-worker-pool.js +7 -6
- package/engine/api-contracts/agent-content.js +761 -0
- package/engine/api-contracts/cc-ops.js +219 -0
- package/engine/api-contracts/config-runtime.js +419 -0
- package/engine/api-contracts/core.js +138 -0
- package/engine/api-contracts/index.js +506 -0
- package/engine/api-contracts/orchestration.js +602 -0
- package/engine/api-contracts/pull-requests.js +323 -0
- package/engine/api-contracts/qa-process.js +764 -0
- package/engine/api-contracts/work-plan-prd.js +494 -0
- package/engine/api-validation.js +543 -0
- package/engine/cc-api-validation.js +586 -0
- package/engine/cc-worker-pool.js +9 -1
- package/engine/cleanup.js +393 -271
- package/engine/cli.js +65 -7
- package/engine/comment-classifier.js +70 -5
- package/engine/consolidation.js +123 -5
- package/engine/content-api-validation.js +606 -0
- package/engine/create-pr-worktree.js +22 -1
- package/engine/db/migrations/027-review-learning-lifecycle.js +162 -0
- package/engine/dispatch.js +33 -0
- package/engine/distribution.js +189 -0
- package/engine/execution-model.js +59 -0
- package/engine/features.js +12 -0
- package/engine/github.js +67 -25
- package/engine/harness-context.js +313 -0
- package/engine/inbox-store.js +1 -1
- package/engine/kb-sweep.js +161 -38
- package/engine/keep-process-sweep.js +43 -3
- package/engine/lifecycle.js +1066 -165
- package/engine/llm.js +4 -0
- package/engine/managed-spawn.js +463 -48
- package/engine/meeting.js +197 -34
- package/engine/memory-retrieval.js +280 -0
- package/engine/memory-store.js +821 -38
- package/engine/model-discovery.js +17 -3
- package/engine/pipeline.js +802 -14
- package/engine/plan-prd-validation.js +745 -0
- package/engine/playbook.js +206 -17
- package/engine/pooled-agent-process.js +6 -1
- package/engine/pr-action.js +1 -1
- package/engine/pr-issue-validation.js +653 -0
- package/engine/pr-resolve.js +75 -13
- package/engine/prd-store.js +39 -6
- package/engine/preflight.js +7 -2
- package/engine/process-utils.js +79 -31
- package/engine/projects.js +198 -12
- package/engine/promotion.js +371 -0
- package/engine/qa-from-prd.js +3 -0
- package/engine/qa-process-validation.js +572 -0
- package/engine/qa-runbooks.js +41 -37
- package/engine/qa-runners/maestro.js +11 -7
- package/engine/qa-runners/playwright.js +37 -14
- package/engine/qa-runners.js +9 -10
- package/engine/qa-runs.js +124 -11
- package/engine/qa-sessions.js +139 -40
- package/engine/quarantine-refs.js +81 -11
- package/engine/queries.js +163 -9
- package/engine/review-learning-backfill.js +482 -0
- package/engine/review-learning.js +1236 -0
- package/engine/runtimes/claude.js +60 -2
- package/engine/runtimes/codex.js +57 -16
- package/engine/runtimes/contract.js +21 -0
- package/engine/runtimes/copilot.js +51 -3
- package/engine/runtimes/index.js +1 -0
- package/engine/scheduler.js +201 -32
- package/engine/settings-validation.js +909 -0
- package/engine/shared.js +705 -208
- package/engine/spawn-agent.js +48 -21
- package/engine/steering-constraints.js +31 -0
- package/engine/steering-store.js +10 -2
- package/engine/steering.js +14 -2
- package/engine/timeout.js +404 -111
- package/engine/untrusted-fence.js +24 -10
- package/engine/watch-actions.js +7 -2
- package/engine/watches.js +353 -51
- package/engine/work-item-validation.js +561 -0
- package/engine/work-items-store.js +61 -1
- package/engine/worktree-gc.js +656 -37
- package/engine/worktree-preflight.js +154 -0
- package/engine.js +2068 -342
- package/package.json +1 -1
- package/playbooks/_pr-description-audit.md +88 -41
- package/playbooks/build-fix-complex.md +3 -3
- package/playbooks/docs.md +2 -2
- package/playbooks/fix.md +18 -18
- package/playbooks/implement.md +18 -18
- package/playbooks/qa-session-draft.md +10 -12
- package/playbooks/qa-session-execute.md +16 -12
- package/playbooks/qa-validate.md +8 -7
- package/playbooks/shared-rules.md +45 -0
- package/playbooks/test.md +4 -0
- package/prompts/cc-system.md +1 -1
- package/skills/check-self-authored-review-comment/SKILL.md +2 -2
package/engine/playbook.js
CHANGED
|
@@ -29,30 +29,43 @@ function getRepoHost(project) {
|
|
|
29
29
|
return project?.repoHost || 'ado';
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
function getPrCreateInstructions(project) {
|
|
32
|
+
function getPrCreateInstructions(project, config) {
|
|
33
33
|
const host = getRepoHost(project);
|
|
34
34
|
const repoId = project?.repositoryId || '';
|
|
35
|
+
// W-mrtdy7xv — createPrsAsDraft: when ON, tell agents to open the PR
|
|
36
|
+
// as a draft (host-aware). Per-project-overridable (W-mrxv648b): a project
|
|
37
|
+
// can opt IN or OUT of draft PRs independent of the fleet-wide engine flag.
|
|
38
|
+
// Resolved via shared.resolveCreatePrsAsDraft(project, engine): explicit
|
|
39
|
+
// per-project boolean wins → else engine flag → else ENGINE_DEFAULTS (false).
|
|
40
|
+
const createPrsAsDraft = shared.resolveCreatePrsAsDraft(project, config?.engine);
|
|
35
41
|
if (host === 'github') {
|
|
36
42
|
const org = getProjectOrg(project);
|
|
37
43
|
const repo = project?.repoName || '';
|
|
38
44
|
const mainBranch = project?.localPath ? shared.resolveMainBranch(project.localPath, project.mainBranch) : (project?.mainBranch || 'main');
|
|
45
|
+
const draftFlag = createPrsAsDraft ? ' --draft' : '';
|
|
39
46
|
return `Use \`gh pr create\` to create a pull request:\n` +
|
|
40
|
-
`- Write the PR description to a temporary Markdown file, then run: \`gh pr create --base ${mainBranch} --head <your-branch> --title "PR title" --body-file <body-file.md> --repo ${org}/${repo}\`\n` +
|
|
47
|
+
`- Write the PR description to a temporary Markdown file, then run: \`gh pr create --base ${mainBranch} --head <your-branch> --title "PR title" --body-file <body-file.md> --repo ${org}/${repo}${draftFlag}\`\n` +
|
|
41
48
|
`- Always set --base to \`${mainBranch}\` (the main branch)\n` +
|
|
42
49
|
`- Always set --repo to \`${org}/${repo}\` to target the correct repository\n` +
|
|
43
50
|
`- Use --head to specify your feature branch name\n` +
|
|
44
|
-
`-
|
|
51
|
+
(createPrsAsDraft ? `- Open the PR as a DRAFT: include the \`--draft\` flag exactly as shown above (the operator has "Create PRs as draft" enabled)\n` : '') +
|
|
52
|
+
`- Include a meaningful --title and body file describing the changes\n` +
|
|
53
|
+
`- If this PR contains a meaningful VISUAL/UI change (dashboard pages, slim-ux, Settings, work-item/PR/plan views, badges, layout/CSS), proactively capture + EMBED screenshots in the body — BEFORE/AFTER for fixes, AFTER-only for new UI. Publish PNGs as assets on a per-PR prerelease (\`gh release create pr-<num>-visual … --prerelease\`, or \`gh release upload … --clobber\` on re-dispatch) with a per-command \`GH_TOKEN\` for the ${org} account (NEVER \`gh auth switch\`), resolve each \`browser_download_url\`, and reference it as \`\`. Never \`git add\` a PNG; skip + record on failure. Full recipe: the "Screenshot handling" section of the PR description audit.`;
|
|
45
54
|
}
|
|
46
55
|
// Default: Azure DevOps — prefer `az` CLI first, ADO REST API as fallback
|
|
47
56
|
const adoOrg = project?.adoOrg || '';
|
|
48
57
|
const adoProject = project?.adoProject || '';
|
|
49
58
|
const repoName = project?.repoName || '';
|
|
50
59
|
const mainBranch = project?.localPath ? shared.resolveMainBranch(project.localPath, project.mainBranch) : (project?.mainBranch || 'main');
|
|
60
|
+
const adoDraftFlag = createPrsAsDraft ? ' --draft true' : '';
|
|
51
61
|
return `For Azure DevOps, use the \`az\` CLI first to create a pull request:\n` +
|
|
52
62
|
`- Run \`az devops configure --defaults organization=https://dev.azure.com/${adoOrg} project="${adoProject}"\` once per session if defaults are not yet set\n` +
|
|
53
|
-
`- Then: \`az repos pr create --repository "${repoName}" --source-branch <your-branch> --target-branch ${mainBranch} --title "PR title" --description @<body-file.md
|
|
63
|
+
`- Then: \`az repos pr create --repository "${repoName}" --source-branch <your-branch> --target-branch ${mainBranch} --title "PR title" --description @<body-file.md>${adoDraftFlag}\`\n` +
|
|
54
64
|
`- Use \`@<file>\` syntax for \`--description\` so Markdown, quotes, and newlines pass safely\n` +
|
|
55
|
-
`- Always set --target-branch to \`${mainBranch}\` (the main branch)\n
|
|
65
|
+
`- Always set --target-branch to \`${mainBranch}\` (the main branch)\n` +
|
|
66
|
+
(createPrsAsDraft ? `- Open the PR as a DRAFT: include \`--draft true\` exactly as shown above (the operator has "Create PRs as draft" enabled). For the REST API fallback, set \`"isDraft": true\` in the request body\n` : '') +
|
|
67
|
+
`- If this PR contains a meaningful VISUAL/UI change (dashboard pages, slim-ux, Settings, work-item/PR/plan views, badges, layout/CSS), proactively capture + EMBED screenshots in the description — BEFORE/AFTER for fixes, AFTER-only for new UI. Upload via \`PUT .../pullRequests/<id>/attachments/<filename>\` with the PNG bytes and reference the returned URL. Save PNGs under \`agents/<id>/screenshots/\` only; never \`git add\` a PNG; skip + record on failure. Full recipe: the "Screenshot handling" section of the PR description audit\n` +
|
|
68
|
+
`\n` +
|
|
56
69
|
`If \`az\` is unavailable, fall back to the ADO REST API: get a token with \`az account get-access-token --resource 499b84ac-1321-427f-aa17-267ca6975798 --query accessToken -o tsv\` and \`POST .../_apis/git/repositories/${repoId}/pullrequests?api-version=7.1\` (Bearer auth). Do not use \`gh\` for Azure DevOps repositories.`;
|
|
57
70
|
}
|
|
58
71
|
|
|
@@ -415,7 +428,7 @@ const PLAYBOOK_REQUIRED_VARS = {
|
|
|
415
428
|
'test': ['item_name'],
|
|
416
429
|
'docs': ['item_id', 'item_name'],
|
|
417
430
|
'setup': ['item_id', 'item_name', 'project_path'],
|
|
418
|
-
'qa-validate': ['item_id', 'item_name', 'qa_run_id'],
|
|
431
|
+
'qa-validate': ['item_id', 'item_name', 'qa_run_id', 'qa_artifacts_dir', 'qa_result_sidecar'],
|
|
419
432
|
// P-e6b3c2d8 — QA Session SETUP phase. Required vars are session
|
|
420
433
|
// identification + target kind + flows + the deterministic managed-spawn
|
|
421
434
|
// name the engine joins back to the session on. Conditional target_*
|
|
@@ -426,11 +439,11 @@ const PLAYBOOK_REQUIRED_VARS = {
|
|
|
426
439
|
// flows + the live managed-spawn name + the runner adapter's
|
|
427
440
|
// generateBrief() output. The brief is computed at render time by
|
|
428
441
|
// engine.js (lazy-required qa-sessions + qa-runners + managed-spawn).
|
|
429
|
-
'qa-session-draft': ['session_id', 'flows_raw', 'managed_spawn_name', 'runner_brief'],
|
|
442
|
+
'qa-session-draft': ['session_id', 'flows_raw', 'managed_spawn_name', 'managed_spawn_lookup_url', 'qa_test_dir', 'runner_brief'],
|
|
430
443
|
// P-f9a2e1b4 — QA Session EXECUTE phase. Required vars are session id +
|
|
431
444
|
// live managed-spawn name + executeBrief() output + the qa-runs record id
|
|
432
445
|
// (the agent stamps it on the result sidecar so lifecycle.js can ingest it).
|
|
433
|
-
'qa-session-execute': ['session_id', 'managed_spawn_name', 'runner_execute_brief', 'qa_run_id'],
|
|
446
|
+
'qa-session-execute': ['session_id', 'managed_spawn_name', 'managed_spawn_lookup_url', 'runner_execute_brief', 'qa_run_id', 'qa_artifacts_dir', 'qa_result_sidecar'],
|
|
434
447
|
'work-item': ['item_id', 'item_name'],
|
|
435
448
|
'meeting-investigate': ['meeting_title', 'agenda'],
|
|
436
449
|
'meeting-debate': ['meeting_title', 'agenda'],
|
|
@@ -443,6 +456,31 @@ const LIVE_VALIDATION_DEFERRED_PLAYBOOKS = new Set([
|
|
|
443
456
|
'build-fix-complex',
|
|
444
457
|
]);
|
|
445
458
|
|
|
459
|
+
// W-mrtdmtwq000kf391 — playbooks whose completion can open or update a
|
|
460
|
+
// Minions-authored PR body. Only these dispatches get the "Repo harnesses used"
|
|
461
|
+
// PR-body appendix, AND only when the work item's resolved PR contract actually
|
|
462
|
+
// produces/updates a PR (see the `skip_pr` / `shared_branch` gates at the
|
|
463
|
+
// injection site). Review/explore/ask/plan/meeting dispatches post comments or
|
|
464
|
+
// produce artifacts rather than authoring a PR body, so they are excluded.
|
|
465
|
+
//
|
|
466
|
+
// This set is aligned with the real per-playbook PR contract, NOT a loose
|
|
467
|
+
// name allowlist (reviewer BLOCKING, PR #898):
|
|
468
|
+
// - `setup` (playbooks/setup.md) explicitly produces NO PR — excluded.
|
|
469
|
+
// - `build-and-test` (playbooks/build-and-test.md) is read-only ("Do not
|
|
470
|
+
// create pull requests or push commits") — excluded.
|
|
471
|
+
// - `test` (playbooks/test.md) CAN create a PR when it changes files — included
|
|
472
|
+
// (the fenced block is a no-op when the dispatch opens no PR, since the agent
|
|
473
|
+
// only appends it to a PR body it actually authors).
|
|
474
|
+
const PR_AUTHORING_PLAYBOOKS = new Set([
|
|
475
|
+
'implement',
|
|
476
|
+
'work-item',
|
|
477
|
+
'fix',
|
|
478
|
+
'build-fix-complex',
|
|
479
|
+
'verify',
|
|
480
|
+
'docs',
|
|
481
|
+
'test',
|
|
482
|
+
]);
|
|
483
|
+
|
|
446
484
|
/**
|
|
447
485
|
* Validate that all required template variables for a playbook type are present
|
|
448
486
|
* and non-empty in the provided vars object.
|
|
@@ -530,13 +568,14 @@ function resolvePlaybookPath(projectName, playbookType) {
|
|
|
530
568
|
// and renders a compact, prompt-friendly summary. Heavy guards against
|
|
531
569
|
// missing fields because dispatch callers may supply partial snapshots when
|
|
532
570
|
// the managed-process state has rotated between schedule and dispatch.
|
|
533
|
-
function buildQaValidateContextBlock({ runId, runbook, target, artifactsDir }) {
|
|
571
|
+
function buildQaValidateContextBlock({ runId, runbook, target, artifactsDir, resultSidecar }) {
|
|
534
572
|
if (!runId) return '';
|
|
535
573
|
const lines = [];
|
|
536
574
|
lines.push('## QA Run Context');
|
|
537
575
|
lines.push('');
|
|
538
576
|
lines.push(`- **runId:** \`${runId}\``);
|
|
539
577
|
if (artifactsDir) lines.push(`- **artifactsDir:** \`${artifactsDir}\``);
|
|
578
|
+
if (resultSidecar) lines.push(`- **resultSidecar:** \`${resultSidecar}\``);
|
|
540
579
|
lines.push('');
|
|
541
580
|
|
|
542
581
|
const rb = runbook && typeof runbook === 'object' ? runbook : null;
|
|
@@ -582,7 +621,7 @@ function buildQaValidateContextBlock({ runId, runbook, target, artifactsDir }) {
|
|
|
582
621
|
lines.push('');
|
|
583
622
|
}
|
|
584
623
|
|
|
585
|
-
lines.push(
|
|
624
|
+
lines.push(`Use this context to execute the runbook against the live target. Write the result sidecar to \`${resultSidecar || 'the injected qa_result_sidecar path'}\` before exit — the engine consumes it in \`engine/lifecycle.js\` and calls \`qaRuns.completeRun(runId, ...)\`.`);
|
|
586
625
|
|
|
587
626
|
return lines.join('\n');
|
|
588
627
|
}
|
|
@@ -744,6 +783,80 @@ function renderPlaybook(type, vars) {
|
|
|
744
783
|
}
|
|
745
784
|
}
|
|
746
785
|
|
|
786
|
+
// Reserved deterministic review-lesson recall (P-a6137579). A dedicated
|
|
787
|
+
// project + audience path, independent of the generic memory budget above and
|
|
788
|
+
// gated on its own feature flag. Review-learning records are globally excluded
|
|
789
|
+
// from generic recall, so with recall off (capture-only) the rendered prompt
|
|
790
|
+
// is unchanged with respect to those records. Only dispatches with a resolved
|
|
791
|
+
// project context are eligible; projectless CC / central work get no section.
|
|
792
|
+
if (projectName && features.isFeatureOn('review-learning-recall', configEarly)) {
|
|
793
|
+
try {
|
|
794
|
+
const applicable = memoryRetrieval.retrieveApplicableReviewLearnings({
|
|
795
|
+
title: vars.item_name || vars.pr_title || '',
|
|
796
|
+
description: vars.item_description || vars.task_description || vars.pr_description || '',
|
|
797
|
+
type: vars.work_type || type,
|
|
798
|
+
project: projectName,
|
|
799
|
+
agent: vars.agent_id || '',
|
|
800
|
+
failureClass: vars.failure_class || '',
|
|
801
|
+
sourcePlan: vars.source_plan || '',
|
|
802
|
+
references: vars.references || '',
|
|
803
|
+
prTitle: vars.pr_title || '',
|
|
804
|
+
prBranch: vars.pr_branch || '',
|
|
805
|
+
});
|
|
806
|
+
memoryStore.recordRetrievalRun({
|
|
807
|
+
workItemId: vars.item_id || null,
|
|
808
|
+
dispatchId: vars.task_id || null,
|
|
809
|
+
project: projectName,
|
|
810
|
+
agent: vars.agent_id || null,
|
|
811
|
+
retrievalKind: 'review-learning',
|
|
812
|
+
query: [...applicable.hints.files, ...applicable.hints.symbols, ...applicable.hints.tags].join(' '),
|
|
813
|
+
candidateCount: applicable.candidates.length,
|
|
814
|
+
selectedCount: applicable.selected.length,
|
|
815
|
+
selectedBytes: applicable.bytes,
|
|
816
|
+
durationMs: applicable.durationMs,
|
|
817
|
+
selectedIds: applicable.selectedIds,
|
|
818
|
+
decisionTrace: applicable.decisionTrace,
|
|
819
|
+
});
|
|
820
|
+
// P-bfc75585 — per-lesson `retrieved` lifecycle events. The retrieval run
|
|
821
|
+
// above records the aggregate selection; these events give the per-lesson
|
|
822
|
+
// audit trail that the completion's reviewLearningApplications are matched
|
|
823
|
+
// against. Deterministic event keys (dispatchId + memoryId) keep re-renders
|
|
824
|
+
// idempotent. Best-effort: an audit write must never break prompt render.
|
|
825
|
+
for (const record of applicable.selected || []) {
|
|
826
|
+
if (!record || !record.id) continue;
|
|
827
|
+
try {
|
|
828
|
+
memoryStore.recordMemoryLifecycleEvent({
|
|
829
|
+
eventType: 'retrieved',
|
|
830
|
+
memoryId: record.id,
|
|
831
|
+
findingKey: record.sourceRef || null,
|
|
832
|
+
project: projectName,
|
|
833
|
+
agent: vars.agent_id || null,
|
|
834
|
+
area: record.metadata?.area || 'general',
|
|
835
|
+
disposition: record.metadata?.disposition || null,
|
|
836
|
+
workItemId: vars.item_id || null,
|
|
837
|
+
dispatchId: vars.task_id || null,
|
|
838
|
+
identity: record.id,
|
|
839
|
+
metadata: {
|
|
840
|
+
audience: record.metadata?.audience || 'project-team',
|
|
841
|
+
retrievalKind: 'review-learning',
|
|
842
|
+
},
|
|
843
|
+
});
|
|
844
|
+
} catch (eventErr) {
|
|
845
|
+
log('warn', `Review-learning retrieved-event failed for ${record.id}: ${eventErr.message}`);
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
if (applicable.text) {
|
|
849
|
+
const fenced = wrapUntrusted(
|
|
850
|
+
applicable.text,
|
|
851
|
+
buildSource('review-learning', { item: vars.item_id || vars.task_id || 'unknown' })
|
|
852
|
+
);
|
|
853
|
+
inertAppendices.push('\n\n---\n\n## Applicable Prior Review Lessons (task-selected; verify against live code)\n\n' + (fenced || applicable.text));
|
|
854
|
+
}
|
|
855
|
+
} catch (e) {
|
|
856
|
+
log('warn', `Review-learning recall failed for ${vars.item_id || vars.task_id || type}: ${e.message}`);
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
|
|
747
860
|
// Inject team notes (single injection point — not in buildAgentContext) — capped via ENGINE_DEFAULTS.
|
|
748
861
|
// F5: wrap in <UNTRUSTED-INPUT> fence — notes.md is an LLM-consolidated mix
|
|
749
862
|
// of agent inbox notes (semi-trusted) and human edits.
|
|
@@ -792,19 +905,33 @@ function renderPlaybook(type, vars) {
|
|
|
792
905
|
// there is nothing to conflict with). Bounded discovery (nearest-applicable
|
|
793
906
|
// walk-up, byte-capped) lives in engine/claude-md-context.js. Degrades
|
|
794
907
|
// silently on any error.
|
|
908
|
+
//
|
|
909
|
+
// These resolved facts (runtime, bare mode, propagation flag, and the ACTUAL
|
|
910
|
+
// injected file list) are hoisted so the "Repo harnesses used" PR-body section
|
|
911
|
+
// below reports the same resolved reality the engine actually injected, rather
|
|
912
|
+
// than re-discovering statically (reviewer BLOCKING, PR #898).
|
|
913
|
+
const harnessAgentCfg = configEarly?.agents?.[vars.agent_id] || null;
|
|
914
|
+
const harnessCliName = vars.runtime_cli || shared.resolveAgentCli(harnessAgentCfg, configEarly?.engine);
|
|
915
|
+
const harnessBareMode = shared.resolveAgentBareMode(harnessAgentCfg, configEarly?.engine);
|
|
916
|
+
let harnessClaudeMdCtx = null;
|
|
917
|
+
try { harnessClaudeMdCtx = require('./claude-md-context'); } catch { /* optional */ }
|
|
918
|
+
const runtimeNativeClaudeMd = harnessClaudeMdCtx
|
|
919
|
+
? !!harnessClaudeMdCtx.runtimeAutoDiscoversClaudeMd(harnessCliName) : false;
|
|
920
|
+
const propagateClaudeMd = shared.resolvePropagateClaudeMdForNonClaudeRuntimes(matchedProject, configEarly?.engine);
|
|
921
|
+
let claudeMdInjectedFiles = [];
|
|
795
922
|
try {
|
|
796
|
-
const claudeMdCtx = require('./claude-md-context');
|
|
797
|
-
const cliName = vars.runtime_cli || shared.resolveAgentCli(null, configEarly?.engine);
|
|
798
923
|
const projectRoot = matchedProject?.localPath;
|
|
799
924
|
if (projectRoot
|
|
800
|
-
&&
|
|
801
|
-
&&
|
|
925
|
+
&& harnessClaudeMdCtx
|
|
926
|
+
&& !runtimeNativeClaudeMd
|
|
927
|
+
&& propagateClaudeMd) {
|
|
802
928
|
const pathHints = Array.isArray(vars.claude_md_path_hints) ? vars.claude_md_path_hints : [];
|
|
803
|
-
const { block } =
|
|
929
|
+
const { block, files } = harnessClaudeMdCtx.buildClaudeMdPropagationBlock({
|
|
804
930
|
projectRoot,
|
|
805
931
|
pathHints,
|
|
806
932
|
maxBytes: ENGINE_DEFAULTS.maxNotesPromptBytes,
|
|
807
933
|
});
|
|
934
|
+
claudeMdInjectedFiles = Array.isArray(files) ? files : [];
|
|
808
935
|
if (block) {
|
|
809
936
|
const fenced = wrapUntrusted(block, buildSource('project-instructions', { path: 'CLAUDE.md' }));
|
|
810
937
|
inertAppendices.push(
|
|
@@ -819,6 +946,67 @@ function renderPlaybook(type, vars) {
|
|
|
819
946
|
}
|
|
820
947
|
} catch (e) { log('warn', `CLAUDE.md propagation inject failed: ${e.message}`); }
|
|
821
948
|
|
|
949
|
+
// W-mrtdmtwq000kf391 — surface the repo HARNESS assets in effect for this
|
|
950
|
+
// dispatch (runtime + project) in the Minions-authored PR body. We compute a
|
|
951
|
+
// compact, deterministic inventory from the read-only harness-diagnostics
|
|
952
|
+
// source and instruct the agent to append it (verbatim, fenced) to its PR
|
|
953
|
+
// description. Gated on: the flag (default on), a resolved project, a
|
|
954
|
+
// PR-authoring playbook, and the work item's resolved PR contract — NOT a
|
|
955
|
+
// shared-branch item (those never self-PR) and NOT a `skipPr` item (QA-session
|
|
956
|
+
// SETUP/DRAFT/EXECUTE and any PR-less work). Reporting only — no
|
|
957
|
+
// propagation/attestation (docs/harness-propagation.md).
|
|
958
|
+
//
|
|
959
|
+
// The inventory is derived from the RESOLVED dispatch: the same runtime, bare
|
|
960
|
+
// mode, propagation flag, injected CLAUDE.md files, and dispatch worktree the
|
|
961
|
+
// engine actually used — so the section never over-claims context the runtime
|
|
962
|
+
// never saw (reviewer BLOCKING, PR #898).
|
|
963
|
+
if (matchedProject
|
|
964
|
+
&& !vars.shared_branch
|
|
965
|
+
&& !vars.skip_pr
|
|
966
|
+
&& PR_AUTHORING_PLAYBOOKS.has(type)
|
|
967
|
+
&& (configEarly?.engine?.includeHarnessSectionInPrBody !== false)) {
|
|
968
|
+
try {
|
|
969
|
+
const harnessCtx = require('./harness-context');
|
|
970
|
+
const { inventory, section } = harnessCtx.renderHarnessSectionForDispatch({
|
|
971
|
+
runtimeCli: harnessCliName,
|
|
972
|
+
project: matchedProject,
|
|
973
|
+
worktreePath: vars.worktree_path || '',
|
|
974
|
+
bareMode: harnessBareMode,
|
|
975
|
+
nativeClaudeMd: runtimeNativeClaudeMd,
|
|
976
|
+
claudeMdInjectedFiles,
|
|
977
|
+
propagateClaudeMd,
|
|
978
|
+
pathHints: Array.isArray(vars.claude_md_path_hints) ? vars.claude_md_path_hints : [],
|
|
979
|
+
});
|
|
980
|
+
if (section) {
|
|
981
|
+
// Skills are the one category the engine can't resolve ahead of time —
|
|
982
|
+
// it knows which project skills are AVAILABLE but not which the agent
|
|
983
|
+
// will actually invoke. Hand the available list to the agent as a
|
|
984
|
+
// reference (prompt only, never the PR body) and have it report the
|
|
985
|
+
// subset it actually used. This keeps the block "used, not discovered".
|
|
986
|
+
const availableSkills = Array.isArray(inventory?.availableSkills) ? inventory.availableSkills : [];
|
|
987
|
+
const skillsGuidance = availableSkills.length
|
|
988
|
+
? 'If — and only if — you actually invoked one or more repo skills while doing this '
|
|
989
|
+
+ 'work, add a single `- **Skills used:** <comma-separated names>` line inside the '
|
|
990
|
+
+ 'block (before the end marker), listing ONLY the skills you actually used. Omit '
|
|
991
|
+
+ 'the line entirely if you used none. Do NOT list skills you did not use. The '
|
|
992
|
+
+ 'project skills available to you this dispatch were: '
|
|
993
|
+
+ availableSkills.join(', ') + '.\n\n'
|
|
994
|
+
: '';
|
|
995
|
+
inertAppendices.push(
|
|
996
|
+
'\n\n---\n\n## Repo harnesses — include in your PR body\n\n'
|
|
997
|
+
+ 'When you open or update the PR for this dispatch, append the block below to the PR '
|
|
998
|
+
+ 'description (keep the `' + harnessCtx.HARNESS_BLOCK_START + '` / `'
|
|
999
|
+
+ harnessCtx.HARNESS_BLOCK_END + '` markers). If the PR body already contains a block '
|
|
1000
|
+
+ 'between those markers, replace it in place instead of adding a second copy. The '
|
|
1001
|
+
+ 'engine-resolved lines (runtime, CLAUDE.md, AGENTS.md, MCP) report what was actually '
|
|
1002
|
+
+ 'in effect for this runtime + project — keep them as given.\n\n'
|
|
1003
|
+
+ skillsGuidance
|
|
1004
|
+
+ section,
|
|
1005
|
+
);
|
|
1006
|
+
}
|
|
1007
|
+
} catch (e) { log('warn', `harness PR-section inject failed: ${e.message}`); }
|
|
1008
|
+
}
|
|
1009
|
+
|
|
822
1010
|
// W-mp68q6ke0010de68 — opt-in keep_processes hint. Injected only when the
|
|
823
1011
|
// dispatcher set vars.keep_processes (truthy) from the work item's
|
|
824
1012
|
// `meta.keep_processes`. Built via the keep-process-sweep module so the
|
|
@@ -882,6 +1070,7 @@ function renderPlaybook(type, vars) {
|
|
|
882
1070
|
runbook: vars.qa_runbook,
|
|
883
1071
|
target: vars.qa_target,
|
|
884
1072
|
artifactsDir: vars.qa_artifacts_dir,
|
|
1073
|
+
resultSidecar: vars.qa_result_sidecar,
|
|
885
1074
|
});
|
|
886
1075
|
if (block) inertAppendices.push(block);
|
|
887
1076
|
} catch (e) { log('warn', `qa-validate context render failed: ${e.message}`); }
|
|
@@ -962,7 +1151,7 @@ function renderPlaybook(type, vars) {
|
|
|
962
1151
|
repo_host: repoHost,
|
|
963
1152
|
ado_shared_rules: repoHost === 'ado' ? '1' : '',
|
|
964
1153
|
github_shared_rules: repoHost === 'github' ? '1' : '',
|
|
965
|
-
pr_create_instructions: getPrCreateInstructions(renderProject),
|
|
1154
|
+
pr_create_instructions: getPrCreateInstructions(renderProject, config),
|
|
966
1155
|
pr_comment_instructions: getPrCommentInstructions(renderProject),
|
|
967
1156
|
pr_fetch_instructions: getPrFetchInstructions(renderProject),
|
|
968
1157
|
pr_vote_instructions: getPrVoteInstructions(renderProject, config),
|
|
@@ -1139,7 +1328,7 @@ function buildAgentContext(agentId, config, project) {
|
|
|
1139
1328
|
if (history && history.trim() !== '# Agent History') {
|
|
1140
1329
|
const entries = history.split(/(?=^### )/m);
|
|
1141
1330
|
const header = entries[0].startsWith('#') && !entries[0].startsWith('### ') ? entries.shift() : '';
|
|
1142
|
-
const recent = entries.slice(
|
|
1331
|
+
const recent = entries.slice(0, 5);
|
|
1143
1332
|
const trimmed = (header ? header + '\n' : '') + recent.join('');
|
|
1144
1333
|
context += `## Your Recent History (last 5 tasks)\n\n${trimmed}\n\n`;
|
|
1145
1334
|
}
|
|
@@ -16,8 +16,13 @@
|
|
|
16
16
|
* ACP lease.
|
|
17
17
|
*
|
|
18
18
|
* Output translation (parity, not full fidelity) is adapter-owned through
|
|
19
|
-
* `encodePooledOutput()`. The facade only forwards semantic chunk/result
|
|
19
|
+
* `encodePooledOutput()`. The facade only forwards semantic model/chunk/result
|
|
20
20
|
* events, so a harness can change its JSONL schema without changing this file.
|
|
21
|
+
*
|
|
22
|
+
* Before returning a healthy worker, the facade snapshots and reaps process
|
|
23
|
+
* trees created by this lease while preserving baseline worker/MCP descendants
|
|
24
|
+
* and validated keep_processes anchors. Cleanup uncertainty discards the worker
|
|
25
|
+
* instead of exposing its leftover processes to the next dispatch.
|
|
21
26
|
*/
|
|
22
27
|
|
|
23
28
|
const { EventEmitter } = require('events');
|
package/engine/pr-action.js
CHANGED
|
@@ -278,7 +278,7 @@ function resolvePrActionRequest({ url, action } = {}) {
|
|
|
278
278
|
if (!rawUrl) throw new PrActionError('url required');
|
|
279
279
|
|
|
280
280
|
const ref = prResolve.normalizePrRef(rawUrl);
|
|
281
|
-
if (!ref) throw new PrActionError(
|
|
281
|
+
if (!ref) throw new PrActionError('unrecognized PR reference');
|
|
282
282
|
|
|
283
283
|
return { action: act, ref };
|
|
284
284
|
}
|