fix(gate): F6 approves each CTE by name, not 'phase:6'

reviewer_confirm kind:'cte_result' registered cte_approved --subject
phase:6, which decision_cmd rejects (exit 5) and next_cte never
recognizes — dead-ending F6. Derive the CTE name from 'tht cte next'
(plan-order single source of truth) and approve by name. sql path
(sql_approved:phase:N) unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-01 16:34:54 +02:00
co-authored by Claude Opus 4.8
parent 47a52170ce
commit 160d7f075e
+27 -4
View File
@@ -620,8 +620,31 @@ export default function (pi) {
`CTE plan approvato (${names.length} CTE, sessione ${session}).`,
);
}
if (kind === "cte_result" || kind === "sql") {
const dt = kind === "sql" ? "sql_approved" : "cte_approved";
if (kind === "cte_result") {
// The CTE under review is always next_cte (plan order is enforced by
// `tht cte test`). Approve it BY NAME: `cte_approved` keys on the CTE
// name (phase.approved_ctes / next_cte); a `phase:N` subject is rejected
// by `decision add` (exit 5) and never satisfies F6's advance prereq.
const cteName = tht(ctx, [
"cte",
"next",
"--session",
session,
]).trim();
if (!cteName) {
return textResult(
`Nessun CTE in attesa di approvazione (sessione ${session}).`,
);
}
const err = relayIfThtFails(
ctx,
["decision", "add", "--session", session, "--type", "cte_approved", "--subject", cteName],
"",
);
if (err) return err;
return textResult(`CTE '${cteName}' approvato (sessione ${session}).`);
}
if (kind === "sql") {
const err = relayIfThtFails(
ctx,
[
@@ -630,14 +653,14 @@ export default function (pi) {
"--session",
session,
"--type",
dt,
"sql_approved",
"--subject",
`phase:${currentPhase(ctx, session)}`,
],
"",
);
if (err) return err;
return textResult(`${kind} approvato (sessione ${session}).`);
return textResult(`SQL approvato (sessione ${session}).`);
}
return textResult(`Approvato (kind=${kind}, sessione ${session}).`);
},