Files
davideandClaude Sonnet 5.5 f2086de31d ADR-0007: schema di una wiki interrogabile con immagini; documentazione generale
- Nuovo ADR-0007: convenzione in tre parti (indice con gli id delle figure,
  catalogo JSON con campi minimi, istruzioni solo-query) e ripartizione dei
  compiti tra wiki, motore e app. Nessuna cartella o formato imposti dall'app.
- ADR-0006, README, ROADMAP, PROJECT_STATE, TESTING: esempi resi generici
  (nessun riferimento a una wiki specifica) e nota sull'assenza di uno standard.
- Test delle immagini con struttura e testi neutri.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-15 16:11:00 +02:00

25 KiB
Raw Permalink Blame History

Piano dei test

Decisioni (strumenti, livelli, struttura): ADR-0003. Qui: regola, flusso, soglie e matrice requisito → test, sorgente di verità per la copertura. Le spunte [ ] passano a [x] quando il test esiste e passa.

Regola

Nuova funzione, correzione o cambio di comportamento ⇒ test nello stesso commit. Niente test, funzione non finita.

  • Una nuova funzione aggiunge righe alla matrice qui sotto (con ID) prima di scrivere il codice.
  • Una correzione di bug parte da un test che fallisce e lo lascia come regressione.
  • Una modifica che cambia un requisito aggiorna prima il doc, poi la riga della matrice, poi i test, poi il codice.
  • Una riga senza test non è copertura: va lasciata [ ] e conta come debito visibile.

Flusso (estende il doc-first di README.md)

ADR (se serve) → MVP.md (requisito e criterio) → riga in questa matrice → test che falliscono → codice → test verdi → ROADMAP/README/AGENT.md.

Livelli

Livello Cosa prova Come
U — unitario Core/ e MainViewModel xUnit, finto runner, cartella dati temporanea
R — renderer MarkdownView xUnit + Headless, asserzioni sull'albero visuale
G — GUI headless MainWindow, template, tastiera, finestre di dialogo xUnit + Headless, senza schermo
P — processo avvio reale di un processo (Claude) FakeClaude nel PATH
E — end-to-end l'eseguibile pubblicato (CLI, 127, exit code) publish + processo figlio + FakeClaude

Struttura

agent-wiki-ui.slnx
src/agent-wiki-ui/            app (Core/, Gui/, Program.cs)
tests/agent-wiki-ui.Tests/    Support/ (TestApp, PngFactory), Gui/ (R, G), Process/ (P), Core/ (U, quando arrivano), E2E/ (E)
tests/FakeClaude/             eseguibile finto `claude` (vedi sotto)

Una cartella per livello, creata quando c'è il primo test; il livello si dichiara anche con [Trait("Category", "Unit" | "Gui" | "Process" | "E2E")].

FakeClaude

Piccolo eseguibile (AssemblyName claude, nel PATH dei test) che prende il posto del vero motore. Un test lo configura con variabili d'ambiente del processo che avvia:

Variabile Effetto
FAKE_CLAUDE_LOG file in cui accoda una riga JSON per invocazione: {"args": [...], "cwd": "...", "stdin": "..."}
FAKE_CLAUDE_OUT testo scritto su stdout (anche per --version)
FAKE_CLAUDE_ERR testo scritto su stderr
FAKE_CLAUDE_EXIT exit code (predefinito 0)
FAKE_CLAUDE_DELAY_MS attesa prima di rispondere

Legge stdin fino alla fine e lo registra: se il chiamante non lo chiude, il processo non termina (così CL-05 è verificabile). Il percorso del file compilato lo fornisce l'helper di test FakeClaudePath.

Predisposizioni di testabilità (prerequisito dei test)

  • ChatStore come istanza con cartella iniettata (oggi statico su LocalApplicationData)
  • IEngineRunner dietro Core/EngineRunner.cs, iniettato nel MainViewModel
  • EngineUpdater.CheckAsync accetta un HttpClient: i test usano un gestore finto (rete assente, risposta non valida, versioni di prova)
  • InternalsVisibleTo verso il progetto di test
  • Spostamento in src/agent-wiki-ui/ e tests/ con soluzione unica agent-wiki-ui.slnx

