Skip to content

spec-driven ​

Gli artefatti del flusso di lavoro predefinito: il loro ordine, i loro formati e la cartella delle modifiche che producono.

spec-driven è lo schema predefinito integrato di OpenSpec. schema.yaml definisce i campi che imposta.

Artefatti ​

Il flusso di lavoro redige quattro artefatti:

ArtefattoFileScopo
proposalproposal.mdPerché è necessaria la modifica
specsspecs/<capability-path>/spec.md, uno per capabilityQuali comportamenti cambiano
designdesign.mdCome costruirlo
taskstasks.mdLa checklist di implementazione

Ordine di redazione ​

text
             ┌─ specs ──┐
proposal ────┤          ├── tasks ── apply
             └─ design ─┘

La proposta viene per prima. Specs e design seguono in qualsiasi ordine, e tasks richiede entrambi. L'implementazione (apply) inizia una volta che tasks.md è presente.

Due artefatti possono essere saltati:

  • design: quando nessuna delle sue condizioni si applica, l'agente lo omette e redige comunque tasks.
  • specs: imposta skip_specs: true nel .openspec.yaml della modifica.

Esempio di cartella di modifica ​

Una modifica denominata add-user-auth, con ogni artefatto redatto:

text
openspec/changes/add-user-auth/
├── .openspec.yaml      change metadata, written when the change is created
├── proposal.md
├── specs/
│   └── user-auth/
│       └── spec.md     one delta spec per capability
├── design.md
└── tasks.md

proposal.md ​

Stabilisce perché la modifica è necessaria.

Struttura ​

Il template che l'agente riceve come formato di output (templates/proposal.md):

md
# Proposal

## Why

<!-- Explain the motivation for this change. What problem does this solve? Why now? -->

## What Changes

<!-- Describe what will change. Be specific about new capabilities, modifications, or removals. -->

## Capabilities

### New Capabilities
<!-- Capabilities being introduced. Name each capability for a cohesive system
     behavior that can own related requirements as the system evolves. Do not name
     implementation tasks or proposal sections. Avoid broad catch-all names. Use
     kebab-case for path segments you introduce (e.g., user-auth or identity/user-auth)
     that follow the project's existing spec organization. Each creates
     specs/<capability-path>/spec.md. -->
- `<capability-path>`: <brief description of what this capability covers>

### Modified Capabilities
<!-- Existing capabilities whose REQUIREMENTS are changing (not just implementation).
     Only list here if spec-level behavior changes. Each needs a delta spec file.
     Use the exact existing path under openspec/specs/. Leave empty if no requirement
     changes. A change with no capabilities at all (pure refactor, tooling, docs)
     must set `skip_specs: true` in its .openspec.yaml - openspec validate rejects
     a zero-delta change without that marker. Do not invent a requirement just to
     satisfy validation. -->
- `<existing-capability-path>`: <what requirement is changing>

## Impact

<!-- Affected code, APIs, dependencies, systems -->

Istruzioni ​

L'istruzione inviata all'agente quando redige questo artefatto (da schema.yaml):

md
Create the proposal document that establishes WHY this change is needed.

Sections:
- **Why**: 1-2 sentences on the problem or opportunity. What problem does this solve? Why now?
- **What Changes**: Bullet list of changes. Be specific about new capabilities, modifications, or removals. Mark breaking changes with **BREAKING**.
- **Capabilities**: Identify which specs will be created or modified:
  - **New Capabilities**: List capabilities being introduced. Each becomes a new `specs/<capability-path>/spec.md`. Name each capability for a durable system behavior (for example, `user-auth`), not the work in this change (for example, `add-login-endpoint`). Choose a cohesive boundary that can own related requirements as the system evolves; avoid broad catch-all capabilities. Use kebab-case for path segments you introduce (e.g., `user-auth` or `identity/user-auth`) and follow the project's existing spec organization.
  - **Modified Capabilities**: List existing capabilities whose REQUIREMENTS are changing. Only include if spec-level behavior changes (not just implementation details). Each needs a delta spec file. Use the exact existing path under `openspec/specs/`. Leave empty if no requirement changes.
- **Impact**: Affected code, APIs, dependencies, or systems.

