cc-os/openspec/specs/adr-authoring/spec.md

75 lines
3.6 KiB
Markdown
Raw Permalink Normal View History

# Spec: ADR Authoring
## Purpose
Defines how Architecture Decision Records are created and maintained by the `os-adr` plugin: one standard template, one file per decision at a standard location, a mechanically maintained index, one-invocation creation skills, and mechanical supersession.
## Requirements
### Requirement: Standard ADR template
The plugin SHALL provide a single customized-Nygard ADR template used identically in every
project, with frontmatter fields `id`, `date`, `status`, `supersedes`, `superseded-by`,
`affected-paths`, `affected-components`, and body sections `Context`, `Decision`,
`Consequences`, and `Alternatives rejected`. The plugin SHALL NOT provide per-project or
per-client template variants.
#### Scenario: Template contains all required fields
- **WHEN** a new ADR is generated in any project
- **THEN** the resulting file contains every frontmatter field and body section listed above,
in template order
#### Scenario: No project-specific variation
- **WHEN** ADRs are generated in two different projects
- **THEN** both files follow the identical template structure
### Requirement: One file per decision at the standard location
ADRs SHALL be stored one-file-per-decision at `docs/adr/NNNN-kebab-title.md`, where `NNNN` is a
4-digit zero-padded sequential ID derived by scanning the existing directory contents (max
existing ID + 1), never by trusting the index file.
#### Scenario: Sequential ID assignment
- **WHEN** `docs/adr/` contains ADRs `0001` and `0002` and a new ADR titled "Use Postgres" is
created
- **THEN** the new file is `docs/adr/0003-use-postgres.md`
#### Scenario: ID derived from directory, not index
- **WHEN** the index file is stale or missing but `docs/adr/0007-*.md` exists
- **THEN** the next generated ADR receives ID `0008`
### Requirement: Mechanically maintained index
The plugin SHALL maintain an index file at `docs/adr/README.md` listing every ADR's ID, title,
status, and date. The index SHALL be regenerated in full from the directory contents on every
ADR write, with no LLM involvement, and SHALL declare itself generated/never-hand-edited.
#### Scenario: Index updated on ADR creation
- **WHEN** a new ADR is created via the generator
- **THEN** the index file is regenerated and contains a row for the new ADR
#### Scenario: Index self-heals
- **WHEN** an ADR file was added or edited manually and the generator next runs
- **THEN** the regenerated index reflects the actual directory contents
### Requirement: One-invocation ADR creation skill
The plugin SHALL provide a `create` skill (`/os-adr:create`) that produces a correctly templated,
correctly numbered, and indexed ADR in a single invocation, and an `init` skill (`/os-adr:init`)
that sets up `docs/adr/` plus the index in a project that has none.
#### Scenario: Create in one invocation
- **WHEN** the user (or agent) invokes `/os-adr:create` with a decision to record
- **THEN** a new templated ADR file exists under `docs/adr/` and the index includes it, with no
further steps required
#### Scenario: Init on a fresh project
- **WHEN** `/os-adr:init` runs in a project without `docs/adr/`
- **THEN** `docs/adr/` and an empty index exist and any session-hook suppression flag for the
project is cleared
### Requirement: Supersession is mechanical
WHEN a new ADR declares `supersedes: NNNN`, the generator SHALL set `superseded-by` on the
referenced ADR and update its status accordingly, without manual edits.
#### Scenario: Superseding an existing ADR
- **WHEN** a new ADR `0009` is created with `supersedes: 0004`
- **THEN** ADR `0004`'s frontmatter gains `superseded-by: 0009` and status `Superseded`, and the
regenerated index shows both statuses