Soglie di copertura (la build fallisce sotto soglia)

Area Righe Rami
Core/ ≥ 95% ≥ 90%
Gui/MainViewModel ≥ 95% ≥ 90%
Gui/MarkdownView ≥ 90% ≥ 85%
Gui/MainWindow*, ConfirmDialog (code-behind) ≥ 85% —
Totale ≥ 90% —

Esclusi dal calcolo: XAML generato, Program.cs (tre righe, coperte da E2E), App.axaml.cs. La soglia non sostituisce la matrice: copertura di righe alta con requisiti scoperti non basta.

Matrice requisito → test

Fonte dei requisiti: MVP.md e gli ADR. Livello: vedi sopra. Il nome del test è indicativo.

Avvio dei motori — Core/EngineRunner.cs

ID Requisito Liv. Test
CL-01 Il prompt è un solo argomento, anche con virgolette e spazi (criterio MVP 4) U/P Prompt_con_virgolette_arriva_intatto [ ]
CL-02 Primo messaggio: --session-id <guid>; successivi: --resume <guid> U Sessione_prima_e_ripresa [ ]
CL-03 --model/--effort omessi se vuoti, presenti se valorizzati U Flag_opzionali [ ]
CL-04 Cartella di lavoro = cartella dell'exe, non la cwd del chiamante (criterio MVP 1) U/P Cartella_di_lavoro_e_quella_dell_exe [ ]
CL-05 Stdin chiuso subito: nessuna attesa di 3 s P Stdin_chiuso_non_blocca [ ]
CL-06 CLI: l'exit code di claude è propagato (criterio MVP 3) P/E ExitCode_propagato [ ]
CL-07 CLI: eseguibile del motore assente ⇒ messaggio chiaro (con il nome dell'eseguibile) ed exit code 127 P/E Claude_assente_127 [ ]
CL-08 CLI: stdout/stderr ereditati e ritrasmessi (criterio MVP 2: streaming) E Output_ereditato_in_tempo_reale [ ]
CL-09 GUI: output catturato e ripulito agli estremi; stderr separato P Output_catturato [ ]
CL-10 GUI: claude assente ⇒ eccezione riconoscibile, non crash P Claude_assente_in_GUI [ ]
CL-11 Il catalogo modelli contiene gli ID attesi e gli effort previsti U Catalogo_modelli_ed_effort [ ]
CL-12 Senza argomenti non parte la CLI; con argomenti sì (tutti uniti in un prompt) E Argomenti_uniti_in_un_prompt [ ]

Codex — Core/Engine.cs (parser e argomenti), Core/EngineRunner.cs

Le righe CL valgono per ogni motore; queste sono specifiche di Codex (ADR-0002). Il parser si prova con output JSONL reali salvati nei test.

ID Requisito Liv. Test
CX-01 Primo messaggio: exec --json --skip-git-repo-check -s read-only … -- <prompt> U Codex_primo_messaggio [ ]
CX-02 Ripresa: exec resume --json … -c sandbox_mode="read-only" <id> -- <prompt>, senza -s U Codex_ripresa [ ]
CX-03 Un prompt che inizia con - arriva intatto (grazie a --) U/P Codex_prompt_con_trattino [ ]
CX-04 Modello ⇒ -m; effort ⇒ -c model_reasoning_effort=<livello>; vuoti ⇒ omessi U Codex_modello_ed_effort [ ]
CX-05 Il parser legge thread_id da thread.started U Codex_thread_id [ ]
CX-06 La risposta è l'ultimo agent_message, anche con più messaggi U Codex_ultimo_agent_message [ ]
CX-07 turn.failed: messaggio interno di error.message estratto dal JSON annidato; exit ≠ 0 ⇒ errore U Codex_errore_turno [ ]
CX-08 Eventi item.completed di tipo error (avvisi) non fanno fallire la risposta U Codex_avvisi_ignorati [ ]
CX-09 Exit 0 senza agent_message ⇒ errore "nessuna risposta" U Codex_nessuna_risposta [ ]
CX-10 Righe non JSON o eventi sconosciuti sono ignorati senza eccezioni U Codex_righe_non_json [ ]
CX-11 In modalità CLI (output ereditato) non si usa --json U Codex_cli_senza_json [ ]
CX-12 Con un FakeClaude configurato come Codex il ciclo primo messaggio + ripresa funziona (id letto e riusato) P Codex_ciclo_completo_con_finto [ ]

Aggiornamento dei CLI — Core/EngineUpdater.cs, Gui/MainViewModel.cs (ADR-0004)

Si provano con FakeClaude/FakeCodex che rispondono a --version e update; nessun test aggiorna un CLI reale.

ID Requisito Liv. Test
UP-01 Versione letta da --version (prima riga ripulita); eseguibile assente ⇒ versione nulla P Versione_letta [ ]
UP-02 Versione cambiata dopo update ⇒ esito "Aggiornato da X a Y" P Aggiornato [ ]
UP-03 Exit 0 e versione invariata ⇒ "Già aggiornato (X)" P Gia_aggiornato [ ]
UP-04 Exit ≠ 0 ⇒ errore con le ultime righe dell'output e il comando manuale P Aggiornamento_fallito [ ]
UP-05 Tempo massimo superato ⇒ processo terminato ed errore chiaro P Aggiornamento_scaduto [ ]
UP-06 Eseguibile assente ⇒ riga non offerta / errore "non trovato" U Aggiornamento_senza_eseguibile [ ]
UP-07 Metodo di installazione dedotto dal percorso reale (npm, Homebrew, WinGet, nativo) con collegamenti simbolici risolti U Metodo_di_installazione [ ]
UP-08 Comando manuale corretto per ogni coppia motore × metodo (tabella dell'ADR-0004) U Comando_manuale [ ]
UP-09 Un solo aggiornamento alla volta; durante una risposta in corso i pulsanti sono disabilitati e la chat non parte durante l'aggiornamento U Aggiornamento_esclusivo [ ]
UP-10 Dopo un aggiornamento riuscito le versioni mostrate si rileggono; la chat aperta resta invariata U Versioni_rilette [ ]
UP-11 Le righe di aggiornamento compaiono solo per i CLI installati U/G Righe_solo_installati [ ]
UP-12 Il pulsante Aggiorna del riquadro agisce solo sul CLI della sua riga G Pulsante_per_riga [ ]
UP-13 Nessun aggiornamento parte senza un clic U Nessun_aggiornamento_automatico [ ]
UP-14 Claude Code: l'ultima versione si legge dal testo di …/claude-code-releases/latest (spazi e a capo ripuliti) U Ultima_versione_claude [ ]
UP-15 Codex: l'ultima versione si legge da tag_name della release GitHub (rust-v0.162.1 ⇒ 0.162.1); intestazione User-Agent inviata U Ultima_versione_codex [ ]
UP-16 Confronto: ultima > installata ⇒ disponibile; uguale o più nuova ⇒ aggiornato; versioni con testo attorno (2.1.300 (Claude Code), codex-cli 0.162.1) lette bene U Confronto_versioni [ ]
UP-17 Rete assente, risposta non valida o timeout ⇒ stato "sconosciuto", nessuna eccezione, pulsante normale U Controllo_senza_rete [ ]
UP-18 Disponibile ⇒ riga con "Aggiornamento disponibile: X", pulsante evidenziato e puntino sul pulsante Impostazioni; aggiornato ⇒ nessuno dei tre U/G Evidenziazione_aggiornamento [ ]
UP-19 Il controllo parte all'avvio e all'apertura del riquadro solo se l'ultimo ha più di 5 minuti; dopo un aggiornamento riuscito si ripete; non blocca invio né interfaccia U Quando_si_controlla [ ]
UP-20 Il controllo non installa nulla e non modifica i CLI P Controllo_in_sola_lettura [ ]

Cronologia — Core/ChatStore.cs, Core/AppInfo.cs

ID Requisito Liv. Test
ST-01 Salvataggio e rilettura: id, titolo, data, started, messaggi con ruolo e testo U Salva_e_rileggi [ ]
ST-02 Una chat senza messaggi non viene salvata U Chat_vuota_non_salvata [ ]
ST-03 Titolo = inizio del primo messaggio utente: 50 caratteri + "…", a capo sostituiti da spazi U Titolo_troncato [ ]
ST-04 L'id deve essere un Guid: un id con .. o separatori non tocca il disco fuori dalla cartella U Id_non_guid_rifiutato [ ]
ST-05 L'elenco è ordinato dalla più recente U Elenco_ordinato [ ]
ST-06 File JSON corrotto ignorato senza eccezioni U File_corrotto_ignorato [ ]
ST-07 Eliminazione: rimuove solo il file di quella chat; id inesistente senza errori U Elimina_chat [ ]
ST-08 Compatibilità del formato: un JSON scritto dalla versione WinForms si legge U Formato_storico_compatibile [ ]
ST-09 Migrazione: la cartella di un nome precedente (LlmRun) si sposta nella nuova al primo avvio; se la nuova esiste non si tocca nulla U Migrazione_da_nome_precedente [ ]
ST-10 AppInfo.Name = AssemblyName del csproj U Nome_da_assembly [ ]
ST-12 Il JSON salva Engine e SessionId; un file senza questi campi si legge come chat di Claude Code con SessionId = id U Motore_e_sessione_salvati_e_compatibilita [ ]
ST-11 Errore di I/O nel salvataggio non perde la chat a schermo U vedi VM-12 [ ]

Logica della chat — Gui/MainViewModel.cs

ID Requisito Liv. Test
VM-01 Senza chat salvate: schermata iniziale (ShowEmpty), elenco vuoto U Avvio_senza_chat [ ]
VM-02 All'avvio si riapre la chat più recente U Avvio_riapre_ultima [ ]
VM-03 CanSend falso se il testo è vuoto o solo spazi, o se occupato U CanSend [ ]
VM-04 Invio: il messaggio utente compare e viene salvato prima della risposta U Messaggio_salvato_prima_della_risposta [ ]
VM-05 Risposta riuscita: aggiunta come "ai", started diventa vero, il secondo invio usa --resume U Risposta_e_ripresa [ ]
VM-06 Risposta fallita (exit ≠ 0): messaggio "err" con codice e stderr; started resta falso e il tentativo successivo usa ancora --session-id U Errore_non_avvia_la_sessione [ ]
VM-07 claude assente: messaggio "'claude' non trovato nel PATH." U Claude_assente_messaggio [ ]
VM-08 Durante l'attesa: Invia e Nuova chat disabilitati; aprire/eliminare è ignorato U Occupato_blocca_azioni [ ]
VM-09 Modello: "Predefinito" ⇒ nessun flag; modello scelto ⇒ ID; "Altro ID…" ⇒ testo libero ripulito U Scelta_modello [ ]
VM-10 Effort: "Predefinito" ⇒ nessun flag; altrimenti il valore U Scelta_effort [ ]
VM-20 Valori iniziali: modello più piccolo del motore (Claude Code: Haiku 5.5; Codex: GPT-5.6 Luna) ed effort low; il primo invio passa --model/--effort (o -m/-c model_reasoning_effort) con quei valori U Valori_iniziali [ ]
VM-11 Nuova chat: svuota la vista, nuovo guid, started falso, elenco aggiornato U Nuova_chat [ ]
VM-12 Errore di I/O nel salvataggio non interrompe l'invio né cancella i messaggi U Salvataggio_fallito_non_perde_chat [ ]
VM-13 Apertura chat: carica messaggi, started e id; chat inesistente ⇒ elenco ricaricato U Apri_chat [ ]
VM-14 Eliminazione: con conferma rimuove; senza conferma non fa nulla; se è la chat aperta parte una nuova U Elimina_con_e_senza_conferma [ ]
VM-16 Barra laterale: il comando commuta SidebarOpen U Barra_laterale [ ]
VM-17 Copia: il comando passa il testo alla funzione degli appunti U Copia_negli_appunti [ ]
VM-18 Notifiche di proprietà: HasMessages, ShowEmpty, CanSend, IsCustomModel cambiano quando devono U Notifiche_proprieta [ ]
VM-19 Il titolo e la data dell'elenco riflettono l'ultimo scambio; la chat aperta è marcata attiva U Elenco_chat_attiva [ ]

Renderer markdown — Gui/MarkdownView.cs

ID Requisito Liv. Test
MD-01 Sorgente vuota o nulla ⇒ nessun contenuto, senza errori R Sorgente_vuota [ ]
MD-02 Titoli h1–h6 con dimensioni decrescenti e peso semi-grassetto R Titoli [ ]
MD-03 Paragrafi; a capo morbido = spazio, a capo forzato = riga nuova R A_capo [ ]
MD-04 Grassetto, corsivo, barrato, anche annidati R Enfasi [ ]
MD-05 Codice inline in carattere monospazio con sfondo R Codice_inline [ ]
MD-06 Blocco di codice: monospazio, scorrimento orizzontale, pulsante Copia che copia solo il codice R/G Blocco_codice_e_copia [ ]
MD-07 Liste puntate e numerate (rispetta il numero iniziale), annidate R Liste [ ]
MD-08 Citazioni con barra laterale, anche annidate R Citazioni [ ]
MD-09 Tabelle: intestazione in evidenza, allineamenti sinistra/centro/destra, righe irregolari R Tabelle [ ]
MD-10 Linea orizzontale R Linea_orizzontale [ ]
MD-11 Link: colore d'accento e sottolineatura; il clic apre solo http(s) R Link_http_https [ ]
MD-12 Link: nessuna apertura se c'è una selezione in corso; cursore a mano sopra il link R Link_con_selezione [ ]
MD-13 Posizioni dei link corrette con enfasi, codice inline e a capo prima del link R Intervalli_link [ ]
MD-14 Immagini con URL http(s) o altro schema: si mostra il testo alternativo, nessuna richiesta di rete R Immagini_remote_come_testo [x]
MD-19 Immagine con percorso assoluto di un file png valido ⇒ controllo immagine con le dimensioni attese (ADR-0006) R Immagine_percorso_assoluto [x]
MD-20 Percorso relativo risolto rispetto a AppContext.BaseDirectory; anche URI file:// R Immagine_percorso_relativo_e_file_uri [x]
MD-21 File mancante, illeggibile, corrotto o con estensione non ammessa ⇒ testo alternativo, nessuna eccezione R Immagine_non_valida_ripiego [x]
MD-22 File oltre il limite di 20 MB ⇒ testo alternativo, file non decodificato R Immagine_oltre_limite [x]
MD-23 Immagine più larga della colonna ⇒ ridotta in larghezza mantenendo le proporzioni; mai ingrandita oltre l'originale R Immagine_larghezza_massima [x]
MD-24 Il testo alternativo è nome accessibile e suggerimento dell'immagine R Immagine_testo_alternativo_accessibile [x]
MD-25 Immagine dentro un link, in una lista o in una tabella ⇒ resa senza rompere intervalli dei link (MD-13) né il layout R Immagine_in_contesti_annidati [x]
MD-26 Cambio di tema con immagini presenti ⇒ vista ricostruita, immagini ancora mostrate R Immagine_cambio_tema [x]
MD-27 Il caricamento è in background: subito dopo il rendering c'è il segnaposto [alt] e un'immagine in attesa; a fine decodifica compare l'immagine; un file corrotto lascia [alt] R Immagine_caricamento_in_background [x]
MD-28 Percorso relativo non presente nella cartella dell'exe ma in una cartella superiore (radice del progetto, es. figure/<file> con l'exe in una sottocartella) ⇒ immagine mostrata R Immagine_percorso_relativo_alla_radice [x]
MD-29 Se il file esiste in più cartelle, vince la più vicina all'exe; se non esiste in nessuna ⇒ testo alternativo R Immagine_cartella_piu_vicina [x]
MD-30 Struttura tipo wiki (catalogo JSON + cartella immagini + risposta con immagine, didascalia e link [[fig-NNN]] sotto): l'immagine compare e la didascalia resta testo; l'app non legge il JSON R Immagine_risposta_stile_wiki [x]
MD-15 HTML grezzo disabilitato: i tag compaiono come testo, non come elementi R Html_disabilitato [ ]
MD-16 Cambio di tema (chiaro/scuro): i colori si aggiornano ricostruendo la vista R Cambio_tema [ ]
MD-17 Markdown malformato o blocchi sconosciuti non fanno crashare R Markdown_malformato [ ]
MD-18 Testo selezionabile R Testo_selezionabile [ ]

Finestra e interazione — Gui/MainWindow*, Gui/App.axaml, Gui/ConfirmDialog.cs

ID Requisito Liv. Test
UI-01 La finestra si apre e mostra la schermata iniziale (logo, titolo, sottotitolo, nessun suggerimento) G Apertura_schermata_iniziale [ ]
UI-02 Proporzioni 16:10, 75% dell'area utile (max 1440), minimo 900x600; senza schermo primario 1280x800 G Dimensioni_finestra [ ]
UI-03 Invio invia, Maiusc+Invio va a capo, nessun invio a campo vuoto G Tasti_invio [ ]
UI-04 Il pulsante Invia è disabilitato con campo vuoto o in attesa G Pulsante_invia [ ]
UI-05 I messaggi hanno aspetto per ruolo: utente, Claude (con Copia), errore G Template_per_ruolo [ ]
UI-06 La conversazione scorre in fondo a ogni nuovo messaggio G Scorrimento_in_fondo [ ]
UI-07 Indicatore di attesa visibile solo durante l'elaborazione G Indicatore_attesa [ ]
UI-08 Elenco chat: voce attiva evidenziata, clic apre, ✕ elimina; "Nessuna chat salvata" se vuoto G Elenco_chat [ ]
UI-09 Nel riquadro Impostazioni il campo "Altro ID…" compare solo con quella voce del modello G Campo_modello_personalizzato [ ]
UI-10 Il pulsante a tre linee mostra/nasconde la barra laterale G Mostra_nascondi_barra [ ]
UI-11 Dialogo di conferma: restituisce vero con Elimina, falso con Annulla o chiusura G Dialogo_conferma [ ]
UI-12 Accessibilità: ogni pulsante a sola icona e il campo messaggio hanno AutomationProperties.Name G Nomi_accessibili [ ]
UI-13 Tema: sia il chiaro sia lo scuro risolvono tutti i token usati (nessuna risorsa mancante) G Token_tema_completi [ ]
UI-14 Focus sul campo messaggio all'apertura, dopo la risposta e dopo "Nuova chat" G Focus_campo [ ]
UI-16 Il pulsante Impostazioni (in alto a destra) apre il riquadro con Modello ed Effort; Esc lo chiude G Riquadro_impostazioni [ ]
UI-17 Il composer non contiene selettori di modello ed effort G Composer_senza_selettori [ ]
UI-18 Le scelte fatte nel riquadro arrivano ai flag --model/--effort del messaggio successivo G/U Impostazioni_applicate_all_invio [ ]
UI-15 Il nome dell'app compare nel titolo della finestra e nella barra laterale G Nome_app_visibile [ ]

Eseguibile pubblicato

Righe WIN: console su Windows (ADR-0005).

ID Requisito Liv. Test
WIN-01 L'eseguibile win-x64 pubblicato ha sottosistema "Windows GUI" (intestazione PE); quello linux-x64 non è interessato E Sottosistema_gui [ ]
WIN-02 CLI con output reindirizzato su file o pipe: l'output arriva, handle ereditati non toccati E Cli_con_output_reindirizzato [ ]
WIN-03 CLI da un terminale: output visibile (AttachConsole + CONOUT$); senza terminale padre l'attacco fallisce in silenzio e l'app prosegue E (manuale su Windows nativo) Cli_con_terminale_padre [ ]
WIN-04 Exit code corretto quando il chiamante attende il processo (start /wait, Start-Process -Wait) E (manuale su Windows nativo) ExitCode_con_attesa [ ]
WIN-05 Il codice di ConsoleHost non fa nulla su Linux/macOS U ConsoleHost_non_windows [ ]
ID Requisito Liv. Test
PUB-01 Il publish single-file linux-x64 si compila e la CLI risponde con FakeClaude E Publish_linux_smoke [ ]
PUB-02 Il publish single-file win-x64 si compila e la CLI risponde con FakeClaude E Publish_windows_smoke [ ]
PUB-03 Le librerie native (Skia/HarfBuzz) vengono estratte e la GUI si avvia (provata con timeout) E Gui_si_avvia [ ]

Più motori (ADR-0002) — da compilare quando si implementa la Fase 4

Per ogni motore, la stessa batteria di contratto:

ID Requisito Liv.
EN-01 Argomenti del primo messaggio e della ripresa (Claude: CL-02; Codex: CX-01, CX-02) U [ ]
EN-02 Rilevamento nel PATH; assente ⇒ disabilitato e messaggio chiaro U/P [ ]
EN-03 Lettura dell'id di sessione dall'output (Codex: CX-05) U [ ]
EN-04 Parser dell'output → markdown, con output di esempio reali salvati nei test U [ ]
EN-05 Modelli ed effort mostrati secondo il motore U/G [ ]
EN-06 Il JSON della chat memorizza il motore; cambiare motore apre una nuova chat U [ ]
EN-07 Politica dei permessi: nessun flag che salta i controlli senza scelta esplicita U [ ]
EN-08 Impostazioni persistite e rilette U [ ]
EN-09 Gestione del blocco di agy -p con output rediretto (timeout, errore chiaro) P [ ]
EN-10 Engines.Find per id (claude, codex, sconosciuto ⇒ nullo); l'id salvato nei JSON resta stabile U [ ]
EN-11 Cambiare CLI nelle Impostazioni apre una nuova chat con quel motore; modello ed effort tornano ai valori iniziali del nuovo motore (modello più piccolo, low); liste secondo il motore U [ ]
EN-12 Motore non installato: etichetta "non installato", non selezionabile; il VM rifiuta la selezione U/G [ ]
EN-13 L'interruttore CLI è disabilitato durante l'attesa U/G [ ]
EN-14 Aprendo una chat salvata il selettore passa al motore della chat; sessione e started coerenti U [ ]
EN-15 Etichetta autore, segnaposto, messaggio d'attesa ed elenco chat mostrano il nome del motore U/G [ ]
EN-16 Dopo il primo invio con Codex il SessionId è quello letto dall'output e il secondo invio usa la ripresa; con errore al primo invio resta senza sessione U [ ]
EN-17 CLI --engine <id> "prompt"; id sconosciuto o prompt mancante ⇒ uso su stderr ed exit 2; senza --engine ⇒ Claude Code E [ ]
EN-18 Rilevamento nel PATH: nome esatto su Linux, .exe su Windows; cartella inesistente nel PATH ignorata U [ ]

FakeClaude — tests/FakeClaude

ID Requisito Liv. Test
FK-01 Registra argomenti (anche con virgolette e spazi, uno per elemento), cartella di lavoro e stdin P Registra_argomenti_cwd_e_stdin [x]
FK-02 Scrive su stdout e stderr il testo configurato P Output_e_stderr_configurati [x]
FK-03 L'exit code configurato è quello del processo P ExitCode_configurato [x]
FK-04 Il ritardo configurato è rispettato P Ritardo_configurato [x]
FK-05 Termina solo dopo la chiusura di stdin P Attende_la_chiusura_di_stdin [x]

Come si eseguono (a implementazione avvenuta)

Comandi previsti, da confermare con ADR-0003 → "Da verificare":

  • Tutti i test: dotnet test
  • Con copertura e soglie: dotnet test --collect:"XPlat Code Coverage" e controllo delle soglie della tabella sopra
  • Solo una categoria: dotnet test --filter "Category=Unit" (o Gui, Process, E2E) Su Linux i test GUI girano senza display (Headless).

Definition of Done di una modifica

  • Doc aggiornati (MVP, ROADMAP, ADR se serve)
  • Righe nuove o modificate nella matrice, con ID
  • Test scritti e verdi su Windows e Linux
  • Soglie di copertura rispettate
  • Nessun requisito della modifica resta con la casella [ ] senza motivo scritto