IMPORTANT: The Capabilities section is critical. It creates the contract between
proposal and specs phases. Research existing specs before filling this in:
run `openspec list --specs` for the project's capability inventory, then
`openspec show "<spec-id>" --type spec --json --no-scenarios` for any that
look related - that returns a capability's purpose and requirement texts
without pulling whole spec files into context. Append `--store "<id>"` to
both commands only for a registered standalone store, and keep `--type
spec`: a change and a spec sharing a name is otherwise an ambiguous-item
error. `openspec list` without `--specs` lists in-flight changes, not
specs - it never shows what the project already covers. Reuse an existing
capability's exact path instead of introducing a near-duplicate name.
The filtered read is only an overview. Before deciding what is already
covered or what should change, read each relevant spec in full, including
scenarios, with `openspec show "<spec-id>" --type spec` (same `--store` rule).
Each capability listed here will need a corresponding spec file.

Every change must either declare at least one capability (new or
modified) or explicitly opt out of specs: `openspec validate` rejects a
change with zero deltas unless the change's `.openspec.yaml` sets
`skip_specs: true`. Use `skip_specs: true` only when no spec-level
behavior changes (pure refactor, tooling, docs) - specs describe
behavior, so if behavior does not change, no spec should change either.
Do not invent a requirement just to satisfy validation.

Keep it concise (1-2 pages). Focus on the "why" not the "how" -
implementation details belong in design.md.

This is the foundation - specs, design, and tasks all build on this.

Specifiche delta (spec.md) ​

Definisce quali comportamenti cambiano, con una specifica delta per ogni capacità elencata nella proposta.

Ogni specifica delta è il file spec.md all'interno della cartella della capacità. openspec validate e openspec archive rifiutano sezioni delta scritte in qualsiasi altro file sotto specs/, come specs/user-auth.md, perché l'archivio non le unisce mai.

Struttura ​

Il template che l'agente riceve come formato di output (templates/spec.md):

md
# Spec Delta

## Purpose
<!-- New capabilities only: one or two sentences (50+ characters) on what this capability is for. Delete this section for an existing capability. -->

## ADDED Requirements

### Requirement: <!-- requirement name -->
<!-- requirement text -->

#### Scenario: <!-- scenario name -->
- **WHEN** <!-- condition -->
- **THEN** <!-- expected outcome -->

Istruzioni ​

L'istruzione inviata all'agente quando redige questo artefatto (da schema.yaml):

md
Create specification files that define WHAT the system should do.

A spec is a behavior contract, not an implementation plan.

Good spec content:
- Observable behavior users or downstream systems rely on
- Inputs, outputs, and error conditions
- External constraints (security, privacy, reliability, compatibility)
- Scenarios that can be tested or explicitly validated

Avoid in specs:
- Internal class/function names
- Library or framework choices
- Step-by-step implementation details
- Detailed execution plans (those belong in design.md or tasks.md)

Quick test: if the implementation can change without changing externally
visible behavior, it likely does not belong in the spec.

Create one spec file per capability listed in the proposal's Capabilities section.
`<capability-path>` is the spec directory relative to `specs/` (for example,
`user-auth` or `identity/user-auth`). Preserve the full path:
- New capabilities: use the exact path from the proposal at `specs/<capability-path>/spec.md`. Any path segment newly introduced in the proposal must be kebab-case. Follow the project's existing organization; do not add a new domain level when the project uses a flat layout.
- Modified capabilities: use the exact existing path from `openspec/specs/<capability-path>/` when creating the delta at `specs/<capability-path>/spec.md`. Run `openspec list --specs` to confirm that path before writing the delta, appending `--store "<id>"` only for a registered standalone store - a mistyped or invented path targets a capability that does not exist rather than the one you meant. Do not move or rename the capability.

Write the spec files one at a time, so the user sees progress and an
interrupted run keeps the files it already wrote:
- Before writing anything, compare the capabilities the proposal lists
  with the `specs/<capability-path>/spec.md` files that already exist,
  and start with the first capability that has no file. Do not rewrite
  an existing file unless the user asks you to.
- Before each file, say in one line which capability you are writing.
- Write each file as soon as you have drafted it. Do not plan every file
  before writing the first.
- Stop when every capability the proposal lists has its file.

There must be at least one spec file unless the change's `.openspec.yaml`
sets `skip_specs: true` (no spec-level behavior change) - `openspec validate`
rejects a zero-delta change without that marker. If the proposal lists no
capabilities and `skip_specs` is not set, revisit the proposal first.

