From 7c417d4cf1dc57c50225d45e51184b25e636ca7a Mon Sep 17 00:00:00 2001 From: mptyl Date: Thu, 2 Jul 2026 12:37:26 +0200 Subject: [PATCH] docs: set up MkDocs site with technical/general docs split MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add mkdocs.yml (windmill theme, mermaid2, matching ~/Chirone/chirone/etl setup) with nav split into "ThothII (Documentazione Tecnica)" — architecture overview, existing design specs/plans, reports — and "Considerazioni Generali" for cross-project notes. Add docs/general/pi-configuration.md explaining Pi's three model-resolution tiers (built-in, user models.json, project extension) and where GLM/DeepSeek/ Qwen each sit. Add docs/architecture/overview.md synthesizing the ThothII architecture for the doc site. Relocate the L2 run report into docs/reports/. Co-Authored-By: Claude Sonnet 5 --- .gitignore | 3 + docs/architecture/overview.md | 59 +++++++ docs/general/pi-configuration.md | 149 ++++++++++++++++++ docs/index.md | 13 ++ docs/javascripts/layout-init.js | 90 +++++++++++ .../{ => reports}/l2-run-report-2026-06-27.md | 0 docs/requirements.txt | 3 + docs/stylesheets/extra.css | 134 ++++++++++++++++ mkdocs.yml | 76 +++++++++ 9 files changed, 527 insertions(+) create mode 100644 docs/architecture/overview.md create mode 100644 docs/general/pi-configuration.md create mode 100644 docs/index.md create mode 100644 docs/javascripts/layout-init.js rename docs/{ => reports}/l2-run-report-2026-06-27.md (100%) create mode 100644 docs/requirements.txt create mode 100644 docs/stylesheets/extra.css create mode 100644 mkdocs.yml diff --git a/.gitignore b/.gitignore index af0d3fb8..c7049dfa 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ htmlcov/ # Playwright MCP run artifacts .playwright-mcp/ + +# === MkDocs build output === +site/ diff --git a/docs/architecture/overview.md b/docs/architecture/overview.md new file mode 100644 index 00000000..695f82d1 --- /dev/null +++ b/docs/architecture/overview.md @@ -0,0 +1,59 @@ +# Panoramica dell'architettura + +> Sintesi ad uso documentazione. Per il dettaglio storico delle decisioni di design vedi le [Specifiche di Design](../superpowers/specs/2026-06-25-thothii-architecture-design.md) e i [Piani di Implementazione](../superpowers/plans/2026-06-25-harness-implementation.md). Per lo stato corrente del progetto (gate manuali pendenti, layout workspace/secret) vedi `PROJECT_STATE.md` nella radice del repo. + +ThothII è un **datamart builder human-in-the-loop**: trasforma una domanda in linguaggio naturale in SQL validato (ed eventualmente un datamart dbt) attraverso un **workflow deterministico a 8 fasi NL→SQL**, in cui il modello *propone* e un revisore umano *decide* ai gate. + +## I tre progetti indipendenti + +``` +frontend (React/SSE) → backend (Fastify) → pi --mode rpc → tht/harness → DWH (sola lettura) +``` + +| Layer | Stack | Ruolo | +|---|---|---| +| **harness/** | Python (`tht` CLI) + Pi gate extension (JS) | Possiede il workflow e **tutta** la persistenza | +| **backend/** | Fastify + TypeScript | Ponte sottile senza database proprio | +| **frontend/** | React 18 + Vite | UI che renderizza i widget di gate e ricostruisce il transcript live dallo stream SSE | + +## L'harness possiede il workflow + +`tht` (Python) è una CLI deterministica; `harness/.pi/extensions/tht-gate.js` è un'estensione Pi che guida il workflow a 8 fasi. La fonte di verità unica del workflow è `harness/workflow.yaml`; le regole di orchestrazione che il modello deve seguire sono in `harness/.pi/skills/tht-sessione/SKILL.md`. La "fase corrente" **non è memorizzata**: viene calcolata piegando il decision ledger (`harness/tht/phase.py`) — va letta prima di ragionare sulla logica di fase. + +## Persistenza = documenti di fase, non chat + +Una sessione è una directory sotto `sessions/` (path definito dal workspace): `session_manifest.yaml` + artefatti per fase (`question.md`, `schema_linking.json`, `sql_final.sql`, …) + `review_decisions.jsonl`. Il contratto (SKILL.md): *"lo stato persistito è la verità — ciò che non è registrato non è accaduto"*. Non esiste uno store di transcript verbatim. Un processo Pi ripreso ricostruisce il contesto da `tht session show ` + gli artefatti su disco. + +## Il backend è un ponte sottile senza database + +- `ThtRunner` esegue subcommand `tht` in shell +- `PiProcessManager` esegue un processo Pi figlio per sessione e fa da bridge al suo stream RPC +- `SessionBridge` mappa eventi RPC di Pi → eventi client (`ui_request` / `text_delta` / `info`) +- `SseHub` distribuisce questi eventi via SSE al browser + +Le impostazioni applicative vivono in un file JSON (`backend/data/settings.json`), non in un database. + +## Contratto del gate human-in-the-loop + +Il modello propone; un revisore umano decide ai gate tramite widget: + +- **`reviewer_select`** — scelta singola: un'opzione con `decision` payload auto-conferma/persiste direttamente; un'opzione senza payload chiede soltanto +- **`reviewer_decide`** — multiselect: ogni scelta È una decisione +- **`reviewer_confirm`** — gate su artefatto/fase + +Il frontend renderizza questi widget-descriptor (registro in `src/widgets/`); il transcript live viene ricostruito in memoria dallo stream SSE (`src/store/sessionStore.ts`) — **non è persistito**. + +## Punti di attenzione ricorrenti + +- `tht -c`/`--config` è un'opzione **per-comando**: deve seguire il subcommand, mai precederlo (`ThtRunner.buildArgv` lo impone). +- L'output `--json` deve essere JSON puro su stdout — è un contratto machine-readable. +- Le stringhe UI sono in inglese; il *contenuto* dei documenti resta nella lingua del workspace (italiano per `psd`), perché è il dato reale — solo chrome/label sono in inglese. +- I workspace (`harness/workspaces/*.yaml`) impostano il target DB e i path **assoluti** `paths.sessions/artifacts/indexes` — per `psd` puntano a un repo separato e non versionato (`tht-workspace-psd/`). I segreti vivono solo in `harness/.env` (gitignored). +- Le impostazioni sono globali (`backend/data/settings.json`: workspace/provider/modello/thinking); il form di nuova sessione richiede solo la domanda. +- **Resume**: una sessione riprendibile rientra all'ultima fase incompleta. Il backend rifiuta il resume con 409 se `finalized` o `archived`; `PiProcessManager.spawnFor` deve inviare `/riprendi-sessione ` (resume) vs `/nuova-domanda` (nuova) — il prompt sbagliato trasforma silenziosamente un resume in una nuova domanda. + +## Come si lancia lo stack + +Lo **stack completo** (Pi reale + DWH reale, serve VPN + `harness/.env` + `pi` sul PATH) si avvia con `./scripts/run-stack.sh` (frontend `:5173` → backend `:8787`). + +Comandi per singolo layer, test, lint: vedi il file `CLAUDE.md` nella radice del repo (guida operativa per Claude Code, tenuta sincronizzata con questa pagina). diff --git a/docs/general/pi-configuration.md b/docs/general/pi-configuration.md new file mode 100644 index 00000000..091029ae --- /dev/null +++ b/docs/general/pi-configuration.md @@ -0,0 +1,149 @@ +# Configurazione dei modelli in Pi: built-in, utente, progetto + +Pi (il coding agent che orchestra il workflow NL→SQL) può risolvere un `provider/model` in tre modi diversi. Non sono alternativi: coesistono, e la scelta di quale usare dipende da **quanto è standard l'endpoint** e da **quanto deve essere ampia la visibilità** del modello (tutti i progetti vs. un progetto solo). + +## I tre livelli di provenienza di un modello + +### 1. Built-in (compilato dentro Pi) + +Pi viene distribuito con un elenco di modelli già noti (`models.generated.js` dentro il pacchetto `@mariozechner/pi-ai`): Anthropic, OpenAI, Google, e anche provider di terze parti con API pubblica ben nota come DeepSeek. Per questi **non serve alcuna configurazione**: bastano le credenziali (env var o `pi auth`). + +`deepseek/deepseek-v4-pro` è così: è nella build di Pi perché `api.deepseek.com` è un'API pubblica documentata, non un endpoint interno. + +### 2. `models.json` a livello utente (`~/.pi/agent/models.json`) + +Per un endpoint **OpenAI-compatible** che non è tra i built-in — ma che non richiede nessuna logica di trasporto speciale — basta *dichiararlo*: baseUrl, apiKey, lista modelli. Questo file esiste **solo a livello utente**: non c'è un equivalente project-level (un `./.pi/models.json` non viene letto). + +Esempio reale in uso su questa macchina — GLM (provider `zai`): + +```json +{ + "providers": { + "zai": { + "baseUrl": "https://api.z.ai/api/coding/paas/v4", + "api": "openai-completions", + "apiKey": "$ZAI_API_KEY", + "models": [ + { + "id": "glm-5.2", + "name": "GLM-5.2", + "reasoning": true, + "contextWindow": 200000, + "maxTokens": 131072 + } + ] + } + } +} +``` + +Essendo a livello utente, GLM è visibile da **qualsiasi progetto**. + +### 3. Estensione (`.pi/extensions/*.js`, utente o progetto) + +Quando l'endpoint richiede codice — ad esempio conversione di eventi (thinking→text), un `streamSimple` custom, o comunque logica che un file dichiarativo non può esprimere — serve un'estensione Pi che chiama `pi.registerProvider(...)`. Le estensioni possono vivere sia in `~/.pi/agent/extensions/` (tutti i progetti) sia in `/.pi/extensions/` (solo quel progetto, se Pi viene lanciato con quella cwd). + +Esempio reale — il provider AritmoLab (Qwen), interno all'ospedale, usato solo da ThothII: [harness/.pi/extensions/aritmolab-provider.js](../../harness/.pi/extensions/aritmolab-provider.js). + +## Tabella riassuntiva (stato attuale di questa macchina) + +| Modello | Livello | Perché | Visibilità | +|---|---|---|---| +| `deepseek/deepseek-v4-pro` | Built-in Pi | API pubblica nota, già nella build | Tutti i progetti | +| `zai/glm-5.2` | `~/.pi/agent/models.json` | Endpoint OpenAI-compatible custom (z.ai), nessuna logica speciale | Tutti i progetti | +| `aritmolab/qwen3.6-35b-a3b` | Estensione di progetto | Endpoint interno ospedaliero + conversione eventi thinking→text custom | Solo ThothII (cwd=`harness/`) | + +## Come scegliere il livello giusto per un nuovo modello + +1. **L'endpoint è un'API pubblica già nota a Pi?** → niente da fare, verifica con `pi --list-models`. +2. **È OpenAI-compatible, nessuna logica custom, e deve essere visibile ovunque?** → `~/.pi/agent/models.json`. +3. **Serve codice custom (auth non standard, conversione eventi, trasporto non-OpenAI) oppure deve restare visibile a un solo progetto?** → estensione, in `~/.pi/agent/extensions/` (globale) o `/.pi/extensions/` (locale). + +--- + +## Ambito utente vs. progetto — riepilogo generale + +Oltre ai modelli, Pi carica altre risorse da due alberi paralleli: `~/.pi/agent/` (utente) e `/.pi/` (progetto, risolto in base alla directory da cui viene lanciato `pi`). + +| File/Directory | Livello utente | Livello progetto | Auto-discovery | Precedenza | +|---|---|---|---|---| +| `models.json` | `~/.pi/agent/models.json` | non supportato | no | solo utente | +| `settings.json` | `~/.pi/agent/settings.json` | `./.pi/settings.json` | no | progetto sovrascrive utente | +| `extensions/` | `~/.pi/agent/extensions/` | `./.pi/extensions/` | sì (`.ts`/`.js`) | uniti (progetto + utente) | +| `prompts/` | `~/.pi/agent/prompts/` | `./.pi/prompts/` | sì (`.md`) | uniti | +| `themes/` | `~/.pi/agent/themes/` | `./.pi/themes/` | sì (`.json`) | progetto preferito | +| `skills/` | `~/.pi/agent/skills/` | `./.pi/skills/` | sì (`.md`) | uniti | + +### Esempio reale: ThothII + +``` +harness/.pi/ +├── extensions/ +│ ├── aritmolab-provider.js ← provider LLM solo-progetto +│ ├── tht-gate.js ← gate human-in-the-loop +│ ├── reserved-labels.mjs ← utility condivisa (NON auto-caricata; .mjs ignorato) +│ └── gate/ ← modulo usato da tht-gate.js +├── settings.json ← (opzionale) override delle impostazioni utente +└── themes/ + └── thothii-mono.json ← tema del progetto +``` + +### Comportamento rispetto alla cwd + +La directory da cui lanci `pi` determina quale `.pi/` di progetto viene trovata: + +```bash +# Da harness/ — trova harness/.pi/extensions/aritmolab-provider.js +cd /path/to/ThothII/harness +pi --model aritmolab/qwen3.6-35b-a3b "..." + +# Dalla radice di ThothII — nessun .pi/ trovato lì o nei genitori, solo config utente +cd /path/to/ThothII +pi --model aritmolab/qwen3.6-35b-a3b "..." # ❌ Error: model not found +``` + +Il backend di ThothII (`PiProcessManager`, `list-models.ts`, `model-matrix.mjs`) lancia sempre `pi` con `cwd: harnessDir`, per questo Qwen è visibile in produzione. + +--- + +## Trappola nell'auto-discovery: `.mjs` viene ignorato + +Il pattern di auto-discovery delle estensioni in Pi è **`/\.(ts|js)$/`** — non include `.mjs`. + +``` +.pi/extensions/ +├── my-extension.js ✅ auto-caricata +├── my-extension.ts ✅ auto-caricata +├── my-extension.mjs ❌ ignorata silenziosamente (non combacia col pattern) +└── shared-module.mjs ✅ va bene per moduli helper (deliberatamente non caricato come estensione) +``` + +Se serve un modulo condiviso importato da un'estensione, usa `.mjs` proprio per evitare che venga trattato come estensione a sé. + +--- + +## Verifica + +### Elenco modelli +```bash +pi --list-models +``` +Mostra i built-in + i modelli utente da `models.json`. **Non mostra** i provider registrati da estensione (come AritmoLab) — quelli vanno verificati con la cwd giusta. + +### Verifica che un'estensione sia caricata +```bash +cd harness # o la cwd rilevante per il progetto +pi --mode rpc +# poi: {"type": "get_available_models", "id": "1"} +``` +La risposta RPC include tutti i modelli disponibili, inclusi quelli da estensione. + +--- + +## Troubleshooting + +| Problema | Causa | Soluzione | +|---|---|---| +| `Model "X/Y" not found` lanciando da fuori progetto | Il modello è registrato da un'estensione locale, non visibile fuori dalla cwd giusta | Lancia `pi` dalla directory di progetto corretta (es. `harness/`) | +| Estensione non caricata pur essendo nella cartella giusta | File `.mjs` invece di `.js`/`.ts` | Rinomina in `.js` | +| Impostazioni di progetto non applicate | `settings.json` di progetto ha errori di sintassi, o si sta lanciando `pi` dalla cwd sbagliata | Valida il JSON, controlla la cwd | diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 00000000..99cfa341 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,13 @@ +# ThothII — Documentazione + +Benvenuto nella documentazione di ThothII, il datamart builder human-in-the-loop che trasforma domande in linguaggio naturale in SQL validato attraverso un workflow a 8 fasi orchestrato dal coding agent Pi. + +La documentazione è divisa in due aree: + +## ThothII (Documentazione Tecnica) + +Come funziona il sistema: architettura, specifiche di design delle singole funzionalità, piani di implementazione, report di test. Parte da qui: [Panoramica dell'architettura](architecture/overview.md). + +## Considerazioni Generali + +Note operative e di configurazione che non sono specifiche del dominio ThothII ma riguardano l'ambiente di sviluppo condiviso con altri progetti — ad esempio come Pi (il coding agent) risolve i modelli a livello built-in, utente e progetto. Parte da qui: [Configurazione dei modelli in Pi](general/pi-configuration.md). diff --git a/docs/javascripts/layout-init.js b/docs/javascripts/layout-init.js new file mode 100644 index 00000000..4ea0647a --- /dev/null +++ b/docs/javascripts/layout-init.js @@ -0,0 +1,90 @@ +(function () { + function toggleMenus() { + const current = document.querySelector(".bs-sidenav a.current, .bs-sidenav a[aria-current='page']"); + if (!current) { + return; + } + + const activeList = current.closest("ul"); + document.querySelectorAll(".bs-sidenav ul").forEach((list) => { + if (list === activeList || list.contains(current)) { + list.style.display = ""; + return; + } + + const nested = list.parentElement && list.parentElement.parentElement; + if (nested && nested.classList.contains("bs-sidenav")) { + list.style.display = ""; + } + }); + } + + // Keep the content pane's left padding in sync with the actual width + // of the left TOC sidebar. Fixes the windmill default where the sidebar + // can grow up to 350px but the content padding stays at 250px, so a + // wide item ends up overlapping the article body. + function syncTocSidebarWidth() { + const tocPane = document.querySelector(".wm-toc-pane"); + const contentPane = document.querySelector(".wm-content-pane"); + if (!tocPane || !contentPane) { + return; + } + // Skip on small screens where the sidebar is a dropdown / hidden. + if (window.matchMedia("(max-width: 600px)").matches) { + contentPane.style.paddingLeft = ""; + return; + } + if (tocPane.classList.contains("wm-toc-dropdown")) { + return; + } + if (contentPane.parentElement && contentPane.parentElement.classList.contains("wm-toc-hidden")) { + contentPane.style.paddingLeft = ""; + return; + } + const width = Math.ceil(tocPane.getBoundingClientRect().width); + if (width > 0) { + contentPane.style.paddingLeft = width + "px"; + } + } + + function installTocSidebarSync() { + const tocPane = document.querySelector(".wm-toc-pane"); + if (!tocPane) { + return; + } + syncTocSidebarWidth(); + + if (typeof ResizeObserver === "function") { + const ro = new ResizeObserver(syncTocSidebarWidth); + ro.observe(tocPane); + } + + // Re-sync after expand/collapse animations and toggle button clicks. + tocPane.addEventListener("click", function () { + // Bootstrap collapse animation defaults to 350ms. + window.setTimeout(syncTocSidebarWidth, 50); + window.setTimeout(syncTocSidebarWidth, 400); + }); + const tocBtn = document.getElementById("wm-toc-button"); + if (tocBtn) { + tocBtn.addEventListener("click", function () { + window.setTimeout(syncTocSidebarWidth, 50); + window.setTimeout(syncTocSidebarWidth, 400); + }); + } + + window.addEventListener("resize", syncTocSidebarWidth); + window.addEventListener("orientationchange", syncTocSidebarWidth); + } + + function init() { + toggleMenus(); + installTocSidebarSync(); + } + + if (document.readyState === "loading") { + document.addEventListener("DOMContentLoaded", init); + } else { + init(); + } +})(); diff --git a/docs/l2-run-report-2026-06-27.md b/docs/reports/l2-run-report-2026-06-27.md similarity index 100% rename from docs/l2-run-report-2026-06-27.md rename to docs/reports/l2-run-report-2026-06-27.md diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 00000000..0eec5f83 --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,3 @@ +mkdocs>=1.6 +mkdocs-windmill>=1.0.5 +mkdocs-mermaid2-plugin>=1.2.1 diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 00000000..9ceda446 --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,134 @@ +html { + font-size: 62.5%; /* 1rem = 10px */ + width: 100%; +} + +body { + font-size: 1.3rem; /* 13px */ + width: 100%; +} + +.wm-page-content { + width: 100% !important; + box-sizing: border-box !important; + max-width: 1400px !important; + margin-left: auto !important; + margin-right: auto !important; +} + +.wm-content-pane { + width: 100% !important; + max-width: none !important; + box-sizing: border-box !important; +} + +.wm-article, +.col-md-9[role="main"], +[role="main"] .col-md-9, +[role="main"] { + width: 100% !important; + box-sizing: border-box !important; + max-width: 1400px !important; + margin-left: auto !important; + margin-right: auto !important; +} + +@media (min-width: 992px) { + .container, + .container-fluid { + width: 100% !important; + box-sizing: border-box !important; + max-width: 1400px !important; + margin-left: auto !important; + margin-right: auto !important; + padding-left: 24px; + padding-right: 24px; + } +} + +@media (min-width: 900px) and (max-width: 1199px) { + .wm-toc-pane { + min-width: 200px; + width: 200px; + } + + .wm-content-pane { + padding-left: 200px; + } +} + +@media (max-width: 899px) { + .wm-toc-pane { + margin-left: -250px; + } + + .wm-content-pane { + padding-left: 0; + } +} + +.wm-article { + display: block !important; +} + +/* Headings — scala gerarchica (base: 1rem = 10px) */ +.wm-page-content h1 { font-size: 2.0rem; } /* 20px */ +.wm-page-content h2 { font-size: 1.8rem; } /* 18px */ +.wm-page-content h3 { font-size: 1.6rem; } /* 16px */ +.wm-page-content h4 { font-size: 1.4rem; } /* 14px */ +.wm-page-content h5 { font-size: 1.3rem; } /* 13px */ +.wm-page-content h6 { font-size: 1.2rem; } /* 12px */ + +/* Testo corpo */ +.wm-page-content p, +.wm-page-content li, +.wm-page-content blockquote, +.wm-page-content .admonition { + font-size: 1.3rem; /* 13px */ +} + +/* Tabelle */ +.wm-page-content td, +.wm-page-content th { + font-size: 1.2rem; /* 12px */ +} + +/* Codice */ +.wm-page-content .highlight pre, +.wm-page-content pre, +.wm-page-content code { + font-size: 1.2rem; /* 12px */ +} + +/* TOC laterale */ +.wm-toc-pane, +.wm-toc-pane a, +.wm-toctree, +.wm-toctree li, +.wm-toctree .wm-toc-text { + font-size: 1.2rem; /* 12px */ +} + +/* Navbar e ricerca */ +.navbar, +.navbar a, +#wm-search-form, +#mkdocs-search-query { + font-size: 1.2rem; /* 12px */ +} + +.bs-sidebar { + max-height: none; +} + +.table, +table, +pre, +.mermaid { + width: 100%; + max-width: none !important; +} + +table { + table-layout: auto; +} diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..a6f00504 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,76 @@ +site_name: ThothII Docs +site_description: Documentazione tecnica di ThothII e considerazioni generali sull'ambiente di sviluppo +site_url: https://mptyl.github.io/ThothII/ +repo_url: https://github.com/mptyl/ThothII +repo_name: mptyl/ThothII +edit_uri: edit/main/docs/ +docs_dir: docs +site_dir: site +use_directory_urls: true +theme: + name: windmill + highlightjs: true + hljs_languages: + - yaml + - sql + - bash + - python + - json + - typescript +plugins: +- search +- mermaid2 +extra_css: +- stylesheets/extra.css +extra_javascript: +- javascripts/layout-init.js +markdown_extensions: +- admonition +- attr_list +- md_in_html +- tables +- toc: + permalink: true +- pymdownx.details +- pymdownx.highlight: + anchor_linenums: true +- pymdownx.inlinehilite +- pymdownx.snippets +- pymdownx.superfences: + custom_fences: + - name: mermaid + class: mermaid + format: !!python/name:mermaid2.fence_mermaid +- pymdownx.tabbed: + alternate_style: true +nav: +- Home: index.md +- ThothII (Documentazione Tecnica): + - Panoramica Architettura: architecture/overview.md + - Specifiche di Design: + - Architettura ThothII: superpowers/specs/2026-06-25-thothii-architecture-design.md + - Backend: superpowers/specs/2026-06-27-backend-design.md + - Frontend: superpowers/specs/2026-06-27-frontend-design.md + - CLI Port / Skill: superpowers/specs/2026-06-27-cli-port-completo-skill-riscritta-design.md + - Settings Menu: superpowers/specs/2026-06-28-settings-menu-design.md + - Ollama Ensure: superpowers/specs/2026-06-29-ollama-ensure-design.md + - Session Management: superpowers/specs/2026-06-29-session-management-design.md + - Session UI Refinements: superpowers/specs/2026-06-29-session-ui-refinements-design.md + - Workflow Contract Hardening: superpowers/specs/2026-07-01-workflow-contract-hardening-design.md + - Piani di Implementazione: + - Harness: superpowers/plans/2026-06-25-harness-implementation.md + - Backend: superpowers/plans/2026-06-27-backend-implementation.md + - Frontend: superpowers/plans/2026-06-27-frontend-implementation.md + - Harness RPC Readiness: superpowers/plans/2026-06-27-harness-rpc-readiness.md + - CLI Porting / Skill: superpowers/plans/2026-06-27-tht-porting-cli-skill.md + - Settings Menu: superpowers/plans/2026-06-28-settings-menu.md + - Ollama Ensure: superpowers/plans/2026-06-29-ollama-ensure.md + - Session Management: superpowers/plans/2026-06-29-session-management.md + - Session UI Refinements: superpowers/plans/2026-06-29-session-ui-refinements.md + - Cross-Model Behavior Matrix: superpowers/plans/2026-06-30-cross-model-behavior-matrix.md + - Workflow Contract Hardening: superpowers/plans/2026-07-01-workflow-contract-hardening.md + - Report: + - L2 Run Report (2026-06-27): reports/l2-run-report-2026-06-27.md + - "Stato e Ripresa (snapshot 2026-06-27, superato da PROJECT_STATE.md)": superpowers/2026-06-27-stato-e-ripresa.md +- Considerazioni Generali: + - Configurazione dei modelli in Pi: general/pi-configuration.md