fix(web): preserve batch contract on scheduler failures
This commit is contained in:
@@ -219,6 +219,15 @@ function sourceMappingReadiness(pointer) {
|
|||||||
const card = read(cardPath);
|
const card = read(cardPath);
|
||||||
const implementation = card.match(/- Implementation entrypoint: `([^`]+)`/u)?.[1];
|
const implementation = card.match(/- Implementation entrypoint: `([^`]+)`/u)?.[1];
|
||||||
if (!implementation) return { ok: false, reason: "implementation_entrypoint_missing", taskClass };
|
if (!implementation) return { ok: false, reason: "implementation_entrypoint_missing", taskClass };
|
||||||
|
if (/targetImplementationClass:\s*LOCAL_EXACT/u.test(card)) {
|
||||||
|
const batchId = card.match(/^- batchId:\s*`?([^`\n]+)`?/mu)?.[1];
|
||||||
|
const selected = card.match(/^- selectedRecordIds:\s*(\[[^\n]+\])/mu)?.[1];
|
||||||
|
if (!batchId || !selected) return { ok: false, reason: "batch_contract_missing", taskClass };
|
||||||
|
try {
|
||||||
|
const selectedRecordIds = JSON.parse(selected);
|
||||||
|
if (!Array.isArray(selectedRecordIds) || selectedRecordIds.length === 0) return { ok: false, reason: "batch_selection_missing", taskClass };
|
||||||
|
} catch { return { ok: false, reason: "batch_selection_invalid", taskClass }; }
|
||||||
|
}
|
||||||
|
|
||||||
// Continuation source tasks must have an explicit, non-generic phase mapping.
|
// Continuation source tasks must have an explicit, non-generic phase mapping.
|
||||||
// This prevents a long-running loop from replaying an older marker forever.
|
// This prevents a long-running loop from replaying an older marker forever.
|
||||||
|
|||||||
@@ -81,10 +81,12 @@ const stopOnFatal = (error, source) => {
|
|||||||
if (fatalHandled) return;
|
if (fatalHandled) return;
|
||||||
fatalHandled = true;
|
fatalHandled = true;
|
||||||
try {
|
try {
|
||||||
|
failureLedger.record({ task: currentTask()?.task ?? "UNKNOWN", phase: "supervisor", reason: source, detail: error?.message ?? String(error) });
|
||||||
writeCheckpoint({ state: "blocked", iteration, reason: source, error: error?.message ?? String(error) });
|
writeCheckpoint({ state: "blocked", iteration, reason: source, error: error?.message ?? String(error) });
|
||||||
appendLog(`blocked reason=${source} error=${error?.message ?? String(error)}`);
|
appendLog(`blocked reason=${source} error=${error?.message ?? String(error)}`);
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
|
failureLedger.flush();
|
||||||
releaseLock();
|
releaseLock();
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user