feat: evaluate approved-plan continuity closure
This commit is contained in:
@@ -1,6 +1,8 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
import fs from 'node:fs';
|
import fs from 'node:fs';
|
||||||
|
|
||||||
|
const LEGAL_TERMINAL_STATES = new Set(['waiting_user', 'blocked', 'pending_verification']);
|
||||||
|
|
||||||
function parseArgs(argv) {
|
function parseArgs(argv) {
|
||||||
let inputPath = null;
|
let inputPath = null;
|
||||||
let compact = false;
|
let compact = false;
|
||||||
@@ -38,10 +40,12 @@ function readInput(inputPath) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const raw = fs.readFileSync(inputPath, 'utf8');
|
const raw = fs.readFileSync(inputPath, 'utf8');
|
||||||
|
const parsed = JSON.parse(raw);
|
||||||
return {
|
return {
|
||||||
ok: true,
|
ok: true,
|
||||||
bytes: Buffer.byteLength(raw, 'utf8'),
|
bytes: Buffer.byteLength(raw, 'utf8'),
|
||||||
preview: raw.slice(0, 0),
|
preview: raw.slice(0, 0),
|
||||||
|
parsed,
|
||||||
};
|
};
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return {
|
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 { inputPath, compact } = parseArgs(process.argv.slice(2));
|
||||||
const input = readInput(inputPath);
|
const input = readInput(inputPath);
|
||||||
|
const evaluation = input.ok ? evaluateContinuity(input.parsed) : {
|
||||||
|
ok: false,
|
||||||
|
status: 'input_error',
|
||||||
|
verdict: 'input_error',
|
||||||
|
};
|
||||||
|
|
||||||
const response = {
|
const response = {
|
||||||
ok: true,
|
...evaluation,
|
||||||
status: 'placeholder',
|
|
||||||
gate: 'approved_plan_continuity',
|
gate: 'approved_plan_continuity',
|
||||||
compact,
|
compact,
|
||||||
inputPath,
|
inputPath,
|
||||||
input,
|
input: {
|
||||||
verdict: 'not_implemented',
|
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)}
|
||||||
|
`);
|
||||||
|
|||||||
Reference in New Issue
Block a user