# Fare il lint delle specifiche in CI con un linter di specifiche

Canonical: https://specscore.md/it/articles/lint-specs-in-ci/

Ultimo aggiornamento: 4 novembre 2026

Un linter di specifiche è un programma che controlla una specifica alla ricerca di errori di struttura ed esce con un codice di errore quando li trova. L’[integrazione continua](https://specscore.md/it/validators/) (CI, continuous integration) è un controllo automatico su ogni modifica proposta. L’integrazione continua e la consegna continua (CI/CD, continuous integration and continuous delivery) è la pipeline che esegue quel controllo e mantiene rilasciabile una modifica che passa. Lo [sviluppo guidato dalle specifiche](https://specscore.md/it/spec-driven-development/) (SDD, spec-driven development) è la pratica di scrivere la specifica prima del codice e di trattare la specifica come fonte di verità. Un documento dei requisiti di prodotto (PRD, product requirements document) è la prosa che enuncia il problema e l’ambito. In [SpecScore](https://specscore.md/), un requisito (REQ) è una regola con nome dentro una funzionalità, e un criterio di accettazione (AC, acceptance criterion) è una condizione astratta facoltativa che punta a una o più di quelle regole. Il controllo è un comando dell’[interfaccia a riga di comando](https://specscore.md/it/cli/) (CLI, command-line interface), `specscore spec lint`, della CLI in [specscore/specscore-cli](https://github.com/specscore/specscore-cli) ([Apache-2.0](https://github.com/specscore/specscore-cli/blob/main/LICENSE)). [Easy Approach to Requirements Syntax](https://specscore.md/it/articles/ears-requirements/) (EARS) è un modello di frase per un requisito. Questo linter controlla i titoli, le sezioni obbligatorie e i riferimenti. Non valuta l’inglese.

## Che cosa significa fare il lint di una specifica

Fare il lint di una specifica è lo stesso tipo di controllo che fare il lint del codice. Un programma deterministico legge i file e segnala violazioni di regole. Non decide se il prodotto è una buona idea, e non riscrive il requisito in una prosa migliore. La [pagina dei validatori](https://specscore.md/it/validators/) separa quel controllo strutturale da una revisione manuale con IA. `specscore spec lint` è il controllo strutturale.

La descrizione del comando, in [internal/cli/spec.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/internal/cli/spec.go) al tag v0.55.1 della CLI e al tag v0.39.1 che il workflow di questo repository installa, dice che valida l’albero delle specifiche rispetto a violazioni di convenzioni strutturali. Un’esecuzione pulita stampa `0 violations found` ed esce con 0. Un’esecuzione che trova violazioni stampa una riga per rilievo ed esce con 1. Quel codice di uscita è ciò che fa fallire un job di CI. Gli argomenti non validi escono con 2. Un `specscore.yaml` mancante esce con 3, e il messaggio dice di eseguire `specscore init`.

## Che cosa controlla il linter di specifiche

Le regole sono della CLI, non di un servizio cloud separato. Il catalogo generato [docs/lint-rules.md](https://github.com/specscore/specscore-cli/blob/v0.55.1/docs/lint-rules.md) al tag v0.55.1 elenca 183 regole. Il workflow di questo sito installa v0.39.1, una versione precedente, quindi una regola che esiste solo in un tag successivo non è ciò che quel job esegue. Le regole nominate in questa sezione sono in entrambi i tag. Il `--severity` predefinito è `error`. Un avviso viene stampato solo quando passi `--severity warning` o `info`, e il comando predefinito non fallisce per un avviso. Il catalogo segna `dogfood-version-bump` come avviso, quindi il comando predefinito non fallisce quando il pin del workflow è indietro rispetto al binario.

### File e sezioni obbligatori

La regola `readme-exists` ([readme_exists.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/readme_exists.go)) richiede un `README.md` in ogni directory della specifica. La regola `oq-section` ([oq_section.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/oq_section.go)) richiede che il README di una funzionalità contenga una sezione `## Open Questions`. Un titolo ereditato `## Outstanding Questions` è un rilievo a parte, e `--fix` riscrive quel titolo sul posto. Il messaggio nell’esempio sotto, «Open Questions section not found», è il rilievo di un README di funzionalità a cui è stata tolta la sezione.

### Righe dell’indice e directory figlie

La regola `index-entries` ([index_entries.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/index_entries.go)) confronta un indice di funzionalità con le directory figlie sul disco. Una figlia che non è elencata è una violazione, e una riga il cui link punta a una figlia che non c’è è una violazione. `--fix` può cancellare la riga fantasma e inserire quella mancante. È l’integrità di directory e indice. Non è una scansione di ogni URL nella prosa.

### Forma del titolo del criterio di accettazione

La regola `ac-heading-format` ([ac_heading.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/ac_heading.go)) si applica al README di una funzionalità, un file il cui titolo è `# Feature:`. Una riga che sembra un titolo di criterio di accettazione deve essere esattamente `### AC: <id>` con uno spazio dopo i due punti e un id in kebab-case. È accettato anche un titolo della forma `### AC: <id> (verifies ...)`. `--fix` corregge solo la spaziatura. Un id con lettere maiuscole o trattini bassi viene segnalato e lasciato a una persona. La regola non richiede la riga `**Requirements:**`, non assegna un punteggio a parole come «graceful» o «fast», e non avvisa quando la prosa contiene Given, When o Then. Come scrivere il criterio stesso è in [come scrivere criteri di accettazione](https://specscore.md/it/articles/acceptance-criteria/).

### Riferimenti del piano a quegli identificatori

In un piano che nomina una funzionalità di origine, [plan_rules.go](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/plan_rules.go) legge i titoli `### AC:` nel README di quella funzionalità. La regola `P-002` segnala un valore `**Verifies:**` di un’attività che non si risolve in `<feature-slug>#ac:<ac-slug>` per uno di quei titoli, una riga `**Verifies:**` vuota, una riga di origine assente o non riconosciuta, o una funzionalità di origine che non si risolve in un README di funzionalità. La regola `P-001` segnala un titolo che nessuna attività copre e che non è elencato sotto `## Deferred AC Coverage`. I piani la cui origine è un’idea (`**Source:** idea:<slug>`) e i piani con `**Source:** none` sono esenti, e lo è anche un piano in uno stato di disposizione terminale. Il testo di catalogo su una riga per `P-002` dice «valid dependency references»; il controllo in quel file è il controllo dei riferimenti AC appena descritto.

### Che cosa non è un lint superato

Lo stesso comando non decide se un requisito risolve il problema enunciato, se un nome ha senso, o se due funzionalità si contraddicono nel significato. La pagina dei validatori le elenca come esterne al linter della CLI. Non controlla nemmeno le parole chiave dei passi di uno scenario. `specscore rehearse` esegue i file di scenario. Il workflow di questo repository esegue `specscore spec lint` e non chiama rehearse. Il catalogo nomina altre famiglie — idee, decisioni, entità, proprietà, lezioni, issue e il resto delle regole di piano — e ogni regola si applica ai file che le appartengono. Il catalogo è la lista. Questa pagina non ripete tutte le 183 descrizioni.

## Eseguire specscore spec lint in CI

Il comando cerca verso l’alto, a partire dalla directory di lavoro, un `specscore.yaml`. Senza quel file esce con 3 e nomina `specscore init`. Un job di CI ha quindi bisogno del file di configurazione nel checkout. [scripts/install.sh](https://github.com/specscore/specscore-cli/blob/v0.55.1/scripts/install.sh) legge `SPECSCORE_VERSION` e, se la variabile non è impostata, usa `latest`. Fissa un tag se vuoi le stesse regole a ogni esecuzione.

Il controllo di questo repository è [dogfood.yml](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml). Installa la CLI con `SPECSCORE_VERSION` impostata su `v0.39.1` e poi esegue `specscore spec lint` senza flag aggiuntivi, sulle pull request e sui push verso main. GitHub Actions fa fallire il passo quando quel processo esce con un codice diverso da zero. L’estratto sotto conserva quei passi di installazione e di lint. Il file imposta anche `permissions: contents: read`, un gruppo di concorrenza e un commento sul perché il pin non è `latest`.

### Passi di installazione e di lint da dogfood.yml

```yaml
name: Dogfood lint

on:
  push:
    branches: [main]
  pull_request:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6
      - name: Install specscore CLI (pinned)
        env:
          SPECSCORE_VERSION: v0.39.1
        run: |
          curl -fsSL https://specscore.md/install/get-cli | \
            SPECSCORE_INSTALL_DIR="$HOME/.local/bin" sh
          echo "$HOME/.local/bin" >> "$GITHUB_PATH"
          specscore --version
      - name: Lint spec tree
        run: specscore spec lint
```

### Rapporto di fallimento (specscore 0.55.0, stessa forma di riga in v0.39.1)

```text
features/apply-discount/README.md:0 [error] oq-section: Open Questions section not found
features/apply-discount/README.md:0 [error] index-entries: Child directory not listed in index: refunds
features/apply-discount/refunds:0 [error] readme-exists: README.md not found

3 violations found (3 errors)
```

### Rapporto pulito

```text
0 violations found
```

Ogni rilievo è `file:line [severity] rule: message`. Il riepilogo è `N violations found` più un conteggio tra parentesi, come `(3 errors)`. Il codice di uscita è lo stato del processo, non una riga del rapporto. Le tre righe sopra sono state catturate da specscore 0.55.0 su una funzionalità a cui era stata tolta la sezione Open Questions e il cui indice ometteva una directory figlia vuota. Sono lo stesso rapporto che mostra la pagina della CLI. `--format` accetta `text` (il predefinito), `json` o `yaml`. `--rules` e `--ignore` selezionano regole e non si possono combinare. `--fix` riscrive i rilievi che hanno un correttore, compreso il titolo Outstanding Questions. Il job dogfood non passa `--fix`.

## Strumenti che non fanno il lint di questo formato in CI

Un controllo di qualità dei requisiti, in questa CLI, è il controllo strutturale sopra. Non è un punteggio della prosa. Altri strumenti di sviluppo guidato dalle specifiche pubblicano controlli diversi. I paragrafi sotto usano solo ciò che dicono le pagine di quei progetti. La [rassegna degli strumenti](https://specscore.md/it/spec-driven-development/tools/) registra le stesse pagine come lette il 30 ottobre 2026, tranne la home della documentazione di Spec Kit, che stampa il 28 settembre 2026, e la pagina delle specifiche di funzionalità di Kiro, che stampa il 4 agosto 2026.

[GitHub Spec Kit](https://github.github.io/spec-kit/) è un workflow di agente che scrive artefatti Markdown. Il [riferimento di SDD agentico](https://github.github.io/spec-kit/reference/agentic-sdd.html) descrive `/speckit.analyze` come un rapporto di incoerenze tra la specifica, il piano e le attività, senza modificare i file. Si esegue nell’agente. La home della documentazione nomina anche estensioni della comunità, tra cui una chiamata CI Guard, che aggiungono varchi di conformità. Non è un comando che fa il lint di un README di funzionalità SpecScore.

[OpenSpec](https://github.com/Fission-AI/OpenSpec) pubblica un controllo strutturale. `openspec validate`, documentato nel [riferimento della CLI](https://openspec.dev/docs/cli), controlla la struttura di cambiamento e di specifica di OpenSpec, esce con un codice diverso da zero quando la validazione fallisce, e il riferimento include un frammento di shell che un job di CI può eseguire. Quel controllo è la forma di OpenSpec, non i titoli `### AC:` né un indice SpecScore.

La [pagina delle specifiche di funzionalità di Kiro](https://kiro.dev/docs/specs/feature-specs/) descrive Analyze Requirements come un controllo dentro Kiro, prima della progettazione, che cerca incoerenze, ambiguità, vincoli in conflitto e lacune. Non è il comando di `dogfood.yml`. I modelli di frase che Kiro scrive sono nella [sintassi dei requisiti EARS](https://specscore.md/it/articles/ears-requirements/).

Il README di [BMAD Method](https://github.com/bmad-code-org/BMAD-METHOD) descrive gli artefatti del metodo e i workflow degli agenti. Non documenta un comando che fa il lint di uno schema di specifica fisso in CI. Il README di [Task Master](https://github.com/eyaltoledano/claude-task-master) descrive la trasformazione di un PRD in attività con `task-master parse-prd`. Non descrive un linter per quel PRD. Un PRD può comunque essere l’ingresso di una funzionalità SpecScore, e `specscore spec lint` è ciò che poi controlla il file della funzionalità.

## Domande frequenti

### Che cos’è un linter di specifiche?

Un linter di specifiche legge file di specifica e segnala violazioni strutturali. `specscore spec lint` è quel comando per un albero SpecScore. Esce con 0 quando non trova nulla alla severità scelta, e con 1 quando trova violazioni.

### Il linter di specifiche giudica la qualità dei requisiti nella formulazione?

No. `ac-heading-format` controlla il titolo `### AC:`. Non assegna un punteggio a parole come «graceful» o «fast», e non avvisa quando un criterio contiene Given, When o Then. La formulazione è un lavoro di scrittura. La pagina dei validatori separa quel lint deterministico dalla revisione manuale con IA.

### Come faccio il lint delle specifiche in CI?

Installa la CLI con `SPECSCORE_VERSION` impostata su un tag di release, poi esegui `specscore spec lint`. Il checkout ha bisogno di un `specscore.yaml`. [dogfood.yml](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml) è un esempio funzionante di GitHub Actions. Il file fissa v0.39.1.

### Che cosa stampa un’esecuzione che fallisce?

Una riga per rilievo, `file:line [severity] rule: message`, poi un riepilogo come `3 violations found (3 errors)`. Il processo esce con 1. Un albero pulito stampa `0 violations found` ed esce con 0.

### Altri strumenti di sviluppo guidato dalle specifiche validano le specifiche in CI/CD?

L’`openspec validate` di OpenSpec può far fallire un job di CI, e controlla la struttura di cambiamento propria di OpenSpec. Il `/speckit.analyze` di Spec Kit viene eseguito nella sessione dell’agente. Analyze Requirements di Kiro viene eseguito dentro Kiro. I README di BMAD Method e di Task Master non documentano un linter di formato per la CI. Il workflow dogfood di SpecScore esegue `specscore spec lint` sull’albero SpecScore.

## Fonti

Comportamento della CLI controllato il 4 novembre 2026 rispetto ai tag v0.55.1 e v0.39.1 di specscore-cli. Le pagine dei concorrenti sono quelle collegate sotto; la rassegna degli strumenti le registra come lette il 30 ottobre 2026, tranne dove la pagina stampa la propria data.

- [specscore/specscore-cli](https://github.com/specscore/specscore-cli)
- [specscore-cli — licenza Apache-2.0](https://github.com/specscore/specscore-cli/blob/main/LICENSE)
- [specscore/specscore](https://github.com/specscore/specscore)
- [specscore-cli v0.55.1 — catalogo delle regole di lint (183 regole)](https://github.com/specscore/specscore-cli/blob/v0.55.1/docs/lint-rules.md)
- [specscore/specscore — dogfood.yml (CLI v0.39.1)](https://github.com/specscore/specscore/blob/main/.github/workflows/dogfood.yml)
- [specscore-cli — install.sh (SPECSCORE_VERSION)](https://github.com/specscore/specscore-cli/blob/v0.55.1/scripts/install.sh)
- [specscore-cli v0.55.1 — readme-exists](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/readme_exists.go)
- [specscore-cli v0.55.1 — oq-section](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/oq_section.go)
- [specscore-cli v0.55.1 — index-entries](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/index_entries.go)
- [specscore-cli v0.55.1 — ac-heading-format](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/ac_heading.go)
- [specscore-cli v0.55.1 — regole di piano P-001 e P-002](https://github.com/specscore/specscore-cli/blob/v0.55.1/pkg/lint/plan_rules.go)
- [Che cosa valida SpecScore](https://specscore.md/it/validators/)
- [Come scrivere criteri di accettazione che un agente IA possa verificare](https://specscore.md/it/articles/acceptance-criteria/)
- [Sintassi dei requisiti EARS spiegata, con esempi](https://specscore.md/it/articles/ears-requirements/)
- [Documentazione di GitHub Spec Kit (data della pagina 28 settembre 2026)](https://github.github.io/spec-kit/)
- [GitHub Spec Kit — riferimento di SDD agentico (/speckit.analyze)](https://github.github.io/spec-kit/reference/agentic-sdd.html)
- [Riferimento della CLI OpenSpec — openspec validate](https://openspec.dev/docs/cli)
- [Fission-AI/OpenSpec](https://github.com/Fission-AI/OpenSpec)
- [Kiro — specifiche di funzionalità (aggiornato il 4 agosto 2026)](https://kiro.dev/docs/specs/feature-specs/)
- [bmad-code-org/BMAD-METHOD](https://github.com/bmad-code-org/BMAD-METHOD)
- [eyaltoledano/claude-task-master](https://github.com/eyaltoledano/claude-task-master)
- [Strumenti di sviluppo guidato dalle specifiche](https://specscore.md/it/spec-driven-development/tools/)

## Correlati

- [Sviluppo guidato dalle specifiche con Claude Code e Cursor](https://specscore.md/it/articles/claude-code-specs/)
- [Modello di PRD in Markdown per programmare con l’IA](https://specscore.md/it/articles/feature-spec-template/)
- [Come scrivere criteri di accettazione che un agente IA possa verificare](https://specscore.md/it/articles/acceptance-criteria/)
- [Sintassi dei requisiti EARS spiegata, con esempi](https://specscore.md/it/articles/ears-requirements/)
- [Che cosa valida SpecScore](https://specscore.md/it/validators/)
- [CLI](https://specscore.md/it/cli/)
- [Installa la CLI](https://specscore.md/it/cli/install/)
- [Sviluppo guidato dalle specifiche](https://specscore.md/it/spec-driven-development/)
- [Strumenti di sviluppo guidato dalle specifiche](https://specscore.md/it/spec-driven-development/tools/)
- [Specifica di funzionalità](https://specscore.md/feature-specification)
- [Specifica dei criteri di accettazione](https://specscore.md/acceptance-criteria-specification)
