feat: harden auto-next continuity receipt linkage

This commit is contained in:
Eve
2026-04-24 16:38:36 +08:00
parent 8e290a4d9b
commit 82d0d94b5f
6 changed files with 242 additions and 741 deletions

View File

@@ -11,6 +11,10 @@ function isObject(value) {
return value != null && typeof value === 'object' && !Array.isArray(value);
}
function normalizeAction(action) {
return JSON.stringify(action ?? null);
}
function hasValidDispatchReceipt(receipt) {
if (!isObject(receipt)) return false;
if (!isNonEmptyString(receipt.planId)) return false;
@@ -20,6 +24,27 @@ function hasValidDispatchReceipt(receipt) {
return true;
}
function receiptMatchesPayload(payload, receipt) {
if (!hasValidDispatchReceipt(receipt)) return false;
const expectedPlanId = payload?.planId;
if (isNonEmptyString(expectedPlanId) && receipt.planId !== expectedPlanId) return false;
const expectedCurrentTask = payload?.currentTask;
if (isNonEmptyString(expectedCurrentTask) && receipt.currentTask !== expectedCurrentTask) return false;
const expectedNextTask = payload?.nextTaskId ?? payload?.nextTaskKey ?? null;
const receiptNextTask = receipt?.nextTaskId ?? receipt?.nextTaskKey ?? null;
if (isNonEmptyString(expectedNextTask) && receiptNextTask !== expectedNextTask) return false;
const expectedNextAction = payload?.nextDerivedAction ?? payload?.derivedAction ?? null;
if (expectedNextAction != null && normalizeAction(receipt.nextDerivedAction) !== normalizeAction(expectedNextAction)) {
return false;
}
return true;
}
function parseArgs(argv) {
let inputPath = null;
let compact = false;
@@ -80,9 +105,9 @@ function evaluateContinuity(payload) {
const sameApprovedPlan = payload?.sameApprovedPlan === true;
const taskBoundaryStop = payload?.taskBoundaryStop === true;
const highRiskStop = payload?.highRiskStop === true;
const hasDispatchReceipt = hasValidDispatchReceipt(payload?.dispatchReceipt ?? null);
const closureState = payload?.replyClosureState ?? null;
const isLegalTerminalState = LEGAL_TERMINAL_STATES.has(closureState);
const hasDispatchReceipt = receiptMatchesPayload(payload, payload?.dispatchReceipt ?? null);
const autoNextObligatory = taskComplete
&& explicitNextTaskKnown
&& sameApprovedPlan
@@ -150,5 +175,4 @@ const response = {
},
};
process.stdout.write(`${JSON.stringify(response)}
`);
process.stdout.write(`${JSON.stringify(response)}\n`);