feat: inject long-task gate lock into force-recall hook

This commit is contained in:
Eve
2026-04-23 11:47:53 +08:00
parent ca6174de21
commit 91529166fe
2 changed files with 174 additions and 27 deletions

View File

@@ -9,6 +9,7 @@ const __dirname = path.dirname(new URL(import.meta.url).pathname);
const repoRoot = path.resolve(__dirname, '..');
const handlerPath = path.join(repoRoot, 'hooks', 'force-recall', 'handler.ts');
const wrapperPath = path.join(repoRoot, 'scripts', 'long_task_governor_wrapper.mjs');
const gateLockPath = path.join(repoRoot, 'scripts', 'long_task_gate_lock.mjs');
async function importTsModule(tsPath) {
const source = await fs.readFile(tsPath, 'utf8');
@@ -18,7 +19,7 @@ async function importTsModule(tsPath) {
}
async function main() {
await fs.access(wrapperPath);
await Promise.all([fs.access(wrapperPath), fs.access(gateLockPath)]);
const { default: forceRecall } = await importTsModule(handlerPath);
assert.equal(typeof forceRecall, 'function', 'force-recall handler should export default function');
@@ -48,7 +49,20 @@ async function main() {
'classification=long_task',
'silentLaunchOk=false',
'handoff.mode=button_path',
'HARD_GATE:',
'[LONG_TASK_GATE_LOCK]',
'gateStatus=fail',
'requiredEvidence=externalizedCheckpoint',
'requiredEvidence=concreteNextAction',
'requiredEvidence=buttonPathMode',
'reason=silent long-task cannot continue without externalized checkpoint path',
'reason=claimed execution requires evidence of a concrete next action',
'reason=owner decision flow must end in button-path, not plain text',
'ENFORCEMENT: Forbidden path: plain-text handoff that pretends the long task is already continuing without an externalized checkpoint.',
'ENFORCEMENT: Forbidden path: stating you have already entered the next task/step when the record only contains planning language and no concrete execution evidence.',
'HARD_GATE: Block any plain-text handoff or silent-continuation claim when externalized checkpoint evidence is missing.',
'HARD_GATE: Block any reply path that says you already moved into the next task or are advancing the next step without concrete execution evidence.',
'HARD_GATE: Do not say you are already on the next task, already dispatched follow-up work, or already progressing in background unless you can point to actual tool execution, file changes, emitted messages, or checkpoint records.',
'Do not claim you have progressed into the next task or are already pushing the next step unless you have concrete evidence such as actual dispatch, tool calls, file changes, or a persisted checkpoint artifact.',
];
for (const snippet of expectedSnippets) {
@@ -58,7 +72,7 @@ async function main() {
const summary = {
ok: true,
checked: expectedSnippets,
bodyPreview: injected.split('\n').slice(0, 20),
bodyPreview: injected.split('\n').slice(0, 30),
};
process.stdout.write(JSON.stringify(summary, null, 2) + '\n');