@mestreyoda/fabrica 0.2.33 → 0.2.35
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 +227 -26
- 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.35") {
|
|
113909
|
+
return "0.2.35";
|
|
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";
|
|
@@ -131763,18 +131836,42 @@ async function applyWorkerResult(opts) {
|
|
|
131763
131836
|
if (!validation.ok) {
|
|
131764
131837
|
const validationReason = validation.reason ?? "developer_validation_failed";
|
|
131765
131838
|
const feedbackQueueLabel = getQueueLabels(workflow, "developer").find((label) => isFeedbackState(workflow, label)) ?? "To Improve";
|
|
131839
|
+
const convergence = decidePostPrConvergence({
|
|
131840
|
+
workflow,
|
|
131841
|
+
issueRuntime: context2.issueRuntime,
|
|
131842
|
+
reason: validationReason,
|
|
131843
|
+
feedbackQueueLabel
|
|
131844
|
+
});
|
|
131845
|
+
const blockedSummary = convergence.action === "escalate_human" ? [
|
|
131846
|
+
"Automatic recovery escalated for human decision.",
|
|
131847
|
+
"",
|
|
131848
|
+
`Dominant cause: ${convergence.cause}`,
|
|
131849
|
+
`Retry budget exceeded: ${convergence.retryCount}/${convergence.maxRetries}`,
|
|
131850
|
+
"",
|
|
131851
|
+
validationReason
|
|
131852
|
+
].join("\n") : `Automatic recovery: developer reported DONE but completion validation failed.
|
|
131853
|
+
|
|
131854
|
+
${validationReason}`;
|
|
131766
131855
|
await log(opts.workspaceDir, "worker_completion_skipped", {
|
|
131767
131856
|
sessionKey: context2.project.workers[context2.parsed.role]?.levels?.[context2.slotLevel]?.[context2.slotIndex]?.sessionKey ?? null,
|
|
131768
131857
|
projectSlug: context2.projectSlug,
|
|
131769
131858
|
issueId: context2.issueId,
|
|
131770
131859
|
role: context2.parsed.role,
|
|
131771
131860
|
result: opts.result.value,
|
|
131772
|
-
reason: validationReason
|
|
131861
|
+
reason: validationReason,
|
|
131862
|
+
convergenceCause: convergence.cause,
|
|
131863
|
+
convergenceAction: convergence.action,
|
|
131864
|
+
convergenceRetryCount: convergence.retryCount
|
|
131773
131865
|
}).catch(() => {
|
|
131774
131866
|
});
|
|
131775
131867
|
await updateIssueRuntime(opts.workspaceDir, context2.projectSlug, context2.issueId, {
|
|
131776
131868
|
inconclusiveCompletionAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
131777
|
-
inconclusiveCompletionReason: validationReason
|
|
131869
|
+
inconclusiveCompletionReason: validationReason,
|
|
131870
|
+
lastConvergenceCause: convergence.cause,
|
|
131871
|
+
lastConvergenceAction: convergence.action,
|
|
131872
|
+
lastConvergenceRetryCount: convergence.retryCount,
|
|
131873
|
+
lastConvergenceReason: validationReason,
|
|
131874
|
+
lastConvergenceAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
131778
131875
|
}).catch(() => {
|
|
131779
131876
|
});
|
|
131780
131877
|
await executeCompletion({
|
|
@@ -131783,9 +131880,7 @@ async function applyWorkerResult(opts) {
|
|
|
131783
131880
|
role: context2.parsed.role,
|
|
131784
131881
|
result: "blocked",
|
|
131785
131882
|
issueId: context2.issueId,
|
|
131786
|
-
summary:
|
|
131787
|
-
|
|
131788
|
-
${validationReason}`,
|
|
131883
|
+
summary: blockedSummary,
|
|
131789
131884
|
provider,
|
|
131790
131885
|
repoPath,
|
|
131791
131886
|
projectName: context2.project.name,
|
|
@@ -131794,7 +131889,7 @@ ${validationReason}`,
|
|
|
131794
131889
|
workflow,
|
|
131795
131890
|
level: context2.slotLevel,
|
|
131796
131891
|
slotIndex: context2.slotIndex,
|
|
131797
|
-
overrideToLabel:
|
|
131892
|
+
overrideToLabel: convergence.targetLabel,
|
|
131798
131893
|
overrideReason: validationReason,
|
|
131799
131894
|
runCommand: opts.runCommand
|
|
131800
131895
|
});
|
|
@@ -131897,13 +131992,23 @@ ${validationReason}`,
|
|
|
131897
131992
|
await updateIssueRuntime(opts.workspaceDir, context2.projectSlug, context2.issueId, {
|
|
131898
131993
|
infraFailCount: 0,
|
|
131899
131994
|
inconclusiveCompletionAt: null,
|
|
131900
|
-
inconclusiveCompletionReason: null
|
|
131995
|
+
inconclusiveCompletionReason: null,
|
|
131996
|
+
lastConvergenceCause: null,
|
|
131997
|
+
lastConvergenceAction: null,
|
|
131998
|
+
lastConvergenceRetryCount: 0,
|
|
131999
|
+
lastConvergenceReason: null,
|
|
132000
|
+
lastConvergenceAt: null
|
|
131901
132001
|
}).catch(() => {
|
|
131902
132002
|
});
|
|
131903
132003
|
} else {
|
|
131904
132004
|
await updateIssueRuntime(opts.workspaceDir, context2.projectSlug, context2.issueId, {
|
|
131905
132005
|
inconclusiveCompletionAt: null,
|
|
131906
|
-
inconclusiveCompletionReason: null
|
|
132006
|
+
inconclusiveCompletionReason: null,
|
|
132007
|
+
lastConvergenceCause: null,
|
|
132008
|
+
lastConvergenceAction: null,
|
|
132009
|
+
lastConvergenceRetryCount: 0,
|
|
132010
|
+
lastConvergenceReason: null,
|
|
132011
|
+
lastConvergenceAt: null
|
|
131907
132012
|
}).catch(() => {
|
|
131908
132013
|
});
|
|
131909
132014
|
}
|
|
@@ -132365,6 +132470,12 @@ async function checkWorkerHealth(opts) {
|
|
|
132365
132470
|
}).catch(() => {
|
|
132366
132471
|
});
|
|
132367
132472
|
}
|
|
132473
|
+
const convergence = decidePostPrConvergence({
|
|
132474
|
+
workflow,
|
|
132475
|
+
issueRuntime,
|
|
132476
|
+
reason: inconclusiveReason,
|
|
132477
|
+
feedbackQueueLabel: slotQueueLabel
|
|
132478
|
+
});
|
|
132368
132479
|
const fix = {
|
|
132369
132480
|
issue: {
|
|
132370
132481
|
type: executionContractRecovery ? "execution_contract_recovery_exhausted" : "completion_recovery_exhausted",
|
|
@@ -132392,8 +132503,8 @@ async function checkWorkerHealth(opts) {
|
|
|
132392
132503
|
issueUrl: issue2.web_url,
|
|
132393
132504
|
issueTitle: issue2.title,
|
|
132394
132505
|
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:
|
|
132506
|
+
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",
|
|
132507
|
+
nextState: convergence.targetLabel,
|
|
132397
132508
|
dispatchCycleId: slot.dispatchCycleId ?? issueRuntime?.lastDispatchCycleId ?? null,
|
|
132398
132509
|
dispatchRunId: slot.dispatchRunId ?? issueRuntime?.dispatchRunId ?? null
|
|
132399
132510
|
},
|
|
@@ -132410,12 +132521,17 @@ async function checkWorkerHealth(opts) {
|
|
|
132410
132521
|
}
|
|
132411
132522
|
).catch(() => {
|
|
132412
132523
|
});
|
|
132413
|
-
await revertLabel(fix, expectedLabel,
|
|
132524
|
+
await revertLabel(fix, expectedLabel, convergence.targetLabel);
|
|
132414
132525
|
if (!fix.labelRevertFailed) {
|
|
132415
132526
|
await deactivateSlot();
|
|
132416
132527
|
await updateIssueRuntime(workspaceDir, projectSlug, issueIdNum, {
|
|
132417
132528
|
inconclusiveCompletionAt: null,
|
|
132418
|
-
inconclusiveCompletionReason: null
|
|
132529
|
+
inconclusiveCompletionReason: null,
|
|
132530
|
+
lastConvergenceCause: convergence.cause,
|
|
132531
|
+
lastConvergenceAction: convergence.action,
|
|
132532
|
+
lastConvergenceRetryCount: convergence.retryCount,
|
|
132533
|
+
lastConvergenceReason: inconclusiveReason,
|
|
132534
|
+
lastConvergenceAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
132419
132535
|
}).catch(() => {
|
|
132420
132536
|
});
|
|
132421
132537
|
fix.fixed = true;
|
|
@@ -132430,16 +132546,16 @@ async function checkWorkerHealth(opts) {
|
|
|
132430
132546
|
slotIndex,
|
|
132431
132547
|
reason: inconclusiveReason,
|
|
132432
132548
|
fromLabel: expectedLabel,
|
|
132433
|
-
toLabel:
|
|
132549
|
+
toLabel: convergence.targetLabel,
|
|
132434
132550
|
dispatchCycleId: slot.dispatchCycleId ?? issueRuntime?.lastDispatchCycleId ?? null,
|
|
132435
132551
|
dispatchRunId: slot.dispatchRunId ?? issueRuntime?.dispatchRunId ?? null
|
|
132436
132552
|
}).catch(() => {
|
|
132437
132553
|
});
|
|
132438
132554
|
}
|
|
132439
132555
|
await auditHealthFixApplied(workspaceDir, fix, {
|
|
132440
|
-
action: "requeue_issue",
|
|
132556
|
+
action: convergence.action === "escalate_human" ? "escalate_human" : "requeue_issue",
|
|
132441
132557
|
fromLabel: expectedLabel,
|
|
132442
|
-
toLabel:
|
|
132558
|
+
toLabel: convergence.targetLabel,
|
|
132443
132559
|
deliveryState
|
|
132444
132560
|
});
|
|
132445
132561
|
}
|
|
@@ -132618,19 +132734,21 @@ async function checkWorkerHealth(opts) {
|
|
|
132618
132734
|
const startedAtMs = new Date(slot.startTime).getTime();
|
|
132619
132735
|
const minutesActive = (Date.now() - startedAtMs) / 6e4;
|
|
132620
132736
|
const hours = minutesActive / 60;
|
|
132621
|
-
let
|
|
132737
|
+
let reviewablePrStatus = null;
|
|
132738
|
+
let hasReviewableArtifact2 = Boolean(
|
|
132622
132739
|
issueRuntime?.currentPrNumber || issueRuntime?.currentPrUrl || issueRuntime?.artifactOfRecord?.prNumber
|
|
132623
132740
|
);
|
|
132624
|
-
if (
|
|
132741
|
+
if (issueIdNum) {
|
|
132625
132742
|
try {
|
|
132626
132743
|
const prStatus = await provider.getPrStatus(issueIdNum);
|
|
132627
|
-
|
|
132628
|
-
|
|
132629
|
-
|
|
132744
|
+
if (prStatus.url && prStatus.state !== PrState.MERGED && prStatus.state !== PrState.CLOSED && prStatus.currentIssueMatch !== false) {
|
|
132745
|
+
reviewablePrStatus = prStatus;
|
|
132746
|
+
hasReviewableArtifact2 = true;
|
|
132747
|
+
}
|
|
132630
132748
|
} catch {
|
|
132631
132749
|
}
|
|
132632
132750
|
}
|
|
132633
|
-
if (role === "developer" && issue2 && issueIdNum && !
|
|
132751
|
+
if (role === "developer" && issue2 && issueIdNum && !hasReviewableArtifact2 && minutesActive >= Math.max(5, Math.floor(stallTimeoutMinutes / 2)) && !issueRuntime?.progressNotifiedAt) {
|
|
132634
132752
|
const channel = project.channels?.[0];
|
|
132635
132753
|
await notify(
|
|
132636
132754
|
{
|
|
@@ -132665,7 +132783,7 @@ async function checkWorkerHealth(opts) {
|
|
|
132665
132783
|
}).catch(() => {
|
|
132666
132784
|
});
|
|
132667
132785
|
}
|
|
132668
|
-
if (role === "developer" && issue2 && issueIdNum && !
|
|
132786
|
+
if (role === "developer" && issue2 && issueIdNum && !hasReviewableArtifact2 && minutesActive >= stallTimeoutMinutes) {
|
|
132669
132787
|
const fix = {
|
|
132670
132788
|
issue: {
|
|
132671
132789
|
type: "completion_recovery_exhausted",
|
|
@@ -132729,6 +132847,89 @@ async function checkWorkerHealth(opts) {
|
|
|
132729
132847
|
fixes.push(fix);
|
|
132730
132848
|
continue;
|
|
132731
132849
|
}
|
|
132850
|
+
const quietMinutes = (() => {
|
|
132851
|
+
const lastObservableAt = sessionKey ? getLastObservableSessionActivityAt(sessionKey, sessions) : null;
|
|
132852
|
+
const referenceAt = lastObservableAt ?? agentAcceptedAt ?? dispatchRequestedAt ?? startedAtMs;
|
|
132853
|
+
if (!referenceAt || Number.isNaN(referenceAt)) return minutesActive;
|
|
132854
|
+
return (Date.now() - referenceAt) / 6e4;
|
|
132855
|
+
})();
|
|
132856
|
+
if (role === "developer" && issue2 && issueIdNum && hasReviewableArtifact2 && reviewablePrStatus?.url && minutesActive >= stallTimeoutMinutes && quietMinutes >= Math.max(8, Math.floor(stallTimeoutMinutes / 2))) {
|
|
132857
|
+
const convergence = decidePostPrConvergence({
|
|
132858
|
+
workflow,
|
|
132859
|
+
issueRuntime,
|
|
132860
|
+
reason: "stalled_with_artifact",
|
|
132861
|
+
feedbackQueueLabel: slotQueueLabel
|
|
132862
|
+
});
|
|
132863
|
+
const fix = {
|
|
132864
|
+
issue: {
|
|
132865
|
+
type: "stalled_with_artifact",
|
|
132866
|
+
severity: "critical",
|
|
132867
|
+
project: project.name,
|
|
132868
|
+
projectSlug,
|
|
132869
|
+
role,
|
|
132870
|
+
level,
|
|
132871
|
+
sessionKey,
|
|
132872
|
+
issueId: slot.issueId,
|
|
132873
|
+
slotIndex,
|
|
132874
|
+
message: `${role.toUpperCase()} ${level}[${slotIndex}] has an open PR but stayed idle for ${Math.round(quietMinutes)}m without converging`
|
|
132875
|
+
},
|
|
132876
|
+
fixed: false
|
|
132877
|
+
};
|
|
132878
|
+
if (autoFix) {
|
|
132879
|
+
const channel = project.channels?.[0];
|
|
132880
|
+
await notify(
|
|
132881
|
+
{
|
|
132882
|
+
type: "workerRecoveryExhausted",
|
|
132883
|
+
project: project.name,
|
|
132884
|
+
issueId: issueIdNum,
|
|
132885
|
+
issueUrl: issue2.web_url,
|
|
132886
|
+
issueTitle: issue2.title,
|
|
132887
|
+
role,
|
|
132888
|
+
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}.`,
|
|
132889
|
+
nextState: convergence.targetLabel,
|
|
132890
|
+
dispatchCycleId: slot.dispatchCycleId ?? issueRuntime?.lastDispatchCycleId ?? null,
|
|
132891
|
+
dispatchRunId: slot.dispatchRunId ?? issueRuntime?.dispatchRunId ?? null
|
|
132892
|
+
},
|
|
132893
|
+
{
|
|
132894
|
+
workspaceDir,
|
|
132895
|
+
config: notificationConfig,
|
|
132896
|
+
target: channel ? {
|
|
132897
|
+
channelId: channel.channelId,
|
|
132898
|
+
channel: channel.channel,
|
|
132899
|
+
accountId: channel.accountId,
|
|
132900
|
+
messageThreadId: channel.messageThreadId
|
|
132901
|
+
} : void 0,
|
|
132902
|
+
runCommand
|
|
132903
|
+
}
|
|
132904
|
+
).catch(() => {
|
|
132905
|
+
});
|
|
132906
|
+
await revertLabel(fix, expectedLabel, convergence.targetLabel);
|
|
132907
|
+
if (!fix.labelRevertFailed) {
|
|
132908
|
+
await deactivateSlot();
|
|
132909
|
+
await updateIssueRuntime(workspaceDir, projectSlug, issueIdNum, {
|
|
132910
|
+
inconclusiveCompletionAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
132911
|
+
inconclusiveCompletionReason: "stalled_with_artifact",
|
|
132912
|
+
progressNotifiedAt: null,
|
|
132913
|
+
lastConvergenceCause: convergence.cause,
|
|
132914
|
+
lastConvergenceAction: convergence.action,
|
|
132915
|
+
lastConvergenceRetryCount: convergence.retryCount,
|
|
132916
|
+
lastConvergenceReason: "stalled_with_artifact",
|
|
132917
|
+
lastConvergenceAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
132918
|
+
}).catch(() => {
|
|
132919
|
+
});
|
|
132920
|
+
fix.fixed = true;
|
|
132921
|
+
await auditHealthFixApplied(workspaceDir, fix, {
|
|
132922
|
+
action: convergence.action === "escalate_human" ? "escalate_human" : "requeue_issue",
|
|
132923
|
+
fromLabel: expectedLabel,
|
|
132924
|
+
toLabel: convergence.targetLabel,
|
|
132925
|
+
idleMinutes: Math.round(quietMinutes),
|
|
132926
|
+
deliveryState
|
|
132927
|
+
});
|
|
132928
|
+
}
|
|
132929
|
+
}
|
|
132930
|
+
fixes.push(fix);
|
|
132931
|
+
continue;
|
|
132932
|
+
}
|
|
132732
132933
|
if (hours > staleWorkerHours) {
|
|
132733
132934
|
const fix = {
|
|
132734
132935
|
issue: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mestreyoda/fabrica",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.35",
|
|
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",
|