Delta operations (use ## headers):
- **ADDED Requirements**: New capabilities
- **MODIFIED Requirements**: Changed behavior - MUST include full updated content
- **REMOVED Requirements**: Deprecated features - MUST include **Reason** and **Migration**
- **RENAMED Requirements**: Name changes only - use FROM:/TO: format

Format requirements:
- Each requirement: `### Requirement: <name>` followed by description
- Use SHALL/MUST for normative requirements (avoid should/may)
- Each scenario: `#### Scenario: <name>` with WHEN/THEN format
- **CRITICAL**: Scenarios MUST use exactly 4 hashtags (`####`). Using 3 hashtags or bullets will fail silently.
- Every requirement MUST have at least one scenario.
- Every scenario MUST have a WHEN/GIVEN step (its trigger) and a THEN step (its outcome). A scenario with only AND lines or plain prose still counts as a scenario, but `openspec validate` flags it as a warning: normal validation still passes, but `openspec validate --strict` fails on it.
- Keep each requirement's description (the text between `### Requirement:` and its first scenario) to 500 characters or fewer. `openspec validate` flags longer descriptions in ADDED requirements and in the main spec. This is a warning: normal validation still passes, but `openspec validate --strict` fails on it. When writing a new requirement, state one behavior per requirement: move examples and edge cases into scenarios, and split a requirement that covers several behaviors into separate `### Requirement:` blocks, each with its own scenarios. Under MODIFIED, keep the existing requirement block whole; never split, trim or rewrite existing text just to meet the length. Split an existing long requirement only when the user asks for it, in a change made for that purpose: under MODIFIED, keep its header and every scenario and cut its description down to one behavior without changing its meaning, then add each behavior you removed as its own ADDED requirement with its own scenarios.

New capabilities only: the delta spec's first section is `## Purpose` -
one or two sentences (50+ characters, or `openspec validate --strict`
reports it as too brief) describing what the capability is for. Archive
copies it into the main spec it creates; without it the new main spec is
left with a `TBD ... Update Purpose after archive` placeholder to fill in
by hand. Do NOT add `## Purpose` to a delta for an existing capability -
that spec already has one and the delta's is ignored. To change an
existing capability's Purpose - including a leftover `TBD` placeholder -
edit `<planningHome.root>/openspec/specs/<capability-path>/spec.md`
directly. `planningHome.root` comes from the `openspec instructions ...
--json` response. Always use it rather than a repo-relative path: it
resolves to the store whenever the change lives in one - whether that
came from `--store`, a project `store:` pointer, or a global default
store - and to the current repository otherwise. Do not try to work out
which case applies; the field already has.

MODIFIED requirements workflow:
1. Locate the existing requirement in `<planningHome.root>/openspec/specs/<capability-path>/spec.md` (the same store-aware root as above)
2. Copy the ENTIRE requirement block (from `### Requirement:` through all scenarios)
3. Paste under `## MODIFIED Requirements` and edit to reflect new behavior
4. Ensure header text matches exactly (whitespace-insensitive)

Common pitfall: Using MODIFIED with partial content loses detail at archive time.
If adding new concerns without changing existing behavior, use ADDED instead.

Example (a new capability, so its first section is `## Purpose`):
```
# Spec Delta
```

Scopo ​

Consente agli utenti di estrarre i propri dati dal prodotto in un formato portabile.

Requisiti AGGIUNTI ​

Requisito: L'utente può esportare i dati ​

Il sistema DEVE consentire agli utenti di esportare i propri dati in formato CSV.

Scenario: Esportazione riuscita ​

  • QUANDO l'utente fa clic sul pulsante "Esporta"
  • ALLORA il sistema scarica un file CSV con tutti i dati dell'utente

Requisiti RIMOSSI ​

Requisito: Esportazione legacy ​

Motivo: Sostituita dal nuovo sistema di esportazione Migrazione: Usa il nuovo endpoint di esportazione in /api/v2/export


Le specifiche dovrebbero essere verificabili: ogni scenario è un potenziale caso di test.

design.md ​

Spiega come implementare la modifica. Redatto solo quando la modifica ne richiede uno.

Struttura ​

Il template che l'agente riceve come formato di output (templates/design.md):

md
# Progettazione

## Contesto

<!-- Stato attuale e vincoli che determinano l'approccio. Vedi proposal.md per la motivazione: non ripeterla -->

## Obiettivi / Non obiettivi

**Obiettivi:**
<!-- Cosa intende ottenere questo design -->

**Non obiettivi:**
<!-- Cosa è esplicitamente fuori ambito -->

## Decisioni

<!-- Decisioni chiave di design con motivazione e alternative considerate -->

## Rischi / Compromessi

<!-- Rischi e compromessi noti -->

Istruzioni ​

L'istruzione inviata all'agente quando redige questo artefatto (da schema.yaml):

md
Crea il documento di design che spiega COME implementare la modifica.

Quando includere design.md (creare solo se si applica almeno una delle seguenti condizioni):
- Modifica trasversale (più servizi/moduli) o nuovo pattern architetturale
- Nuova dipendenza esterna o modifiche significative al modello dati
- Complessità di sicurezza, prestazioni o migrazione
- Ambiguità che trae vantaggio da decisioni tecniche prima della codifica

Sezioni:
- **Contesto**: Solo lo stato attuale e i vincoli necessari a spiegare l'approccio. Fai riferimento alla proposta per la motivazione invece di ripeterla (ad es. "Vedi proposal.md - Perché").
- **Obiettivi / Non obiettivi**: Cosa intende ottenere questo design ed esplicitamente cosa esclude. Non ripetere l'ambito della proposta: aggiungi solo i confini a livello di design.
- **Decisioni**: Scelte tecniche chiave con motivazione (perché X invece di Y?). Includi le alternative considerate per ogni decisione.
- **Rischi / Compromessi**: Limitazioni note, cose che potrebbero andare storte. Formato: [Rischio] → Mitigazione
- **Piano di migrazione**: Passaggi per il deployment, strategia di rollback (se applicabile)
- **Domande aperte**: Incognite a cui si può rispondere in sicurezza in seguito senza
  modificare le specifiche, l'approccio o la suddivisione delle attività. Ometti se non ce ne sono.

Le domande aperte riguardano incognite realmente rinviabili, non decisioni che hai
saltato. Se una domanda cambierebbe le specifiche, l'approccio scelto o
la suddivisione delle attività, risolvila ora: chiedi all'utente invece di indovinare.

Concentrati sull'architettura e sull'approccio, non sull'implementazione riga per riga.
La proposta copre il perché e il cosa; il design copre il come. Fai riferimento alla
proposta per la motivazione e, una volta scritte, alle specifiche per i requisiti:
se una sezione si limiterebbe a ripeterli, rimanda ad essi.

I buoni documenti di design spiegano il "perché" dietro le decisioni tecniche.

tasks.md ​

Suddivide l'implementazione in attività verificabili. apply tiene traccia dell'avanzamento qui.

Struttura ​

Il template che l'agente riceve come formato di output (templates/tasks.md):

md
# Attività

## 1. <!-- Nome del gruppo di attività -->

- [ ] 1.1 <!-- Descrizione dell'attività -->
- [ ] 1.2 <!-- Descrizione dell'attività -->

## 2. <!-- Nome del gruppo di attività -->

- [ ] 2.1 <!-- Descrizione dell'attività -->
- [ ] 2.2 <!-- Descrizione dell'attività -->

Istruzioni ​

L'istruzione inviata all'agente quando redige questo artefatto (da schema.yaml):

md
Crea l'elenco delle attività che suddivide il lavoro di implementazione.

Prima di scrivere le attività, controlla le Domande aperte in design.md. Se una di esse
cambierebbe ciò che viene costruito, risolvila prima con l'utente: non
incorporare un'assunzione non dichiarata nell'elenco delle attività.

**IMPORTANTE: Segui il template riportato di seguito per le attività tracciate.** La fase di apply analizza
il formato delle checkbox per tenere traccia dell'avanzamento. Una casella contenente solo `x` è considerata completata,
in maiuscolo o minuscolo e con qualsiasi spaziatura, quindi anche `- [ x]` è completata. Ogni
altro marcatore, inclusi `- [~]`, `- [-]` e una casella vuota `- []`, è letto come
non completato. Una riga senza checkbox non viene tracciata affatto.

Linee guida:
- Raggruppa le attività tracciate correlate sotto intestazioni numerate ##
- Ogni attività tracciata DEVE essere una checkbox: `- [ ] X.Y Task description`
- Le attività dovrebbero essere abbastanza piccole da essere completate in una sessione
- Ordina le attività in base alle dipendenze (cosa deve essere fatto prima?)
- Traccia il lavoro di implementazione e verifica che può essere completato prima
  dell'archiviazione. Se il flusso di lavoro richiesto include l'archiviazione o attività che richiedono
  l'archiviazione di questa modifica, conserva quei passaggi come semplici bullet in una
  sezione facoltativa `## Follow-up del flusso di lavoro` alla fine di tasks.md. Questi
  bullet sono informazioni di riferimento al di fuori dell'avanzamento delle attività tracciate.
- Ogni attività DEVE indicare come verificare il completamento (un test, un comando,
  un comportamento osservabile o un artefatto consegnato). Inserisci la verifica nella
  descrizione della checkbox di quell'attività. Usa un'attività di verifica separata solo
  quando controlla un'integrazione più ampia o un comportamento di sistema che coinvolge
  più attività di implementazione.
- Ogni gruppo di attività DEVE includere i test e la documentazione richiesti dal proprio lavoro.
  NON raccogliere test o documentazione in un gruppo finale:
  quando un gruppo tardivo esercita per la prima volta il lavoro di uno precedente, i guasti
  si propagano a cascata attraverso ogni gruppo intermedio e costringono a rifare il lavoro. Un gruppo
  il cui lavoro non richiede né test né documentazione, ad esempio scaffolding o configurazione delle dipendenze,
  non include nessuno dei due. Un gruppo finale serve solo per i controlli di integrazione, non per
  i test e la documentazione che un gruppo precedente avrebbe dovuto fornire.

Esempio:
```
# Attività

## 1. Configurazione

- [ ] 1.1 Crea la nuova struttura del modulo e verifica che i file previsti siano presenti
- [ ] 1.2 Aggiungi le dipendenze a package.json e verifica che l'installazione dei pacchetti riesca

## 2. Implementazione principale

- [ ] 2.1 Implementa la funzione di esportazione dei dati e verifica che il test di esportazione passi
- [ ] 2.2 Aggiungi utilità di formattazione CSV e verifica che i test unitari coprano virgolette e delimitatori
- [ ] 2.3 Documenta l'API di esportazione in docs/export.md e verifica che il comando documentato funzioni come scritto
```

Quando applicabile, aggiungi il follow-up del flusso di lavoro come semplici bullet, ad esempio:
```
## Follow-up del flusso di lavoro

- Archivia la modifica dopo che i requisiti di revisione del progetto sono soddisfatti.
- Verifica il risultato archiviato.
```

Fai riferimento alle specifiche per ciò che deve essere costruito e al design per come costruirlo.

Apply ​

Il passaggio dalla pianificazione all'implementazione. Apply è la fase che lavora attraverso tasks.md, non un artefatto.

  • Inizia: una volta che tasks.md esiste ed elenca almeno un'attività.
  • Traccia: le checkbox in tasks.md. Spuntarle costituisce il registro di avanzamento.
  • Termina: quando ogni checkbox è spuntata. OpenSpec suggerisce quindi di archiviare la modifica.

Impostazioni ​

Le impostazioni di apply (da schema.yaml):

yaml
apply:
  requires: [tasks]
  tracks: tasks.md
  # istruzione: mostrata di seguito

Istruzioni ​

L'istruzione inviata all'agente all'avvio dell'implementazione (da schema.yaml):

md
Leggi i file di contesto, lavora sulle attività in sospeso e contrassegnale come completate man mano che procedi.
Mettiti in pausa se incontri ostacoli o hai bisogno di chiarimenti.

schema.yaml ​

Il file schema.yaml completo, con i corpi delle istruzioni omessi. Ognuno è mostrato per intero nella rispettiva sezione sopra.

yaml
name: spec-driven
version: 1
description: Flusso di lavoro OpenSpec predefinito - proposta → specifiche → design → attività
artifacts:
  - id: proposal
    generates: proposal.md
    description: Documento di proposta iniziale che descrive la modifica
    template: proposal.md
    # istruzione: mostrata per intero sopra, in proposal.md
    requires: []

  - id: specs
    generates: "specs/**/*.md"
    description: Specifiche dettagliate per la modifica
    template: spec.md
    # istruzione: mostrata per intero sopra, in Delta specs
    requires:
      - proposal

  - id: design
    generates: design.md
    description: Documento di design tecnico con dettagli di implementazione
    template: design.md
    # istruzione: mostrata per intero sopra, in design.md
    requires:
      - proposal

  - id: tasks
    generates: tasks.md
    description: Checklist di implementazione con attività tracciabili
    template: tasks.md
    # istruzione: mostrata per intero sopra, in tasks.md
    requires:
      - specs
      - design

apply:
  requires: [tasks]
  tracks: tasks.md
  # istruzione: mostrata per intero sopra, in Apply