From 4364bdd4a147808b0383bb401a99fba011a5dbe5 Mon Sep 17 00:00:00 2001 From: mptyl Date: Mon, 29 Jun 2026 11:39:56 +0200 Subject: [PATCH] docs(spec): frame cold-start resume correctness as a prerequisite Add the SKILL.md design contract (persisted state is the truth) and a dedicated Resume correctness section: backend new/resume prompt mode, missing cold-start procedure in the skill, end-to-end verification gate. Co-Authored-By: Claude Opus 4.8 --- .../2026-06-29-session-management-design.md | 59 ++++++++++++++++--- 1 file changed, 50 insertions(+), 9 deletions(-) diff --git a/docs/superpowers/specs/2026-06-29-session-management-design.md b/docs/superpowers/specs/2026-06-29-session-management-design.md index 808ad2de..b70a12bc 100644 --- a/docs/superpowers/specs/2026-06-29-session-management-design.md +++ b/docs/superpowers/specs/2026-06-29-session-management-design.md @@ -25,6 +25,14 @@ directory; advancing to the next phase does **not** require replaying the prior conversation. Therefore **the phase documents ARE the persistence** — we do **not** need to store the verbatim chat. +This is the explicit design contract of the orchestrator +([SKILL.md](../../../harness/.pi/skills/tht-sessione/SKILL.md)): *"the persisted state +(ledger `review_decisions.jsonl` + artifacts) is the truth — what is not recorded did not +happen."* The documents are not meant to *contain* the chat; they are meant to make the +chat **reconstructable / unnecessary** — the documents are the *state*, the skill is the +*procedure*, and together they let a fresh model continue the task. Whether that holds for +a cold-start resume is a **verifiable prerequisite**, treated explicitly below. + This was the crux decision in brainstorming. It means: - The "vista divisa" is a **read-only document viewer** driven by what's on disk, not a @@ -136,15 +144,10 @@ new `ThtRunner` method that shells the matching `tht` subcommand: Before spawning, read the manifest (`tht.sessionShow`); if `status == "finalized"` or `archived`, return `409` with a clear message and do **not** spawn Pi. -**Resume must rebuild phase context (gap to fix).** Today `PiProcessManager.spawnFor` -unconditionally sends `/nuova-domanda "kickoff"` -([pi-process-manager.ts](../../../backend/src/pi/pi-process-manager.ts)), and `resume` -calls the same path — so a "resume" actually kicks off a *new* question instead of -re-entering the workflow. `spawnFor` must take a **mode**: new sessions send -`/nuova-domanda`, resumed sessions send `/riprendi-sessione ` (the existing prompt -[riprendi-sessione.md](../../../harness/.pi/prompts/riprendi-sessione.md)) so Pi rebuilds -state and lands on the last incomplete phase. Without this, the resume model does not -actually work. +**Resume must rebuild phase context.** This is the backend half of the resume-correctness +prerequisite: `spawnFor` gains a `new`/`resume` mode (new → `/nuova-domanda`, resume → +`/riprendi-sessione `). See the dedicated **Resume correctness** section below for the +full picture (backend prompt, skill cold-start procedure, end-to-end verification). ## Frontend layer (React + base-ui + Tailwind + React Query) @@ -202,6 +205,40 @@ actually work. - **Rail organization:** collapsible group headers + "Senza gruppo"; "Archivio" as a separate section, never mixed into the active list. +## Resume correctness — verifiable prerequisite + +The whole "no chat persistence" premise rests on a fresh Pi process being able to +**re-enter the workflow at the last incomplete phase using only the persisted state**. +That is the design contract quoted above (ledger + artifacts are the truth; each phase's +prerequisites are prior artifacts; rollback `/torna N`, discipline 11, already resumes +"reviewing the existing artifacts" without replaying chat). The premise is sound — but the +**cold-start resume path** (new process, zero conversation) is today thin and unproven. +This feature treats resume correctness as a prerequisite and must close three gaps: + +1. **Backend sends the wrong prompt.** `PiProcessManager.spawnFor` + ([pi-process-manager.ts](../../../backend/src/pi/pi-process-manager.ts)) always sends + `/nuova-domanda "kickoff"`, and `resume` calls the same path — so a "resume" kicks off a + *new* question. `spawnFor` must take a `new`/`resume` mode: new → `/nuova-domanda`, + resume → `/riprendi-sessione ` (the prompt + [riprendi-sessione.md](../../../harness/.pi/prompts/riprendi-sessione.md)). +2. **No cold-start procedure in the skill.** The phases assume "you must already be in + Phase 1"; there is no "Phase 0 / Resume" step telling a fresh process to read + `tht session show `, take the current phase N, load that phase's artifacts, and + resume its procedure. Add a short **Resume** section to + [SKILL.md](../../../harness/.pi/skills/tht-sessione/SKILL.md) (or confirm the model + reliably bootstraps from `tht session show` + artifact reads). The one-line resume + prompt is not sufficient on its own — intra-session rollback works only because the + conversation is still live; cold start has nothing to lean on. +3. **End-to-end verification.** A test that creates a session, drives it partway (e.g. into + F4), tears down the Pi process, resumes in a fresh process, and asserts it lands on the + **correct phase** with the prior artifacts available and presents the next gate — not a + new-question kickoff. + +Until (1)–(3) pass, the phase-document model is a design assumption, not a proven fact. +The read panel, rename, group, archive, and delete work regardless of resume; but the +**"Riprendi"** action is only trustworthy once resume correctness is verified, so it must +not ship as "working" before this gate is green. + ## Testing approach (TDD per repo convention) - **Harness (pytest):** new `store.py` helpers (set-name/group, archive/unarchive, @@ -214,6 +251,10 @@ actually work. invalidate the query; grouping/archived filtering renders correctly; the panel renders documents via the right viewers and shows/hides "Riprendi" by resumability; delete-confirm flow. +- **Resume correctness (end-to-end):** the verification described in the *Resume + correctness* section — partway session → teardown → fresh-process resume → lands on the + correct phase with prior artifacts, not a new-question kickoff. This gate must be green + before "Riprendi" is considered working. ## Out of scope / deferred (with triggers)