Linter Personalizzabile
# Blueprint — Linter personalizzabile (visibilità + tuning)
> Stato: **design, no codice**. Feature in due fasi rilasciabili indipendentemente.
> Fase 3 (regole custom utente) **congelata** per scelta esplicita — vedi §7.
> Origine: discussione 2026-06-14 su come rendere visibili/modificabili le
> regole di diagnosi (`linting.rs`) e permettere all'utente di gestirle.
## 1. Obiettivo
Oggi le 11 regole del linter sono funzioni Rust hardcoded in
`apps/client/src-tauri/src/linting.rs`, con costanti compile-time e nessuna
superficie utente oltre al toggle per-categoria (che esiste in
`PannelloLinter.svelte` ma **non è montato** in Impostazioni).
Vogliamo:
- **Fase 1 — Visibilità**: catalogo in-app delle regole (cosa controlla
ciascuna, severità, categoria) come singola fonte di verità dal backend, e
toggle a granularità **singola regola** (non solo categoria).
- **Fase 2 — Tuning**: override di severità (es. declassare un `Error` a
`Warning`) e soglie editabili (`LEN_MAX_BODY`, `LEN_MIN_BODY`,
`NGRAM_THRESHOLD`).
Vincoli trasversali: **tutto additivo**, default = comportamento attuale,
zero migrazioni distruttive, nessuna duplicazione delle descrizioni regola
fra Rust e TS.
## 2. Stato attuale (cosa riusiamo)
| Pezzo | File | Note |
| --- | --- | --- |
| Logica 11 regole | `src-tauri/src/linting.rs` | funzioni `regola_*` + `analizza()` / `analizza_completo()` |
| Comando lint | `linting.rs:567` `prompt_lint(body, prompt_id, categorie_disabilitate, state)` | unico caller è il frontend |
| Filtro categorie | `linting.rs:545` `filtra_categorie(issues, &[String])` | filtra per **prefisso alfabetico** del `code` |
| Costanti | `linting.rs:121-126` | `LEN_MAX_BODY=4000`, `LEN_MIN_BODY=30`, `NGRAM_SIZE=3`, `NGRAM_THRESHOLD=4` |
| Pref categorie (TS) | `src/lib/preferenze-linter.ts` | `localStorage` key `pap.linter.categorie_disabilitate`; etichette+descrizioni per categoria |
| UI toggle (non montata) | `src/lib/components/PannelloLinter.svelte` | card per categoria; esportata in `components/index.ts` |
| Tab diagnosi | `src/lib/components/DiagnosiTab.svelte` | invoca `prompt_lint`, debounce 400ms, passa `categorieDisabilitate` |
| Impostazioni | `src/lib/superfici/ImpostazioniModal.svelte` | `subSezioni[]` (riga 331); render accordion per `sub.id` |
| Persistenza globale backend | `src-tauri/src/preferenze.rs` | `Preferenze` struct + `preferenze.json` in data-dir + comandi carica/salva |
**Decisione persistenza**: il modello attuale è *frontend-owns-config →
passa al backend come parametro di `prompt_lint` per chiamata*. Lo
manteniamo: nessuna nuova persistenza backend, la config vive in
`localStorage` e viaggia come parametro. Quando atterrerà *vault-a-cartella*
(`docs/roadmap/vault-a-cartella.md`, ancora design), il blob `localStorage`
migrerà in `.pap/linter.json` per seguire il vault — ma **non** è
prerequisito di questa feature (YAGNI).
## 3. Decisioni di design
1. **Catalogo = singola fonte di verità nel Rust.** Le descrizioni regola
NON vanno duplicate in TS. Nuovo comando `prompt_lint_regole()` che
ritorna i metadati. Le mappe `ETICHETTE`/`DESCRIZIONI` in
`preferenze-linter.ts` vengono **deprecate** a favore dei dati dal
backend (restano per le 5 *categorie*, non per le regole).
2. **Granularità per-regola riusa il filtro esistente.** Generalizziamo
`filtra_categorie`: un token disabilitato matcha un issue se è uguale al
`code` completo (`"PII001"`) **oppure** al prefisso alfabetico
(`"PII"`). Retrocompatibile: `["PII"]` continua a disabilitare la
famiglia.
3. **Config come un solo oggetto.** Fase 2 sostituisce il parametro
`categorie_disabilitate: Option<Vec<String>>` con
`config: Option<ConfigLinter>` (superset). Il caller è solo il frontend →
nessun consumatore esterno rotto.
4. **Override severità in post-pass.** Non tocchiamo le singole `regola_*`:
applichiamo gli override in una passata finale su `Vec<Issue>`.
5. **Soglie con default = costanti attuali.** `SoglieLinter::default()`
riproduce 4000/30/4 → assenza di config ⇒ comportamento identico a oggi
(regression-safe).
## 4. Fase 1 — Visibilità + toggle per-regola
### 4.1 Backend (`linting.rs`)
Nuovo tipo metadati + registro statico:when to use it
Community prompt sourced from the open-source GitHub repo robertomarchioro/prompt-a-porter (AGPL-3.0). A "Linter Personalizzabile" style prompt — adapt the placeholders and specifics to your task. Imported as-is and not independently retested here, so check the output before relying on it.
tags
roleplaycommunitygeneral
source
robertomarchioro/prompt-a-porter · AGPL-3.0