diff --git a/scripts/approved_plan_continuity_gate.mjs b/scripts/approved_plan_continuity_gate.mjs index 4b0af65..83b3894 100755 --- a/scripts/approved_plan_continuity_gate.mjs +++ b/scripts/approved_plan_continuity_gate.mjs @@ -1,6 +1,8 @@ #!/usr/bin/env node import fs from 'node:fs'; +const LEGAL_TERMINAL_STATES = new Set(['waiting_user', 'blocked', 'pending_verification']); + function parseArgs(argv) { let inputPath = null; let compact = false; @@ -38,10 +40,12 @@ function readInput(inputPath) { try { const raw = fs.readFileSync(inputPath, 'utf8'); + const parsed = JSON.parse(raw); return { ok: true, bytes: Buffer.byteLength(raw, 'utf8'), preview: raw.slice(0, 0), + parsed, }; } catch (error) { return { @@ -51,17 +55,54 @@ function readInput(inputPath) { } } +function evaluateContinuity(payload) { + const taskComplete = payload?.taskState === 'complete'; + const nextActionKnown = payload?.nextDerivedAction != null; + const hasDispatchReceipt = payload?.dispatchReceipt != null; + const closureState = payload?.replyClosureState ?? null; + const isLegalTerminalState = LEGAL_TERMINAL_STATES.has(closureState); + + if (taskComplete && nextActionKnown && !hasDispatchReceipt && !isLegalTerminalState) { + return { + ok: false, + status: 'continuity_failure', + verdict: 'continuity_failure', + reason: 'missing_dispatch_receipt', + }; + } + + return { + ok: true, + status: 'pass', + verdict: 'pass', + }; +} + const { inputPath, compact } = parseArgs(process.argv.slice(2)); const input = readInput(inputPath); +const evaluation = input.ok ? evaluateContinuity(input.parsed) : { + ok: false, + status: 'input_error', + verdict: 'input_error', +}; const response = { - ok: true, - status: 'placeholder', + ...evaluation, gate: 'approved_plan_continuity', compact, inputPath, - input, - verdict: 'not_implemented', + input: { + ok: input.ok, + ...(input.ok + ? { + bytes: input.bytes, + preview: input.preview, + } + : { + error: input.error, + }), + }, }; -process.stdout.write(`${JSON.stringify(response)}\n`); +process.stdout.write(`${JSON.stringify(response)} +`);