fix: finalize session after memory promotion
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const fs = require("node:fs");
|
||||
const os = require("node:os");
|
||||
const path = require("node:path");
|
||||
const { createFakePi } = require("./fake_pi_runtime.js");
|
||||
|
||||
// F8 auto-close: reviewer_memory_promote is the last human interaction of the
|
||||
// workflow — after recording the promotion the gate must advance F8 and finalize
|
||||
// the session itself (no trailing reviewer_confirm "approve" form). These tests
|
||||
// drive the real tool execute against a fake `tht` CLI placed on PATH.
|
||||
|
||||
// tht-gate.js calls a bare `require` (Pi's runtime provides it); under node --test
|
||||
// the ESM import has none, so expose the CJS require globally for the gate module.
|
||||
globalThis.require = require;
|
||||
|
||||
const installGatePromise = import("../../tht-gate.js").then((m) => m.default);
|
||||
|
||||
function setupFakeTht(t, { phase, status = "open" }) {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "fake-tht-"));
|
||||
const log = path.join(dir, "calls.log");
|
||||
fs.writeFileSync(log, "");
|
||||
const script = `#!/bin/bash
|
||||
echo "$@" >> "${log}"
|
||||
case "$1 $2" in
|
||||
"phase show") echo "Fase corrente: ${phase}";;
|
||||
"phase meta") echo '{"max_phase":8,"phases":[{"num":2,"id":"F2","emits":[]},{"num":8,"id":"F8","emits":[]}]}';;
|
||||
"memory promote") echo "[]";;
|
||||
"session show") echo '{"status":"${status}"}';;
|
||||
*) echo "OK";;
|
||||
esac
|
||||
`;
|
||||
const bin = path.join(dir, "tht");
|
||||
fs.writeFileSync(bin, script, { mode: 0o755 });
|
||||
const oldPath = process.env.PATH;
|
||||
process.env.PATH = `${dir}:${oldPath}`;
|
||||
t.after(() => {
|
||||
process.env.PATH = oldPath;
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
});
|
||||
return { dir, calls: () => fs.readFileSync(log, "utf8") };
|
||||
}
|
||||
|
||||
async function runPromote(t, { phase }) {
|
||||
const fake = setupFakeTht(t, { phase });
|
||||
const installGate = await installGatePromise;
|
||||
const { pi, ctx, tools } = createFakePi();
|
||||
ctx.cwd = fake.dir; // execFileSync needs an existing cwd; no .env here is fine
|
||||
installGate(pi);
|
||||
const { def } = tools.get("reviewer_memory_promote");
|
||||
const res = await def.execute("t1", { session: "s1" }, null, null, ctx);
|
||||
return { res, calls: fake.calls() };
|
||||
}
|
||||
|
||||
test("F8 + zero candidati: il gate avanza la fase e finalizza da solo", async (t) => {
|
||||
const { res, calls } = await runPromote(t, { phase: 8 });
|
||||
const text = res.content[0].text;
|
||||
assert.match(text, /sessione finalizzata \(s1\)/);
|
||||
assert.match(text, /NON presentare altri gate/);
|
||||
assert.match(calls, /^phase advance --session s1$/m);
|
||||
assert.match(calls, /^session finalize s1$/m);
|
||||
});
|
||||
|
||||
test("fuori dall'ultima fase non chiude nulla (comportamento precedente)", async (t) => {
|
||||
const { res, calls } = await runPromote(t, { phase: 2 });
|
||||
assert.match(res.content[0].text, /prosegui con la chiusura della sessione/);
|
||||
assert.doesNotMatch(calls, /phase advance/);
|
||||
assert.doesNotMatch(calls, /session finalize/);
|
||||
});
|
||||
|
||||
test("phase-gate su sessione gia' finalizzata: nessun widget, il modello viene fermato", async (t) => {
|
||||
setupFakeTht(t, { phase: 8, status: "finalized" });
|
||||
const installGate = await installGatePromise;
|
||||
const { pi, ctx, tools } = createFakePi();
|
||||
ctx.cwd = os.tmpdir();
|
||||
installGate(pi);
|
||||
const { def } = tools.get("reviewer_confirm");
|
||||
const res = await def.execute(
|
||||
"t2",
|
||||
{ session: "s1", kind: "phase", title: "F8", artifact: { kind: "phase", data: {} } },
|
||||
null,
|
||||
null,
|
||||
ctx,
|
||||
);
|
||||
assert.match(res.content[0].text, /gia' finalizzata/);
|
||||
assert.equal(ctx.uiCalls.length, 0); // la form "approve" NON viene ripresentata
|
||||
});
|
||||
Reference in New Issue
Block a user