home/roleplay/linter-personalizzabile

Linter Personalizzabile

GPTClaudeGemini··313 copies·updated 2026-07-14
linter-personalizzabile.prompt
# 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