Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Concepts

codev keeps three kinds of records in the repository: specs say what the system does, decisions say why it is built the way it is, and changes are the work in progress that modifies both.

_codev/
├── config.yaml     # project configuration
├── specs/          # behavior contracts — WHAT the system does
├── decisions/      # architecture decisions — WHY it is built this way
├── changes/        # work in progress, which modifies the two above
│   ├── <name>/     #   proposal.md, design.md, tasks.md, specs/** (deltas)
│   └── archive/    #   finished changes, dated
├── schemas/        # custom workflow schemas (optional)
└── codev.lock      # pinned inherited git sources (when used)

codev finds this folder by walking up from the current directory, so every command works from any subdirectory of the project.

Capability

A capability is a unit of observable behavior the system offers — user authentication, the theme setting, the validate command. Capabilities are identified by a path of kebab-case segments, such as ui/theme or identity/user-auth, which is also where their spec lives. Group them the way your domain is organized, not the way your code is.

Spec

The main spec of a capability lives at _codev/specs/<capability>/spec.md. It has a ## Purpose — one or two sentences on what the capability is for — and a ## Requirements section:

# Theme Specification

## Purpose

Let users choose the color theme of the interface.

## Requirements

### Requirement: Theme follows the system preference by default

The application SHALL render with the operating system's color scheme until the user picks a theme.

#### Scenario: No theme chosen yet

- **GIVEN** a user who has never changed the theme setting
- **WHEN** their operating system is set to dark mode
- **THEN** the application renders with the dark theme

Each requirement is normative (it uses SHALL or MUST, or DOIT or DOIVENT in a French spec) and has at least one scenario describing observable behavior. A spec describes behavior, never implementation: if the code can change without the behavior changing, the spec should not change either.

You never edit a main spec directly. It changes only when a change is synced or archived, which is what makes its history readable.

Change

A change is a folder _codev/changes/<name>/ that carries one evolution of the system: a proposal, spec deltas, a design and a task list, plus a change.yaml holding its metadata. Which artifacts a change has is defined by its schema; the default spec-driven schema is described in The workflow.

A change is active while it lives in _codev/changes/<name>/. Archiving moves it to _codev/changes/archive/<YYYY-MM-DD>-<name>/, where it becomes a record of why and how the specs changed.

Delta

A delta is the part of a change that modifies a spec. It lives at _codev/changes/<name>/specs/<capability>/spec.md — the same capability path as the main spec it targets — and is organized in up to four operations:

SectionEffect when merged
## ADDED RequirementsAppends the requirements to the main spec
## MODIFIED RequirementsReplaces the requirement of the same name, in place
## REMOVED RequirementsDeletes the requirement, with a Reason and a Migration
## RENAMED RequirementsChanges a requirement’s title, leaving its body untouched

Here is a delta that modifies one requirement and renames another:

## MODIFIED Requirements

### Requirement: Theme follows the system preference by default

The application SHALL render with the operating system's color scheme until the user picks a theme, and SHALL switch live when that preference changes.

#### Scenario: No theme chosen yet

- **GIVEN** a user who has never changed the theme setting
- **WHEN** their operating system is set to dark mode
- **THEN** the application renders with the dark theme

## RENAMED Requirements

- FROM: The chosen theme is remembered
- TO: The chosen theme follows the user

A MODIFIED block replaces the whole requirement, so copy the entire block from the main spec — scenarios included — before editing it. Content you leave out is lost at merge time. If you are adding behavior without changing existing behavior, use ADDED.

The merge touches only the requirements named in the delta. Everything else in the main spec — other requirements, free-form sections, comments — stays as it was.

A delta for a new capability starts with its own ## Purpose; merging it creates the main spec. Removing a capability entirely — a REMOVED delta that empties a spec — requires retire_capabilities: true in change.yaml, because the deletion can only be undone from git.

The exact syntax is in File formats.

Decision

