fix(harness): close the Pi-crash class — top-level try/catch on ALL gate tools

Audit finding 1.1 (high): reviewer_memory_promote, rewrite_question,
write_schema_linking, write_cte_sql and write_final_sql still ran execute
without a top-level catch — the same unhandled-rejection class that killed
Pi in reviewer_schema_linking (fixed in 87cb806 for the four reviewer_*
tools). All 9 registered tools now share the pattern: any uncaught throw
becomes a textResult the model can react to.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-20 01:26:27 +02:00
co-authored by Claude Fable 5
parent 803b98de36
commit 075883370e
+25
View File
@@ -1339,6 +1339,7 @@ export default function (pi) {
}),
async execute(_id, params, _signal, _onUpdate, ctx) {
lockActive = true;
try {
const { session } = params;
const curNum = currentPhase(ctx, session);
const phase = phaseId(ctx, curNum);
@@ -1410,6 +1411,10 @@ export default function (pi) {
const closed = closeAfterPromotion(ctx, session, curNum, summary);
if (closed) return closed;
return textResult(summary);
} catch (fatal) {
const msg = (fatal.stderr || fatal.message || String(fatal)).toString().trim();
return textResult(`[reviewer_memory_promote ERRORE INTERNO] ${msg}. Riprova o usa un approccio diverso.`);
}
},
});
@@ -1427,6 +1432,7 @@ export default function (pi) {
}),
async execute(_id, params, _signal, _onUpdate, ctx) {
lockActive = true;
try {
const { session, question, assumptions } = params;
const curNum = currentPhase(ctx, session);
if (curNum !== 3) {
@@ -1462,6 +1468,10 @@ export default function (pi) {
const advanced = advancePhaseAndFinalize(ctx, session, curNum);
if (advanced.err) return advanced.err;
return textResult(`Domanda riscritta e Fase 3 completata (sessione ${session}).`);
} catch (fatal) {
const msg = (fatal.stderr || fatal.message || String(fatal)).toString().trim();
return textResult(`[rewrite_question ERRORE INTERNO] ${msg}. Riprova o usa un approccio diverso.`);
}
},
});
@@ -1480,6 +1490,7 @@ export default function (pi) {
}),
async execute(_id, params, _signal, _onUpdate, ctx) {
lockActive = true;
try {
const { session } = params;
// schema_linking is Type.Any(): a stringified JSON object passes validation
// but would be double-encoded here and rejected by the CLI. Normalize first.
@@ -1497,6 +1508,10 @@ export default function (pi) {
const cliMsg = (e.stderr || e.message || String(e)).toString().trim();
return textResult(`${cliMsg} Correggi schema_linking e riprova.`);
}
} catch (fatal) {
const msg = (fatal.stderr || fatal.message || String(fatal)).toString().trim();
return textResult(`[write_schema_linking ERRORE INTERNO] ${msg}. Riprova o usa un approccio diverso.`);
}
},
});
@@ -1506,6 +1521,7 @@ export default function (pi) {
description: "Persiste un blocco CTE tramite tht cte save; non scrivere mai file di sessione direttamente.",
parameters: Type.Object({ session: Type.String(), name: Type.String(), sql: Type.String() }),
async execute(_id, params, _signal, _onUpdate, ctx) {
try {
const err = relayIfThtFails(
ctx,
["cte", "save", "--session", params.session, "--name", params.name, "--file", "-"],
@@ -1513,6 +1529,10 @@ export default function (pi) {
params.sql,
);
return err || textResult(`CTE ${params.name} salvato per la sessione ${params.session}.`);
} catch (fatal) {
const msg = (fatal.stderr || fatal.message || String(fatal)).toString().trim();
return textResult(`[write_cte_sql ERRORE INTERNO] ${msg}. Riprova o usa un approccio diverso.`);
}
},
});
@@ -1522,6 +1542,7 @@ export default function (pi) {
description: "Persiste il SQL finale tramite tht sql set-final; non scrivere mai file di sessione direttamente.",
parameters: Type.Object({ session: Type.String(), sql: Type.String() }),
async execute(_id, params, _signal, _onUpdate, ctx) {
try {
const err = relayIfThtFails(
ctx,
["sql", "set-final", "--session", params.session, "--file", "-"],
@@ -1529,6 +1550,10 @@ export default function (pi) {
params.sql,
);
return err || textResult(`SQL finale salvato per la sessione ${params.session}.`);
} catch (fatal) {
const msg = (fatal.stderr || fatal.message || String(fatal)).toString().trim();
return textResult(`[write_final_sql ERRORE INTERNO] ${msg}. Riprova o usa un approccio diverso.`);
}
},
});