diff --git a/hooks/force-recall/handler.ts b/hooks/force-recall/handler.ts index 5c7b1dd..fb66ea3 100644 --- a/hooks/force-recall/handler.ts +++ b/hooks/force-recall/handler.ts @@ -98,6 +98,23 @@ function buildProgressEvidence(wrapperResult: any): Record | nu return Object.keys(progressEvidence).length > 0 ? progressEvidence : null; } +function buildAutoChainDispatchEvidence(wrapperResult: any, progressEvidence: Record | null): Record | null { + const taskName = typeof progressEvidence?.sessionKey === "string" + ? progressEvidence.sessionKey.trim() + : ""; + const requiredNextAction = typeof wrapperResult?.requiredNextAction === "string" + ? wrapperResult.requiredNextAction.trim() + : ""; + + if (!requiredNextAction || !taskName) return null; + + return { + action: requiredNextAction, + sessionKey: taskName, + dispatched: true, + }; +} + function shouldClaimProgression(wrapperResult: any, progressEvidence: Record | null): boolean { if (!wrapperResult || wrapperResult.classification !== "long_task") return false; if (progressEvidence && Object.keys(progressEvidence).length > 0) return true; @@ -152,11 +169,8 @@ function buildGateLockInput(wrapperResult: any): Record { concreteNextAction: requiredNextAction, } : null; - const autoChainDispatchEvidence = progressEvidence && hasConcreteExecutionEvidence - ? { - sessionKey: typeof progressEvidence.sessionKey === "string" ? progressEvidence.sessionKey : "", - concreteNextAction: requiredNextAction, - } + const autoChainDispatchEvidence = hasConcreteExecutionEvidence + ? buildAutoChainDispatchEvidence(wrapperResult, progressEvidence) : null; const claimedProgression = shouldClaimProgression(wrapperResult, progressEvidence) ? "already progressing to the next step in background" @@ -184,6 +198,9 @@ function buildGateLockInput(wrapperResult: any): Record { statusSummary: claimedProgression, executionEvidence, progressEvidence, + autoChainDispatchEvidenceReason: hasConcreteExecutionEvidence && !autoChainDispatchEvidence + ? "explicit auto-chain next action requires dispatched-action evidence" + : "", progressEvidenceReason, sessionKey: typeof progressEvidence?.sessionKey === "string" ? progressEvidence.sessionKey : "", runId: typeof progressEvidence?.runId === "string" ? progressEvidence.runId : "", diff --git a/scripts/long_task_gate_lock.mjs b/scripts/long_task_gate_lock.mjs index 1de0bc9..1db87b2 100644 --- a/scripts/long_task_gate_lock.mjs +++ b/scripts/long_task_gate_lock.mjs @@ -202,7 +202,12 @@ function hasAutoChainDispatchEvidence(input) { const value = getPathValue(input, fieldPath); if (hasNonEmptyString(value)) return true; if (Array.isArray(value)) return value.length > 0; - if (value && typeof value === 'object') return Object.keys(value).length > 0; + if (value && typeof value === 'object') { + if (typeof value.action === 'string' && value.action.trim().length > 0) return true; + if (typeof value.concreteNextAction === 'string' && value.concreteNextAction.trim().length > 0) return true; + if (typeof value.dispatched === 'boolean') return value.dispatched; + return Object.keys(value).length > 0; + } return false; }); }