diff --git a/harness/.pi/skills/tht-sessione/SKILL.md b/harness/.pi/skills/tht-sessione/SKILL.md index 805cb0a3..9b60b5fd 100644 --- a/harness/.pi/skills/tht-sessione/SKILL.md +++ b/harness/.pi/skills/tht-sessione/SKILL.md @@ -23,19 +23,40 @@ descriptions and the evidence you read are written in the workspace language (e. your interpretation of domain terms follow the workspace language.** When in doubt about a domain term, ask the reviewer. +## Phase map (advance cheat-sheet) + +A phase advances ONLY when a `phase_approved:phase:N` decision is recorded for the current +phase — written by `reviewer_confirm kind:"phase"` (or `kind:"sql"` for F7). A `reviewer_decide`/ +`reviewer_select` choice records its OWN decision but does NOT advance the phase. `advance:true` +auto-advances only F2 (empty memory) and F6 (skipped/empty) — never a phase that recorded +substantive decisions. + +| Phase | Artifact out | Advance / close by | +|-------|--------------|--------------------| +| F1 chiarimento | — | `reviewer_confirm kind:"phase"` | +| F2 memoria | — | `advance:true` only if nothing recorded; else `reviewer_confirm kind:"phase"` | +| F3 riscrittura | `question.md` | `reviewer_confirm kind:"phase"` (after `rewrite_question`) | +| F4 schema_linking | `schema_linking.json` | `reviewer_confirm kind:"phase"` (after `write_schema_linking`) | +| F5 sintesi | — | `reviewer_confirm kind:"phase"` (after `tht session check`) | +| F6 cte | `cte_plan.json`, `ctes/`, `cte_tests.json` | approve each CTE `kind:"cte_result"`, then `reviewer_confirm kind:"phase"` | +| F7 sql_finale | `sql_final.sql` | `reviewer_confirm kind:"sql"` | +| F8 datamart | — | `reviewer_confirm kind:"phase"` | + ## Disciplines (hold in every phase) 1. **One fact, one `tht` command.** Every state change goes through a single `tht` command (you invoke `tht ...` via the shell tool). NEVER run `tht phase advance` or `tht decision add` from the shell — they are blocked by the gate's anti-bypass hook; the gate extension records every decision via the `reviewer_*` tools. -2. **The choice is the confirmation.** For `reviewer_decide`, and for a - `reviewer_select` whose chosen option carries a `decision`, do NOT add a separate - confirmation gate after — the choice already records its decision and (if - `advance:true`) advances. Add a `reviewer_confirm kind:"phase"` ONLY where the - phase genuinely needs a deliberate gate (F1 close, F5 close, last CTE - `kind:"cte_result"`, final SQL `kind:"sql"`, F8 close) — never as a redundant - echo of a recorded choice. +2. **The choice records; the phase gate advances.** A `reviewer_decide`, or a + `reviewer_select` whose chosen option carries a `decision`, PERSISTS that decision — it + does NOT by itself advance the phase. To move to the next phase you MUST issue + `reviewer_confirm kind:"phase"` (F7 uses `kind:"sql"`), the deliberate "this phase is + done" 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. Do NOT add a `reviewer_confirm` + that merely echoes a decision already recorded by a choice — the phase gate is a separate, + deliberate step, not an echo of a decision. 3. **Single pick vs multi-answer.** For a single-pick clarification or decision, use `reviewer_select` and attach a `decision` payload (`{type, subject, detail?, rationale?}`) to each concrete option: picking it persists that decision directly — @@ -123,9 +144,8 @@ Prerequisite: you must already be in Phase 1. clarifying" gate). Do NOT add a separate confirmation after each individual clarification — each is already recorded by its `reviewer_select`/`reviewer_decide` (`concept_clarified`) choice, not via phase gates. -4. After the phase advance, update the question with the gate's `rewrite_question` - tool (it calls `tht session set-question`, which writes `question.md` - deterministically — never edit `question.md` by hand). +4. Closing Phase 1 advances to Phase 2 (Memories). The question is rewritten later, in + Phase 3 — do NOT call `rewrite_question` here. ## Phase 2 — Memories @@ -148,8 +168,9 @@ Prerequisite: Phase 1 closed. checklist starts pre-selected with the recommended memories. With `allow_empty:true` an empty selection is accepted (no memory applied; deselected still recorded) and the phase advances — no separate gate. -4. If no memory clears score 0.5, say so and close the phase quickly - (`reviewer_confirm kind:"phase"` if the list is empty). +4. Closing: if memories were applied or rejected (substantive decisions), `advance:true` + no-ops — close with `reviewer_confirm kind:"phase"`. Only a truly empty memory phase + (nothing applied, nothing rejected) auto-advances via `advance:true`. 5. **Promotion (D11).** To promote ONE memory in `profile=workstation`, use `tht memory save-one` (targeted one-row upsert via the writer key). Batch promotion (`tht memory promote`) is server-side. Memories live ONLY in the @@ -164,15 +185,14 @@ Phase 3 (CLI exit 5). terms, each condition as a separate numbered clause, ambiguous terms replaced with the concepts clarified in Phase 1 citing the defining evidence, expected output made explicit). -2. Present in **a single** `reviewer_decide(advance:true, allow_other:true)`. The +2. Present in **a single** `reviewer_decide(advance:false, allow_other:true)`. The "Confirm rewriting" option is `recommended:true` with `{type:"question_rewritten", subject:"domanda", detail:""}`. - Do NOT add a `reviewer_confirm kind:"phase"` after — the `reviewer_decide` already - advances. -3. **Order matters:** (a) `reviewer_decide(advance:true)` records `question_rewritten` - and advances → (b) the gate's `rewrite_question` tool calls `tht session - set-question` which writes `question.md` (regenerates question + an "## Assunzioni" - section). Never edit/write `question.md` manually. +3. **Order matters:** (a) the `reviewer_decide` records `question_rewritten` → (b) call the + gate's `rewrite_question` tool, which runs `tht session set-question` to write + `question.md` (regenerates question + an "## Assunzioni" section; never edit it by hand) + → (c) close the phase with `reviewer_confirm kind:"phase"`. F3 does NOT auto-advance: + the `question_rewritten` decision alone does not move the phase. 4. "Altro" iterates (re-propose a new `reviewer_decide`). "Torna indietro" reopens F1. ## Phase 4 — Schema linking @@ -181,7 +201,7 @@ Prerequisite: Phase 3 closed. 1. `tht schema introspect` + `tht schema render --format mschema-text` for the schema context. Copy table/column names EXACTLY from it — never invent objects. -2. Propose tables/columns/joins in `reviewer_decide(advance:true)`. Register +2. Propose tables/columns/joins in `reviewer_decide(advance:false)`. Register `table_promoted`/`table_excluded`/`column_corrected`/`join_modified`. 3. **Value grounding (D14a).** If a cited value (e.g. "ablazione") matches MULTIPLE columns (a boolean flag + a free-text patologia field), present a `reviewer_decide` @@ -192,7 +212,12 @@ Prerequisite: Phase 3 closed. ""` (or derive it from the evidence/context), present it, and let the reviewer approve/reject (`concept_formula_approved`/`concept_formula_rejected`). Reflect the approved formula in `schema_linking.json` (`concept_formulas`). -5. Write `schema_linking.json` (the Phase 4 artifact) and close with +5. Persist `schema_linking.json` with the gate's `write_schema_linking` tool — it validates + the object against the `SchemaLinking` model and writes the file deterministically (never + hand-write it, never edit it with the file tool; on a validation error the tool returns the + exact problem to fix). Shape: `{question, candidates:[{kind:"table"|"column", name, + evidence?, decision?:"promoted"|"excluded"|"pending"}], joins:[{from, to, source?}], + excluded:[{kind, name}], open_questions:[], concept_formulas:[]}`. Then close with `reviewer_confirm kind:"phase"`. Do NOT run `tht session check` (that's Phase 5). ## Phase 5 — Synthesis