A decision, or ADR (architecture decision record), is a file _codev/decisions/NNNN-<slug>.md that records an architectural choice: its context, the decision, its consequences and the alternatives considered.

codev decision new "Use PostgreSQL for persistence"
codev decision accept 0001

A decision has one of five statuses: accepted, superseded, proposed, deprecated or rejected. Every command that creates a decision — codev decision new, supersede, deviate and promote — creates it proposed, so you can write it freely; codev decision accept makes it accepted once its text is final. Accepting is the only step that makes a decision take effect: a proposed decision supersedes nothing and deviates from nothing yet. A decision is in effect when it is accepted and nothing supersedes it. The decisions in effect are handed to the agent whenever it writes a design.md, so designs follow them instead of re-debating them.

Each decision has a short id (0007) and a qualified id that names its origin: project/0007 for a decision of the project itself, path:~/shared/0100 or git:git@github.com:acme/shared.git/0100 for a decision inherited from another repository.

Seal

An accepted decision is immutable. When a decision becomes accepted through a codev decision command — accept, or new --status accepted — codev records a SHA-256 hash of the decision’s body in _codev/decisions/seal.yaml; codev decision seal does the same for a decision you accepted by hand. codev validate compares the body of every local accepted or superseded decision with its hash, and reports an edit as a decision_seal_mismatch error and a missing seal as a decision_unsealed warning. A proposed decision is not sealed.

The frontmatter is not covered by the seal, so a status can move from accepted to superseded without breaking it.

Note Seal a decision when its text is final: write the proposed decision first, then run codev decision accept <ID>, which sets the status and records the seal in one step. If you have edited a sealed decision on purpose, codev decision seal <ID> --force records the new body; to change what an accepted decision says, supersede it instead.

Supersession

To change a decision, supersede it rather than editing it:

codev decision supersede 0001 "Use SQLite for persistence"

codev creates a new proposed decision whose frontmatter lists supersedes: ["0001"], and leaves 0001 untouched: it stays accepted, and in effect, while you write the new one. Accepting the new decision marks 0001 as superseded in the same step:

codev decision accept 0002

The old body stays exactly as it was, so its seal stays valid and the history of the reasoning is preserved. Only an accepted decision can be superseded: if another decision superseded 0001 in the meantime, codev decision accept refuses with predecessor_not_accepted and writes nothing.

Deviation

An inherited decision cannot be superseded from your project, because you cannot write to its source. Instead, record a local deviation:

codev decision deviate path:~/shared/0100 "Services log in logfmt"

This creates a local proposed decision with deviates_from pointing at the inherited one. The deviation takes effect when you accept it with codev decision accept: the inherited decision then stays visible in codev decision list, but it is no longer in effect for your project and is no longer handed to the agent when writing designs. Until then, the inherited decision is still in effect.

Promotion

A design often contains a decision that deserves to outlive the change. Write it in design.md as a ### Decision: <title> block, then promote it:

codev decision promote add-audit-log "Append-only audit table"

codev creates a proposed ADR whose ## Decision section is the block’s content, verbatim, and replaces the block’s body with a reference to the new ADR. Review it and split the promoted text into the ADR’s sections, then accept it with codev decision accept, which seals it — ideally before archiving the change.

Inherited source

A project can inherit read-only material from other codev repositories — a shared folder on your machine (path:) or a git repository pinned to a commit (git:). Each source contributes its context:, its rules: and its decisions. Nothing executable is ever inherited, and nothing is read from a floating branch: git sources are pinned in _codev/codev.lock. See Inherited sources.

Schema

A schema defines which artifacts a change has, what each one requires, and the instructions and templates the agent follows to write them. codev embeds one schema, spec-driven. A project can define its own in _codev/schemas/. See Custom schemas.

In spec-driven, each instruction opens with the role that owns the artifact and its “Done when” criteria: product owner for the proposal (why and what), QA analyst for the specs (observable behavior), architect for the design (how), tech lead for the tasks (sequencing and verification).