@yemi33/minions 0.1.2090 → 0.1.2091
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/engine.js +57 -1
- package/package.json +1 -1
package/engine.js
CHANGED
|
@@ -4816,7 +4816,28 @@ async function discoverFromPrs(config, project) {
|
|
|
4816
4816
|
}
|
|
4817
4817
|
const autoFixBuilds = config.engine?.autoFixBuilds ?? ENGINE_DEFAULTS.autoFixBuilds;
|
|
4818
4818
|
if (pollEnabled && autoFixBuilds && pr.status === PR_STATUS.ACTIVE && pr.buildStatus === 'failing'
|
|
4819
|
+
&& !fixDispatched
|
|
4819
4820
|
&& !isPrNoOpFixCauseSuppressed(pr, shared.PR_FIX_CAUSE.BUILD_FAILURE)) {
|
|
4821
|
+
// W-mpritzcr0004afc5 (#2955): "don't fan out a parallel build-failure
|
|
4822
|
+
// fix while the review-feedback path owns the PR" — implemented via
|
|
4823
|
+
// the `!fixDispatched` gate above (mirrors the merge-conflict block
|
|
4824
|
+
// below). This preserves W-mphnm6a1000281b8 / PR #57 starvation fix:
|
|
4825
|
+
// when the review-feedback dispatch is suppressed by its own cooldown,
|
|
4826
|
+
// `fixDispatched` stays false and the build-fix path still gets to
|
|
4827
|
+
// run. An earlier draft used a bare `reviewStatus === 'changes-requested'`
|
|
4828
|
+
// skip, which broke that starvation guarantee.
|
|
4829
|
+
//
|
|
4830
|
+
// W-mpritzcr0004afc5 (#2955): receive-side cap from lifecycle.js
|
|
4831
|
+
// (`updatePrAfterFix` BUILD_FAILURE branch) flagged this PR as
|
|
4832
|
+
// unrecoverable by auto-retry after `engine.maxBuildFixRetries`
|
|
4833
|
+
// consecutive unverified pushes. Honor the flag here so the dispatcher
|
|
4834
|
+
// stops queuing fix agents — a human must inspect the worktree or
|
|
4835
|
+
// branch protection. Cleared by the same lifecycle path on the next
|
|
4836
|
+
// verified push (lifecycle.js:~2184).
|
|
4837
|
+
if (pr._buildFixNeedsHumanRebase) {
|
|
4838
|
+
log('info', `Skipping build-fix for ${pr.id}: _buildFixNeedsHumanRebase is set — engine reached maxBuildFixRetries, awaiting human rescue`);
|
|
4839
|
+
continue;
|
|
4840
|
+
}
|
|
4820
4841
|
// P-b7e1c4d2: skip when the most recent BUILD-FAILURE dispatch already
|
|
4821
4842
|
// noop'd against the same head SHA — chronic across PRs #2315–#2323
|
|
4822
4843
|
// where every fix agent rebutted "this is a pre-existing master baseline"
|
|
@@ -4907,8 +4928,16 @@ async function discoverFromPrs(config, project) {
|
|
|
4907
4928
|
if (!prBranch) continue;
|
|
4908
4929
|
|
|
4909
4930
|
const reviewNote = [
|
|
4931
|
+
`Cause: ${shared.PR_FIX_CAUSE.BUILD_FAILURE}.`,
|
|
4910
4932
|
`Build is failing: ${pr.buildFailReason || 'check CI pipeline for details'}.`,
|
|
4911
4933
|
'Inspect the live PR checks/build logs yourself, decide the root cause, fix it, run the relevant local validation, and push.',
|
|
4934
|
+
// W-mpritzcr0004afc5 (#2955): the engine-fetched build error log on the
|
|
4935
|
+
// PR record is intentionally not inlined here — the build-error-log
|
|
4936
|
+
// feature regression test in test/unit/build-error-log-feature.test.js
|
|
4937
|
+
// locks the "let the agent inspect live CI" design so the engine does
|
|
4938
|
+
// not have to stay in sync with each CI provider's log format. The
|
|
4939
|
+
// Cause label above plus the build-fail reason is enough to disambiguate
|
|
4940
|
+
// this dispatch from review-feedback / merge-conflict triggers.
|
|
4912
4941
|
pr.url ? `PR URL: ${pr.url}` : '',
|
|
4913
4942
|
].filter(Boolean).join('\n');
|
|
4914
4943
|
|
|
@@ -4949,8 +4978,30 @@ async function discoverFromPrs(config, project) {
|
|
|
4949
4978
|
const autoFixConflicts = config.engine?.autoFixConflicts ?? ENGINE_DEFAULTS.autoFixConflicts;
|
|
4950
4979
|
if (pollEnabled && autoFixConflicts && pr.status === PR_STATUS.ACTIVE && pr._mergeConflict && !fixDispatched
|
|
4951
4980
|
&& !isPrNoOpFixCauseSuppressed(pr, shared.PR_FIX_CAUSE.MERGE_CONFLICT)) {
|
|
4981
|
+
// W-mpritzcr0004afc5 (#2955): "don't fan out a parallel conflict-fix
|
|
4982
|
+
// while the review-feedback path owns the PR" is already handled by
|
|
4983
|
+
// the existing `!fixDispatched` gate above. When review-feedback is
|
|
4984
|
+
// queued in this same iteration, fixDispatched=true and this block
|
|
4985
|
+
// skips. When review-feedback is suppressed by its own cooldown, this
|
|
4986
|
+
// block can still fire — preserving the W-mphnm6a1000281b8 / PR #57
|
|
4987
|
+
// starvation guarantee.
|
|
4952
4988
|
const conflictCauseKey = getPrAutomationCauseKey('merge-conflict', pr);
|
|
4953
4989
|
const key = getPrAutomationDispatchKey(`conflict-fix-${project?.name || 'default'}-${prDisplayId}`, conflictCauseKey);
|
|
4990
|
+
// W-mpritzcr0004afc5 (#2955): per-cause same-head guard mirroring the
|
|
4991
|
+
// build-failure block above. `_conflictFixedAt` is a 10-min wall-clock
|
|
4992
|
+
// suppression for ADO/GH mergeStatus lag; `_lastDispatchByCause` is a
|
|
4993
|
+
// headSha-pinned suppression for repeated agent noops on an unchanged
|
|
4994
|
+
// base+head pair. Both must fire (their windows are independent).
|
|
4995
|
+
const currentHeadSha = String(pr.headSha || pr._adoSourceCommit || pr._adoHeadCommit || '').trim();
|
|
4996
|
+
const lastConflictDispatch = pr._lastDispatchByCause?.[shared.PR_FIX_CAUSE.MERGE_CONFLICT];
|
|
4997
|
+
const skipConflictFix = !!(lastConflictDispatch?.outcome === 'noop'
|
|
4998
|
+
&& lastConflictDispatch.headSha
|
|
4999
|
+
&& currentHeadSha
|
|
5000
|
+
&& lastConflictDispatch.headSha === currentHeadSha);
|
|
5001
|
+
if (skipConflictFix) {
|
|
5002
|
+
log('info', `Skipping conflict-fix for ${pr.id}: last merge-conflict dispatch was noop on the same head ${currentHeadSha.slice(0, 8)} (${(lastConflictDispatch.reason || '').slice(0, 120)})`);
|
|
5003
|
+
continue;
|
|
5004
|
+
}
|
|
4954
5005
|
// Suppress re-dispatch for 10 min after last attempt — ADO/GitHub recomputes
|
|
4955
5006
|
// mergeStatus asynchronously (1–5 min lag), so the flag may stay set even after
|
|
4956
5007
|
// a successful push. _conflictFixedAt is cleared when the poller confirms clean status.
|
|
@@ -4985,9 +5036,14 @@ async function discoverFromPrs(config, project) {
|
|
|
4985
5036
|
if (agentId) {
|
|
4986
5037
|
const prBranch = ensurePrBranchForDispatch(project, pr, 'conflict-fix');
|
|
4987
5038
|
if (!prBranch) continue;
|
|
5039
|
+
const conflictReviewNote = [
|
|
5040
|
+
`Cause: ${shared.PR_FIX_CAUSE.MERGE_CONFLICT}.`,
|
|
5041
|
+
'This PR has merge conflicts with the target branch. Inspect the live PR and repository history, choose the safest merge/rebase/update strategy, resolve all conflicts, validate the result, and push the branch.',
|
|
5042
|
+
pr.url ? `PR URL: ${pr.url}` : '',
|
|
5043
|
+
].filter(Boolean).join('\n');
|
|
4988
5044
|
const item = buildPrDispatch(agentId, config, project, pr, 'fix', {
|
|
4989
5045
|
pr_id: pr.id, pr_branch: prBranch,
|
|
4990
|
-
review_note:
|
|
5046
|
+
review_note: conflictReviewNote,
|
|
4991
5047
|
}, `Fix merge conflicts on ${pr.id}: ${pr.title || ''}`, { dispatchKey: key, cooldownKey: key, automationCauseKey: conflictCauseKey, source: 'pr', pr, branch: prBranch, project: projMeta });
|
|
4992
5048
|
if (item) {
|
|
4993
5049
|
newWork.push(item);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2091",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|