Fix session resume and PSD container configuration
This commit is contained in:
@@ -245,3 +245,61 @@ test("reviewer_schema_linking returns a textResult (not a throw) when a proposed
|
||||
_handler = null;
|
||||
}
|
||||
});
|
||||
|
||||
test("reviewer_schema_linking explains that phase four stays open when joins are missing", async () => {
|
||||
_handler = (_file, args) => {
|
||||
if (args[0] === "phase" && args[1] === "meta")
|
||||
return JSON.stringify({ phases: [{ num: 4, id: "F4" }] });
|
||||
if (args[0] === "phase" && args[1] === "show") return "Fase corrente: 4\n";
|
||||
if (args[0] === "schema" && args[1] === "columns")
|
||||
return JSON.stringify({ ...CATALOG, table: args[2] });
|
||||
if (args[0] === "phase" && args[1] === "advance") {
|
||||
const error = new Error("phase advance failed");
|
||||
error.stderr = "Fase 4: più tabelle promosse richiedono join strutturati";
|
||||
throw error;
|
||||
}
|
||||
return "";
|
||||
};
|
||||
|
||||
try {
|
||||
const gate = require(GATE);
|
||||
const { createFakePi } = require("./fake_pi_runtime.js");
|
||||
const { pi, ctx, tools } = createFakePi();
|
||||
ctx.cwd = "/nonexistent-thothii-test-cwd-open-f4";
|
||||
gate.default(pi);
|
||||
|
||||
ctx.ui.input = async (title) => {
|
||||
const descriptor = JSON.parse(title);
|
||||
return JSON.stringify({
|
||||
id: descriptor.id,
|
||||
kind: "schema-linking",
|
||||
tables: descriptor.tables.map((table) => ({
|
||||
id: table.id,
|
||||
enacted: true,
|
||||
columns: ["cod_paz"],
|
||||
})),
|
||||
});
|
||||
};
|
||||
|
||||
const result = await tools.get("reviewer_schema_linking").def.execute(
|
||||
"call-open-f4",
|
||||
{
|
||||
session: "s1",
|
||||
title: "Schema linking",
|
||||
tables: [
|
||||
{ id: "fact", name: "fact_event", kind: "promote", suggested_columns: ["cod_paz"] },
|
||||
{ id: "patient", name: "dim_patient", kind: "promote", suggested_columns: ["cod_paz"] },
|
||||
],
|
||||
advance: true,
|
||||
},
|
||||
null,
|
||||
null,
|
||||
ctx,
|
||||
);
|
||||
|
||||
assert.match(result.content[0].text, /Fase resta aperta/i);
|
||||
assert.match(result.content[0].text, /join/i);
|
||||
} finally {
|
||||
_handler = null;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const cp = require("node:child_process");
|
||||
const { createRequire } = require("node:module");
|
||||
const path = require("node:path");
|
||||
|
||||
const GATE = path.join(__dirname, "..", "..", "tht-gate.js");
|
||||
|
||||
if (typeof globalThis.require === "undefined") {
|
||||
globalThis.require = createRequire(GATE);
|
||||
}
|
||||
|
||||
test("writing reviewed structured joins closes phase four", async () => {
|
||||
const calls = [];
|
||||
const original = cp.execFileSync;
|
||||
cp.execFileSync = (_file, args) => {
|
||||
calls.push(args.join(" "));
|
||||
if (args[0] === "phase" && args[1] === "show") return "Fase corrente: 4\n";
|
||||
return "";
|
||||
};
|
||||
|
||||
try {
|
||||
const gate = require(GATE);
|
||||
const { createFakePi } = require("./fake_pi_runtime.js");
|
||||
const { pi, ctx, tools } = createFakePi();
|
||||
ctx.cwd = "/nonexistent-thothii-test-cwd";
|
||||
gate.default(pi);
|
||||
|
||||
const result = await tools.get("write_schema_linking").def.execute(
|
||||
"call-write-linking",
|
||||
{
|
||||
session: "s1",
|
||||
schema_linking: {
|
||||
question: "q",
|
||||
candidates: [
|
||||
{ kind: "table", name: "fact_event", decision: "promoted" },
|
||||
{ kind: "table", name: "dim_patient", decision: "promoted" },
|
||||
],
|
||||
joins: [{ from: "fact_event.cod_paz", to: "dim_patient.cod_paz" }],
|
||||
},
|
||||
},
|
||||
null,
|
||||
null,
|
||||
ctx,
|
||||
);
|
||||
|
||||
assert.ok(calls.includes("session set-schema-linking s1 --file -"));
|
||||
assert.ok(calls.includes("phase advance --session s1"));
|
||||
assert.match(result.content[0].text, /Fase avanzata automaticamente/);
|
||||
} finally {
|
||||
cp.execFileSync = original;
|
||||
}
|
||||
});
|
||||
@@ -1117,6 +1117,7 @@ export default function (pi) {
|
||||
const adv = advance ? forceAdvance(ctx, session) : { advanced: false };
|
||||
const parts = [`Schema linking registrato dal reviewer (${n} tabelle + colonne curate). schema_linking.json scritto.`];
|
||||
if (adv.advanced) parts.push("Fase avanzata automaticamente — nessun gate aggiuntivo necessario.");
|
||||
else if (advance && adv.error) parts.push(`Fase resta aperta: ${adv.error}`);
|
||||
return textResult(parts.join(" "));
|
||||
} catch (fatal) {
|
||||
const msg = (fatal.stderr || fatal.message || String(fatal)).toString().trim();
|
||||
@@ -1636,9 +1637,13 @@ export default function (pi) {
|
||||
["session", "set-schema-linking", session, "--file", "-"],
|
||||
JSON.stringify(schema_linking),
|
||||
);
|
||||
return textResult(
|
||||
`schema_linking.json scritto e validato per la sessione ${session}.`,
|
||||
);
|
||||
const message = `schema_linking.json scritto e validato per la sessione ${session}.`;
|
||||
if (currentPhase(ctx, session) !== 4) return textResult(message);
|
||||
const advanced = forceAdvance(ctx, session);
|
||||
if (advanced.error) {
|
||||
return textResult(`${message} Fase non avanzata: ${advanced.error}`);
|
||||
}
|
||||
return textResult(`${message} Fase avanzata automaticamente.`);
|
||||
} catch (e) {
|
||||
const cliMsg = (e.stderr || e.message || String(e)).toString().trim();
|
||||
return textResult(`${cliMsg} Correggi schema_linking e riprova.`);
|
||||
|
||||
@@ -31,9 +31,10 @@ closes the phase itself; a `reviewer_confirm kind:"phase"` summary gate exists o
|
||||
completeness is a human judgment (F1, F2 with recorded memories, F5). A `reviewer_decide`/
|
||||
`reviewer_select` choice records its OWN decision but does NOT advance the phase. `advance:true`
|
||||
on `reviewer_decide` auto-advances only F2 (empty memory) and F6 (skipped/empty) — never a
|
||||
phase that recorded substantive decisions. FIVE gates close their phase themselves, because
|
||||
there the human interaction IS the phase approval: `rewrite_question` (F3),
|
||||
`reviewer_schema_linking` with `advance:true` (F4), the LAST `reviewer_confirm
|
||||
phase that recorded substantive decisions. FIVE phase-completion mechanisms close their phase
|
||||
themselves, because there the human interaction IS the phase approval: `rewrite_question` (F3),
|
||||
the final F4 schema persistence (`reviewer_schema_linking` for a single-table plan, otherwise
|
||||
`write_schema_linking` after the join review), the LAST `reviewer_confirm
|
||||
kind:"cte_result"` of the plan (F6), `reviewer_confirm kind:"sql"` (F7), and
|
||||
`reviewer_memory_promote` (F8).
|
||||
|
||||
@@ -42,7 +43,7 @@ kind:"cte_result"` of the plan (F6), `reviewer_confirm kind:"sql"` (F7), and
|
||||
| F1 chiarimento | — | `reviewer_confirm kind:"phase"` |
|
||||
| F2 memoria | — | `advance:true` only if nothing recorded; else `reviewer_confirm kind:"phase"` |
|
||||
| F3 riscrittura | `question.md` | `rewrite_question` records approval and advances automatically |
|
||||
| F4 schema_linking | `schema_linking.json` | `reviewer_schema_linking` with `advance:true` closes the phase itself (the curation IS the approval; `reviewer_confirm kind:"phase"` only as fallback if it reports an error). Promoted columns are the reviewer-approved OUTPUT columns — project exactly those in the final SELECT. |
|
||||
| F4 schema_linking | `schema_linking.json` | `reviewer_schema_linking(advance:true)` closes a single-table plan. With multiple promoted tables it deliberately keeps F4 open until the separate join review is persisted into `schema_linking.json`; the succeeding `write_schema_linking` closes F4 automatically. Never add `reviewer_confirm kind:"phase"`. Promoted columns are the reviewer-approved OUTPUT columns — project exactly those in the final SELECT. |
|
||||
| F5 sintesi | — | `reviewer_confirm kind:"phase"` (after `tht session check`) |
|
||||
| F6 cte | `cte_plan.json`, `ctes/`, `cte_tests.json` | approve each CTE with `kind:"cte_result"`; approving the LAST CTE of the plan closes the phase automatically (`kind:"phase"` only as fallback if the auto-close reports an error) |
|
||||
| F7 sql_finale | `sql_final.sql` | `kind:"sql"` records `sql_approved` AND closes the phase automatically (`kind:"phase"` only as fallback if it reports an error) |
|
||||
@@ -60,8 +61,8 @@ kind:"cte_result"` of the plan (F6), `reviewer_confirm kind:"sql"` (F7), and
|
||||
with the deliberate `reviewer_confirm kind:"phase"` summary gate. The `advance:true`
|
||||
flag on `reviewer_decide` is a shortcut that auto-advances ONLY F2 when the memory phase
|
||||
recorded nothing and F6 when it is skipped/empty; everywhere else it is a silent no-op,
|
||||
so never rely on it to advance. The self-closing gates are the five listed above
|
||||
(F3 `rewrite_question`, F4 `reviewer_schema_linking` `advance:true`, F6 last
|
||||
so never rely on it to advance. The self-closing mechanisms are the five listed above
|
||||
(F3 `rewrite_question`, F4 final schema persistence, F6 last
|
||||
`kind:"cte_result"`, F7 `kind:"sql"`, F8 `reviewer_memory_promote`) — after one of
|
||||
those, do NOT add a `reviewer_confirm kind:"phase"` that merely echoes it; the phase is
|
||||
already closed.
|
||||
@@ -286,6 +287,9 @@ Prerequisite: Phase 3 closed.
|
||||
columns: project exactly those in the final SELECT (Phase 6/7); you remain free
|
||||
to reference other columns as join keys or filter predicates when the query
|
||||
requires them.
|
||||
Call `reviewer_schema_linking` before the join review. For a multi-table plan,
|
||||
`advance:true` will report that F4 remains open because the structured joins are
|
||||
not present yet; this is expected. Stay in F4 and continue with the join-only gate.
|
||||
Propose **all required joins together in a separate, join-only**
|
||||
`reviewer_decide(advance:false)`, registering `join_modified`. Do not mix
|
||||
`join_modified` with other decision types in that call. The gate renders this proposal
|
||||
@@ -317,7 +321,8 @@ Prerequisite: Phase 3 closed.
|
||||
excluded:[...], open_questions:[], concept_formulas:[]}` — `candidates`/`excluded`
|
||||
are owned by `reviewer_schema_linking`/`sync-schema-linking` (step 2), so if you
|
||||
call `write_schema_linking` after step 2, carry over its `candidates`/`excluded`
|
||||
unchanged rather than overwriting them. Then close with `reviewer_confirm
|
||||
unchanged rather than overwriting them. After the reviewer-approved joins are present,
|
||||
`write_schema_linking` closes F4 automatically. Do not add a `reviewer_confirm
|
||||
kind:"phase"`. Do NOT run `tht session check` (that's Phase 5).
|
||||
|
||||
## Phase 5 — Synthesis
|
||||
|
||||
Reference in New Issue
Block a user