#!/usr/bin/env node // Executable receipt for the production abstention policy (issue #32). // // The calibration harness decides GO/BLOCKED for a candidate model. This reads that report and // answers the only question the app cares about: may a suggestion be shipped at all? It exits 3 when // prefill is blocked, so a release step can gate on it instead of reading prose. // // There is no model candidate yet (#31), so in practice this receipt reports BLOCKED today. That is // the honest state: the policy is ready, the evidence is not. import { readFile } from 'node:fs/promises'; import { ABSTENTION_POLICY, evaluatePrefillGate } from '../src/abstention-policy.js'; function parseArgs(argv) { const args = { report: '' }; for (let i = 0; i < argv.length; i += 1) { if (argv[i] === '--report') { args.report = argv[i + 1] || ''; i += 1; } else throw new Error(`unknown argument: ${argv[i]}`); } if (!args.report) throw new Error('--report is required'); return args; } let args; try { args = parseArgs(process.argv.slice(2)); } catch (error) { console.error(error.message); process.exit(2); } let report; try { report = JSON.parse(await readFile(args.report, 'utf8')); } catch (error) { console.error(`could not read the calibration report at ${args.report}: ${error.message}`); process.exit(2); } const gate = evaluatePrefillGate(report); const policy = ABSTENTION_POLICY; console.log('TIMMY ABSTENTION POLICY RECEIPT'); console.log(`policy: version ${policy.version} · confidence ≥ ${policy.minConfidence.toFixed(2)} · quality ${policy.acceptedImageQuality.join('|')}`); console.log(`calibration: verdict ${gate.verdict} · model ${gate.calibrationModel || 'none'}`); console.log(gate.prefillAllowed ? `prefill: AUTHORISED for ${gate.calibrationModel}` : `prefill: BLOCKED — ${gate.blockedBy.join(', ')}`); process.exit(gate.prefillAllowed ? 0 : 3);