@mestreyoda/fabrica 0.2.34 → 0.2.36
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/dist/index.js +182 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -113905,8 +113905,8 @@ import fsSync from "node:fs";
|
|
|
113905
113905
|
import path5 from "node:path";
|
|
113906
113906
|
import { fileURLToPath as fileURLToPath3 } from "node:url";
|
|
113907
113907
|
function getCurrentVersion() {
|
|
113908
|
-
if ("0.2.
|
|
113909
|
-
return "0.2.
|
|
113908
|
+
if ("0.2.36") {
|
|
113909
|
+
return "0.2.36";
|
|
113910
113910
|
}
|
|
113911
113911
|
try {
|
|
113912
113912
|
const pkgPath = path5.join(THIS_DIR, "..", "..", "package.json");
|
|
@@ -127254,12 +127254,17 @@ function createWorkFinishTool(ctx) {
|
|
|
127254
127254
|
if (role === "tester" && issueRuntime?.infraFailCount) {
|
|
127255
127255
|
await updateIssueRuntime(workspaceDir, project.slug, issueId, { infraFailCount: 0 });
|
|
127256
127256
|
}
|
|
127257
|
-
if (issueRuntime && (issueRuntime.dispatchAttemptCount || issueRuntime.lastFailureReason || issueRuntime.lastDiagnosticResult || issueRuntime.lastDispatchedLevel)) {
|
|
127257
|
+
if (issueRuntime && (issueRuntime.dispatchAttemptCount || issueRuntime.lastFailureReason || issueRuntime.lastDiagnosticResult || issueRuntime.lastDispatchedLevel || issueRuntime.lastConvergenceCause || issueRuntime.lastConvergenceAction || issueRuntime.lastConvergenceRetryCount || issueRuntime.lastConvergenceReason || issueRuntime.lastConvergenceAt)) {
|
|
127258
127258
|
await updateIssueRuntime(workspaceDir, project.slug, issueId, {
|
|
127259
127259
|
dispatchAttemptCount: 0,
|
|
127260
127260
|
lastFailureReason: null,
|
|
127261
127261
|
lastDiagnosticResult: null,
|
|
127262
|
-
lastDispatchedLevel: null
|
|
127262
|
+
lastDispatchedLevel: null,
|
|
127263
|
+
lastConvergenceCause: null,
|
|
127264
|
+
lastConvergenceAction: null,
|
|
127265
|
+
lastConvergenceRetryCount: 0,
|
|
127266
|
+
lastConvergenceReason: null,
|
|
127267
|
+
lastConvergenceAt: null
|
|
127263
127268
|
});
|
|
127264
127269
|
}
|
|
127265
127270
|
return jsonResult({
|
|
@@ -131234,6 +131239,74 @@ init_workflow();
|
|
|
131234
131239
|
init_context3();
|
|
131235
131240
|
init_labels();
|
|
131236
131241
|
|
|
131242
|
+
// lib/services/post-pr-convergence.ts
|
|
131243
|
+
init_types3();
|
|
131244
|
+
function classifyConvergenceCause(reason) {
|
|
131245
|
+
const text = String(reason ?? "").toLowerCase();
|
|
131246
|
+
if (!text) return "other";
|
|
131247
|
+
if (text.includes("qa_gate_missing_") || text.includes("invalid qa evidence")) return "invalid_qa_evidence";
|
|
131248
|
+
if (text.includes("merge conflict") || text.includes("pr_still_conflicting")) return "merge_conflict";
|
|
131249
|
+
if (text.includes("stalled_with_artifact")) return "stalled_with_artifact";
|
|
131250
|
+
if (text.includes("stalled_without_artifact")) return "stalled_without_artifact";
|
|
131251
|
+
if (text.includes("invalid_execution_path")) return "invalid_execution_path";
|
|
131252
|
+
if (text.includes("missing_result_line")) return "missing_result_line";
|
|
131253
|
+
if (text.includes("missing_pr")) return "missing_pr";
|
|
131254
|
+
if (text.includes("no longer targets issue") || text.includes("stale_pr_target")) return "stale_pr_target";
|
|
131255
|
+
if (text.includes("new_pr_required")) return "new_pr_required";
|
|
131256
|
+
if (text.includes("changes requested") || text.includes("review_feedback")) return "review_feedback";
|
|
131257
|
+
if (text.includes("developer_validation_failed")) return "developer_validation_failed";
|
|
131258
|
+
return "other";
|
|
131259
|
+
}
|
|
131260
|
+
function hasReviewableArtifact(issueRuntime) {
|
|
131261
|
+
return Boolean(
|
|
131262
|
+
issueRuntime?.currentPrUrl || issueRuntime?.currentPrNumber || issueRuntime?.artifactOfRecord?.prNumber
|
|
131263
|
+
);
|
|
131264
|
+
}
|
|
131265
|
+
function getConvergenceRetryBudget(cause) {
|
|
131266
|
+
switch (cause) {
|
|
131267
|
+
case "invalid_qa_evidence":
|
|
131268
|
+
return 2;
|
|
131269
|
+
case "merge_conflict":
|
|
131270
|
+
case "stalled_with_artifact":
|
|
131271
|
+
case "stale_pr_target":
|
|
131272
|
+
case "new_pr_required":
|
|
131273
|
+
return 1;
|
|
131274
|
+
case "invalid_execution_path":
|
|
131275
|
+
case "missing_result_line":
|
|
131276
|
+
case "stalled_without_artifact":
|
|
131277
|
+
case "missing_pr":
|
|
131278
|
+
case "review_feedback":
|
|
131279
|
+
case "developer_validation_failed":
|
|
131280
|
+
case "other":
|
|
131281
|
+
default:
|
|
131282
|
+
return 2;
|
|
131283
|
+
}
|
|
131284
|
+
}
|
|
131285
|
+
function getPreferredHoldLabel(workflow) {
|
|
131286
|
+
const holds = Object.values(workflow.states).filter((state) => state.type === StateType.HOLD);
|
|
131287
|
+
if (holds.length === 0) return null;
|
|
131288
|
+
return holds.find((state) => state.label === "Refining")?.label ?? holds[0]?.label ?? null;
|
|
131289
|
+
}
|
|
131290
|
+
function decidePostPrConvergence(params) {
|
|
131291
|
+
const { workflow, issueRuntime, reason, feedbackQueueLabel } = params;
|
|
131292
|
+
const cause = classifyConvergenceCause(reason);
|
|
131293
|
+
const hasArtifact = hasReviewableArtifact(issueRuntime);
|
|
131294
|
+
const previousCause = issueRuntime?.lastConvergenceCause ?? null;
|
|
131295
|
+
const previousCount = issueRuntime?.lastConvergenceRetryCount ?? 0;
|
|
131296
|
+
const retryCount = previousCause === cause ? previousCount + 1 : 1;
|
|
131297
|
+
const maxRetries = getConvergenceRetryBudget(cause);
|
|
131298
|
+
const holdLabel = getPreferredHoldLabel(workflow);
|
|
131299
|
+
const shouldEscalate = hasArtifact && retryCount > maxRetries && Boolean(holdLabel);
|
|
131300
|
+
return {
|
|
131301
|
+
cause,
|
|
131302
|
+
action: shouldEscalate ? "escalate_human" : "retry_feedback",
|
|
131303
|
+
targetLabel: shouldEscalate ? holdLabel ?? feedbackQueueLabel : feedbackQueueLabel,
|
|
131304
|
+
retryCount,
|
|
131305
|
+
maxRetries,
|
|
131306
|
+
hasArtifact
|
|
131307
|
+
};
|
|
131308
|
+
}
|
|
131309
|
+
|
|
131237
131310
|
// lib/services/worker-completion.ts
|
|
131238
131311
|
init_audit();
|
|
131239
131312
|
import fs25 from "node:fs/promises";
|
|
@@ -131669,9 +131742,18 @@ async function defaultValidateDeveloperDone(opts) {
|
|
|
131669
131742
|
);
|
|
131670
131743
|
return { ok: true, prStatus };
|
|
131671
131744
|
} catch (error48) {
|
|
131745
|
+
let prStatus;
|
|
131746
|
+
try {
|
|
131747
|
+
const fallbackPr = await opts.provider.getPrStatus(opts.issueId);
|
|
131748
|
+
if (fallbackPr.url && fallbackPr.state !== "merged" && fallbackPr.state !== "closed") {
|
|
131749
|
+
prStatus = fallbackPr;
|
|
131750
|
+
}
|
|
131751
|
+
} catch {
|
|
131752
|
+
}
|
|
131672
131753
|
return {
|
|
131673
131754
|
ok: false,
|
|
131674
|
-
reason: error48 instanceof Error ? error48.message : "developer_validation_failed"
|
|
131755
|
+
reason: error48 instanceof Error ? error48.message : "developer_validation_failed",
|
|
131756
|
+
prStatus
|
|
131675
131757
|
};
|
|
131676
131758
|
}
|
|
131677
131759
|
}
|
|
@@ -131763,18 +131845,57 @@ async function applyWorkerResult(opts) {
|
|
|
131763
131845
|
if (!validation.ok) {
|
|
131764
131846
|
const validationReason = validation.reason ?? "developer_validation_failed";
|
|
131765
131847
|
const feedbackQueueLabel = getQueueLabels(workflow, "developer").find((label) => isFeedbackState(workflow, label)) ?? "To Improve";
|
|
131848
|
+
const convergenceIssueRuntime = validation.prStatus ? {
|
|
131849
|
+
...context2.issueRuntime,
|
|
131850
|
+
currentPrNumber: validation.prStatus.number ?? context2.issueRuntime?.currentPrNumber ?? null,
|
|
131851
|
+
currentPrUrl: validation.prStatus.url ?? context2.issueRuntime?.currentPrUrl ?? null,
|
|
131852
|
+
currentPrState: validation.prStatus.state ?? context2.issueRuntime?.currentPrState ?? null
|
|
131853
|
+
} : context2.issueRuntime;
|
|
131854
|
+
if (validation.prStatus) {
|
|
131855
|
+
await persistDeveloperPrBinding({
|
|
131856
|
+
workspaceDir: opts.workspaceDir,
|
|
131857
|
+
projectSlug: context2.projectSlug,
|
|
131858
|
+
issueId: context2.issueId,
|
|
131859
|
+
prStatus: validation.prStatus
|
|
131860
|
+
}).catch(() => {
|
|
131861
|
+
});
|
|
131862
|
+
}
|
|
131863
|
+
const convergence = decidePostPrConvergence({
|
|
131864
|
+
workflow,
|
|
131865
|
+
issueRuntime: convergenceIssueRuntime,
|
|
131866
|
+
reason: validationReason,
|
|
131867
|
+
feedbackQueueLabel
|
|
131868
|
+
});
|
|
131869
|
+
const blockedSummary = convergence.action === "escalate_human" ? [
|
|
131870
|
+
"Automatic recovery escalated for human decision.",
|
|
131871
|
+
"",
|
|
131872
|
+
`Dominant cause: ${convergence.cause}`,
|
|
131873
|
+
`Retry budget exceeded: ${convergence.retryCount}/${convergence.maxRetries}`,
|
|
131874
|
+
"",
|
|
131875
|
+
validationReason
|
|
131876
|
+
].join("\n") : `Automatic recovery: developer reported DONE but completion validation failed.
|
|
131877
|
+
|
|
131878
|
+
${validationReason}`;
|
|
131766
131879
|
await log(opts.workspaceDir, "worker_completion_skipped", {
|
|
131767
131880
|
sessionKey: context2.project.workers[context2.parsed.role]?.levels?.[context2.slotLevel]?.[context2.slotIndex]?.sessionKey ?? null,
|
|
131768
131881
|
projectSlug: context2.projectSlug,
|
|
131769
131882
|
issueId: context2.issueId,
|
|
131770
131883
|
role: context2.parsed.role,
|
|
131771
131884
|
result: opts.result.value,
|
|
131772
|
-
reason: validationReason
|
|
131885
|
+
reason: validationReason,
|
|
131886
|
+
convergenceCause: convergence.cause,
|
|
131887
|
+
convergenceAction: convergence.action,
|
|
131888
|
+
convergenceRetryCount: convergence.retryCount
|
|
131773
131889
|
}).catch(() => {
|
|
131774
131890
|
});
|
|
131775
131891
|
await updateIssueRuntime(opts.workspaceDir, context2.projectSlug, context2.issueId, {
|
|
131776
131892
|
inconclusiveCompletionAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
131777
|
-
inconclusiveCompletionReason: validationReason
|
|
131893
|
+
inconclusiveCompletionReason: validationReason,
|
|
131894
|
+
lastConvergenceCause: convergence.cause,
|
|
131895
|
+
lastConvergenceAction: convergence.action,
|
|
131896
|
+
lastConvergenceRetryCount: convergence.retryCount,
|
|
131897
|
+
lastConvergenceReason: validationReason,
|
|
131898
|
+
lastConvergenceAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
131778
131899
|
}).catch(() => {
|
|
131779
131900
|
});
|
|
131780
131901
|
await executeCompletion({
|
|
@@ -131783,9 +131904,7 @@ async function applyWorkerResult(opts) {
|
|
|
131783
131904
|
role: context2.parsed.role,
|
|
131784
131905
|
result: "blocked",
|
|
131785
131906
|
issueId: context2.issueId,
|
|
131786
|
-
summary:
|
|
131787
|
-
|
|
131788
|
-
${validationReason}`,
|
|
131907
|
+
summary: blockedSummary,
|
|
131789
131908
|
provider,
|
|
131790
131909
|
repoPath,
|
|
131791
131910
|
projectName: context2.project.name,
|
|
@@ -131794,7 +131913,7 @@ ${validationReason}`,
|
|
|
131794
131913
|
workflow,
|
|
131795
131914
|
level: context2.slotLevel,
|
|
131796
131915
|
slotIndex: context2.slotIndex,
|
|
131797
|
-
overrideToLabel:
|
|
131916
|
+
overrideToLabel: convergence.targetLabel,
|
|
131798
131917
|
overrideReason: validationReason,
|
|
131799
131918
|
runCommand: opts.runCommand
|
|
131800
131919
|
});
|
|
@@ -131897,13 +132016,23 @@ ${validationReason}`,
|
|
|
131897
132016
|
await updateIssueRuntime(opts.workspaceDir, context2.projectSlug, context2.issueId, {
|
|
131898
132017
|
infraFailCount: 0,
|
|
131899
132018
|
inconclusiveCompletionAt: null,
|
|
131900
|
-
inconclusiveCompletionReason: null
|
|
132019
|
+
inconclusiveCompletionReason: null,
|
|
132020
|
+
lastConvergenceCause: null,
|
|
132021
|
+
lastConvergenceAction: null,
|
|
132022
|
+
lastConvergenceRetryCount: 0,
|
|
132023
|
+
lastConvergenceReason: null,
|
|
132024
|
+
lastConvergenceAt: null
|
|
131901
132025
|
}).catch(() => {
|
|
131902
132026
|
});
|
|
131903
132027
|
} else {
|
|
131904
132028
|
await updateIssueRuntime(opts.workspaceDir, context2.projectSlug, context2.issueId, {
|
|
131905
132029
|
inconclusiveCompletionAt: null,
|
|
131906
|
-
inconclusiveCompletionReason: null
|
|
132030
|
+
inconclusiveCompletionReason: null,
|
|
132031
|
+
lastConvergenceCause: null,
|
|
132032
|
+
lastConvergenceAction: null,
|
|
132033
|
+
lastConvergenceRetryCount: 0,
|
|
132034
|
+
lastConvergenceReason: null,
|
|
132035
|
+
lastConvergenceAt: null
|
|
131907
132036
|
}).catch(() => {
|
|
131908
132037
|
});
|
|
131909
132038
|
}
|
|
@@ -132365,6 +132494,12 @@ async function checkWorkerHealth(opts) {
|
|
|
132365
132494
|
}).catch(() => {
|
|
132366
132495
|
});
|
|
132367
132496
|
}
|
|
132497
|
+
const convergence = decidePostPrConvergence({
|
|
132498
|
+
workflow,
|
|
132499
|
+
issueRuntime,
|
|
132500
|
+
reason: inconclusiveReason,
|
|
132501
|
+
feedbackQueueLabel: slotQueueLabel
|
|
132502
|
+
});
|
|
132368
132503
|
const fix = {
|
|
132369
132504
|
issue: {
|
|
132370
132505
|
type: executionContractRecovery ? "execution_contract_recovery_exhausted" : "completion_recovery_exhausted",
|
|
@@ -132392,8 +132527,8 @@ async function checkWorkerHealth(opts) {
|
|
|
132392
132527
|
issueUrl: issue2.web_url,
|
|
132393
132528
|
issueTitle: issue2.title,
|
|
132394
132529
|
role,
|
|
132395
|
-
detail: executionContractRecovery ? "Execution contract violation did not recover with a canonical completion result" : "No canonical completion result was produced after observable activity",
|
|
132396
|
-
nextState:
|
|
132530
|
+
detail: convergence.action === "escalate_human" ? `Repeated post-PR recovery cause ${convergence.cause} exceeded retry budget (${convergence.retryCount}/${convergence.maxRetries}). Escalating for human decision.` : executionContractRecovery ? "Execution contract violation did not recover with a canonical completion result" : "No canonical completion result was produced after observable activity",
|
|
132531
|
+
nextState: convergence.targetLabel,
|
|
132397
132532
|
dispatchCycleId: slot.dispatchCycleId ?? issueRuntime?.lastDispatchCycleId ?? null,
|
|
132398
132533
|
dispatchRunId: slot.dispatchRunId ?? issueRuntime?.dispatchRunId ?? null
|
|
132399
132534
|
},
|
|
@@ -132410,12 +132545,17 @@ async function checkWorkerHealth(opts) {
|
|
|
132410
132545
|
}
|
|
132411
132546
|
).catch(() => {
|
|
132412
132547
|
});
|
|
132413
|
-
await revertLabel(fix, expectedLabel,
|
|
132548
|
+
await revertLabel(fix, expectedLabel, convergence.targetLabel);
|
|
132414
132549
|
if (!fix.labelRevertFailed) {
|
|
132415
132550
|
await deactivateSlot();
|
|
132416
132551
|
await updateIssueRuntime(workspaceDir, projectSlug, issueIdNum, {
|
|
132417
132552
|
inconclusiveCompletionAt: null,
|
|
132418
|
-
inconclusiveCompletionReason: null
|
|
132553
|
+
inconclusiveCompletionReason: null,
|
|
132554
|
+
lastConvergenceCause: convergence.cause,
|
|
132555
|
+
lastConvergenceAction: convergence.action,
|
|
132556
|
+
lastConvergenceRetryCount: convergence.retryCount,
|
|
132557
|
+
lastConvergenceReason: inconclusiveReason,
|
|
132558
|
+
lastConvergenceAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
132419
132559
|
}).catch(() => {
|
|
132420
132560
|
});
|
|
132421
132561
|
fix.fixed = true;
|
|
@@ -132430,16 +132570,16 @@ async function checkWorkerHealth(opts) {
|
|
|
132430
132570
|
slotIndex,
|
|
132431
132571
|
reason: inconclusiveReason,
|
|
132432
132572
|
fromLabel: expectedLabel,
|
|
132433
|
-
toLabel:
|
|
132573
|
+
toLabel: convergence.targetLabel,
|
|
132434
132574
|
dispatchCycleId: slot.dispatchCycleId ?? issueRuntime?.lastDispatchCycleId ?? null,
|
|
132435
132575
|
dispatchRunId: slot.dispatchRunId ?? issueRuntime?.dispatchRunId ?? null
|
|
132436
132576
|
}).catch(() => {
|
|
132437
132577
|
});
|
|
132438
132578
|
}
|
|
132439
132579
|
await auditHealthFixApplied(workspaceDir, fix, {
|
|
132440
|
-
action: "requeue_issue",
|
|
132580
|
+
action: convergence.action === "escalate_human" ? "escalate_human" : "requeue_issue",
|
|
132441
132581
|
fromLabel: expectedLabel,
|
|
132442
|
-
toLabel:
|
|
132582
|
+
toLabel: convergence.targetLabel,
|
|
132443
132583
|
deliveryState
|
|
132444
132584
|
});
|
|
132445
132585
|
}
|
|
@@ -132619,7 +132759,7 @@ async function checkWorkerHealth(opts) {
|
|
|
132619
132759
|
const minutesActive = (Date.now() - startedAtMs) / 6e4;
|
|
132620
132760
|
const hours = minutesActive / 60;
|
|
132621
132761
|
let reviewablePrStatus = null;
|
|
132622
|
-
let
|
|
132762
|
+
let hasReviewableArtifact2 = Boolean(
|
|
132623
132763
|
issueRuntime?.currentPrNumber || issueRuntime?.currentPrUrl || issueRuntime?.artifactOfRecord?.prNumber
|
|
132624
132764
|
);
|
|
132625
132765
|
if (issueIdNum) {
|
|
@@ -132627,12 +132767,12 @@ async function checkWorkerHealth(opts) {
|
|
|
132627
132767
|
const prStatus = await provider.getPrStatus(issueIdNum);
|
|
132628
132768
|
if (prStatus.url && prStatus.state !== PrState.MERGED && prStatus.state !== PrState.CLOSED && prStatus.currentIssueMatch !== false) {
|
|
132629
132769
|
reviewablePrStatus = prStatus;
|
|
132630
|
-
|
|
132770
|
+
hasReviewableArtifact2 = true;
|
|
132631
132771
|
}
|
|
132632
132772
|
} catch {
|
|
132633
132773
|
}
|
|
132634
132774
|
}
|
|
132635
|
-
if (role === "developer" && issue2 && issueIdNum && !
|
|
132775
|
+
if (role === "developer" && issue2 && issueIdNum && !hasReviewableArtifact2 && minutesActive >= Math.max(5, Math.floor(stallTimeoutMinutes / 2)) && !issueRuntime?.progressNotifiedAt) {
|
|
132636
132776
|
const channel = project.channels?.[0];
|
|
132637
132777
|
await notify(
|
|
132638
132778
|
{
|
|
@@ -132667,7 +132807,7 @@ async function checkWorkerHealth(opts) {
|
|
|
132667
132807
|
}).catch(() => {
|
|
132668
132808
|
});
|
|
132669
132809
|
}
|
|
132670
|
-
if (role === "developer" && issue2 && issueIdNum && !
|
|
132810
|
+
if (role === "developer" && issue2 && issueIdNum && !hasReviewableArtifact2 && minutesActive >= stallTimeoutMinutes) {
|
|
132671
132811
|
const fix = {
|
|
132672
132812
|
issue: {
|
|
132673
132813
|
type: "completion_recovery_exhausted",
|
|
@@ -132737,7 +132877,13 @@ async function checkWorkerHealth(opts) {
|
|
|
132737
132877
|
if (!referenceAt || Number.isNaN(referenceAt)) return minutesActive;
|
|
132738
132878
|
return (Date.now() - referenceAt) / 6e4;
|
|
132739
132879
|
})();
|
|
132740
|
-
if (role === "developer" && issue2 && issueIdNum &&
|
|
132880
|
+
if (role === "developer" && issue2 && issueIdNum && hasReviewableArtifact2 && reviewablePrStatus?.url && minutesActive >= stallTimeoutMinutes && quietMinutes >= Math.max(8, Math.floor(stallTimeoutMinutes / 2))) {
|
|
132881
|
+
const convergence = decidePostPrConvergence({
|
|
132882
|
+
workflow,
|
|
132883
|
+
issueRuntime,
|
|
132884
|
+
reason: "stalled_with_artifact",
|
|
132885
|
+
feedbackQueueLabel: slotQueueLabel
|
|
132886
|
+
});
|
|
132741
132887
|
const fix = {
|
|
132742
132888
|
issue: {
|
|
132743
132889
|
type: "stalled_with_artifact",
|
|
@@ -132763,8 +132909,8 @@ async function checkWorkerHealth(opts) {
|
|
|
132763
132909
|
issueUrl: issue2.web_url,
|
|
132764
132910
|
issueTitle: issue2.title,
|
|
132765
132911
|
role,
|
|
132766
|
-
detail: `Open PR ${reviewablePrStatus.url} has stalled for ${Math.round(quietMinutes)} minutes without a trustworthy completion. Re-queueing to ${slotQueueLabel}.`,
|
|
132767
|
-
nextState:
|
|
132912
|
+
detail: convergence.action === "escalate_human" ? `Open PR ${reviewablePrStatus.url} exceeded the retry budget for ${convergence.cause} (${convergence.retryCount}/${convergence.maxRetries}). Escalating for human decision.` : `Open PR ${reviewablePrStatus.url} has stalled for ${Math.round(quietMinutes)} minutes without a trustworthy completion. Re-queueing to ${slotQueueLabel}.`,
|
|
132913
|
+
nextState: convergence.targetLabel,
|
|
132768
132914
|
dispatchCycleId: slot.dispatchCycleId ?? issueRuntime?.lastDispatchCycleId ?? null,
|
|
132769
132915
|
dispatchRunId: slot.dispatchRunId ?? issueRuntime?.dispatchRunId ?? null
|
|
132770
132916
|
},
|
|
@@ -132781,20 +132927,25 @@ async function checkWorkerHealth(opts) {
|
|
|
132781
132927
|
}
|
|
132782
132928
|
).catch(() => {
|
|
132783
132929
|
});
|
|
132784
|
-
await revertLabel(fix, expectedLabel,
|
|
132930
|
+
await revertLabel(fix, expectedLabel, convergence.targetLabel);
|
|
132785
132931
|
if (!fix.labelRevertFailed) {
|
|
132786
132932
|
await deactivateSlot();
|
|
132787
132933
|
await updateIssueRuntime(workspaceDir, projectSlug, issueIdNum, {
|
|
132788
132934
|
inconclusiveCompletionAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
132789
132935
|
inconclusiveCompletionReason: "stalled_with_artifact",
|
|
132790
|
-
progressNotifiedAt: null
|
|
132936
|
+
progressNotifiedAt: null,
|
|
132937
|
+
lastConvergenceCause: convergence.cause,
|
|
132938
|
+
lastConvergenceAction: convergence.action,
|
|
132939
|
+
lastConvergenceRetryCount: convergence.retryCount,
|
|
132940
|
+
lastConvergenceReason: "stalled_with_artifact",
|
|
132941
|
+
lastConvergenceAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
132791
132942
|
}).catch(() => {
|
|
132792
132943
|
});
|
|
132793
132944
|
fix.fixed = true;
|
|
132794
132945
|
await auditHealthFixApplied(workspaceDir, fix, {
|
|
132795
|
-
action: "requeue_issue",
|
|
132946
|
+
action: convergence.action === "escalate_human" ? "escalate_human" : "requeue_issue",
|
|
132796
132947
|
fromLabel: expectedLabel,
|
|
132797
|
-
toLabel:
|
|
132948
|
+
toLabel: convergence.targetLabel,
|
|
132798
132949
|
idleMinutes: Math.round(quietMinutes),
|
|
132799
132950
|
deliveryState
|
|
132800
132951
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mestreyoda/fabrica",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.36",
|
|
4
4
|
"description": "Autonomous software engineering pipeline for OpenClaw. Turns ideas into deployed code via intake, dispatch, review, test, and merge.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|