feat(resume): Resume in the kebab menu (A1) + harden the resume kickoff (A2)
A1 — SessionMenu gains a Resume item, gated to status!=="finalized" && !archived (matching the backend's 409 read-only guard), wired in AppShell to doResume -> POST /sessions/:id/resume. SessionMenu.test.tsx (3 tests); frontend 96/96, tsc clean. A2 — diagnosis-first clean-room repro driving `pi --mode rpc` with the backend's exact resume handshake shows the cold-start stall NO LONGER reproduces on pi 0.79.4 (8/8 chained into `tht session show` + `read SKILL.md` in-turn, fresh and partway sessions). The earlier narrate-and-stop predates the pi upgrade. Defense-in-depth anyway: RIPRENDI_KICKOFF hardened to force the in-turn tool call (gate_resume_kickoff.test.js + live regression 2/2). Gate JS 34/34. PROJECT_STATE open-item #1 (resume stall) flipped to RESOLVED; cross-model resume robustness folded into workstream G. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert");
|
||||
const { createFakePi } = require("./fake_pi_runtime.js");
|
||||
const installGate = require("../../tht-gate.js").default ?? require("../../tht-gate.js");
|
||||
|
||||
// Workstream A (defense-in-depth): the resume cold-start stall (model narrates step 1
|
||||
// then ends the turn without the tool call) no longer reproduces on pi 0.79.4, but the
|
||||
// resume kickoff is hardened to force the in-turn tool call so weaker/older models don't
|
||||
// regress into a dropped turn.
|
||||
|
||||
test("the resume kickoff injects the bootstrap steps and forces in-turn action", async () => {
|
||||
const { pi } = createFakePi();
|
||||
installGate(pi);
|
||||
await pi.emit("input", { source: "rpc", text: "/riprendi-sessione 2026-06-30-000000-x" });
|
||||
const injected = await pi.emit("before_agent_start", { systemPrompt: "" });
|
||||
const text = injected?.systemPrompt ?? "";
|
||||
assert.match(text, /tht session show/); // the resume kickoff is the one injected
|
||||
// hardening: act now, in this same turn; do not stop after merely stating intent.
|
||||
assert.match(text, /in QUESTO stesso turno/i);
|
||||
assert.match(text, /NON terminare il turno/i);
|
||||
});
|
||||
@@ -104,6 +104,9 @@ const RIPRENDI_KICKOFF =
|
||||
"comando di shell ne' `/skill:...`).\n" +
|
||||
"3. Determina l'ultima fase completata dai fatti persistiti (le decisioni sono la verita': " +
|
||||
"cio' che non e' registrato non e' avvenuto) e riprendi da li'.\n" +
|
||||
"Esegui i passi 1-2 ORA, in QUESTO stesso turno, chiamando subito i tool (`bash` per " +
|
||||
"`tht session show`, `read` per la skill): NON limitarti a dichiarare l'intenzione e NON " +
|
||||
"terminare il turno prima di aver chiamato i tool.\n" +
|
||||
"Valgono le stesse regole non negoziabili: una domanda per volta, conferma esplicita, tool " +
|
||||
"reviewer_*, niente phase advance/reopen o decision add da shell, una fase alla volta.";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user