> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ooneex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Spec-Driven Development

> Turn a request into a structured spec, plan it, and let AI agents implement it — Ooneex's issue-driven workflow of find, plan, and fix.

In Ooneex, you don't hand an AI agent a vague prompt and hope for the best. You give it a **spec**: a small, structured YAML file that says exactly what the work is, why it exists, and how you'll know it's done. The agent reads that spec, implements it against your real module conventions, and checks its own work against the acceptance criteria you wrote.

That spec is an **issue** — a `modules/<module>/issues/<ID>.yml` file. The whole workflow is three steps over that file:

<Steps>
  <Step title="Find — discover work">
    Audit a module's source and surface concrete findings, each one a future issue.
  </Step>

  <Step title="Plan — turn requests into specs">
    Scaffold an issue and restructure it into `context` / `goal` / `dod` / `dependencies`, splitting big work into ordered sub-issues.
  </Step>

  <Step title="Fix — implement the spec">
    Hand each planned issue to the fixer for its module type; it writes the code, lints, satisfies the Definition of Done, and marks the issue `Done`.
  </Step>
</Steps>

Each step is an AI skill — `/issue:found`, `/issue:plan`, `/issue:fix` — that you invoke from your agent (Claude or Codex). They share one artifact, the issue file, so the spec flows from discovery to a finished, verified change.

## The issue is the spec

Everything centers on one file per unit of work:

```
modules/<module>/issues/<ID>.yml
```

The `<ID>` is generated for you — three uppercase letters and six digits, e.g. `ABC-012345`. A brand-new issue starts as a thin skeleton (see [`issue:create`](/cli/commands/issue-create)):

```yaml theme={null}
id: "ABC-012345"
title: "Add authorization check to user delete route"
state: "Todo"
priority: "High"
description: |
  The DELETE /users/:id route never verifies the caller owns the account.
labels: []
```

Planning transforms that free-form skeleton into a real spec — four fields that read as an unambiguous brief:

```yaml theme={null}
id: "ABC-012345"
title: "Add authorization check to user delete route"
state: "Planned"
priority: "High"
labels:
  - "Security"
context: |
  The DELETE /users/:id route deletes any account by id without checking
  the authenticated caller. Any logged-in user can delete any other user.
goal: |
  Add an ownership/authorization guard to the delete route so a user can
  only delete their own account (admins excepted).

  ## Technical Notes
  Reuse the existing permission service; do not hand-roll the check.

  ### Data Model
  - No schema change — authorization only.
dod: |
  - [ ] Non-owner, non-admin caller receives 403 on DELETE /users/:id
  - [ ] Owner can still delete their own account
  - [ ] Admin can delete any account
  - [ ] A test covers each of the three cases
dependencies: []
```

The four planning fields are the contract between you and the agent:

| Field          | What it holds                                                                                                                           |
| -------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| `context`      | Background and **why** the issue exists.                                                                                                |
| `goal`         | The concrete work to do — plus optional **Technical Notes** and a module-type-specific structure block.                                 |
| `dod`          | The Definition of Done: acceptance criteria as `- [ ]` checkboxes. The fixer ticks these and only marks the issue `Done` when all pass. |
| `dependencies` | IDs of issues that must be completed first — how the loop sequences work.                                                               |

### Issue lifecycle

Every issue carries a `state` and a `priority`. State moves left to right as the spec travels through the workflow:

```
Backlog → Todo → Planned → In Progress → In Review → Done
                                                  ↘ Cancelled
```

| State                       | Meaning                                                                                                         |
| --------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `Backlog` / `Todo`          | Captured but not yet a real spec — just a title and a description.                                              |
| `Planned`                   | Restructured into `context`/`goal`/`dod`/`dependencies` — **ready to implement**. `/issue:fix` takes over here. |
| `In Progress` / `In Review` | Being implemented or reviewed.                                                                                  |
| `Done`                      | Every `dod` checkbox is satisfied.                                                                              |
| `Cancelled`                 | Dropped.                                                                                                        |

Priority is one of `Low`, `Medium`, `High`, `Urgent`, inferred from severity (an exploitable vulnerability is `Urgent`; a missing test is `Medium`).

## The workflow

### 1. Find — audit a module for issues

`/issue:found` infers which modules you mean from plain language ("audit the user and billing modules", or just `user`), then runs a **read-only** audit of each module's source. It never writes anything itself — it dispatches each module to the **founder sub-agent** that matches the module's type and collects findings.

| Module `type`      | Founder                                      | What it audits                                                                                                |
| ------------------ | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| `module` (or none) | `module-issue-founder`                       | Backend domain module — security, performance, architecture, missing tests, code quality, database            |
| `api`              | `api-issue-founder`                          | The above plus the HTTP/REST contract (status codes, DTOs, validation, versioning, pagination, rate limiting) |
| `microservice`     | `microservice-issue-founder`                 | The above plus boundaries, event contracts, idempotency, resilience, observability                            |
| `spa`              | `spa-issue-founder` + `design-issue-founder` | Client-side SPA issues and UI/UX design issues                                                                |
| `design`           | `design-issue-founder`                       | UI/UX design issues for the design system                                                                     |

Every finding cites concrete files and lines, gets a priority and a category label, and is handed straight to `/issue:plan`.

```text Prompt icon="terminal" wrap theme={null}
Audit the user and billing modules for security and architecture issues.
```

### 2. Plan — turn a request into a spec

`/issue:plan` is the heart of spec-driven development. It takes either an existing issue (by ID) **or** a free-form description and produces a planned spec:

1. **Scaffold** (for new work) — runs [`issue:create`](/cli/commands/issue-create), inferring the target module from the domain nouns in your request ("user profile" → `user`, "checkout" → `order`).
2. **Restructure** — replaces the free-form `description` with `context` / `goal` / `dod` / `dependencies`.
3. **Label and prioritize** — extracts labels and sets `state: "Planned"` with an inferred priority.
4. **Split when needed** — if the work spans multiple unrelated concerns, it breaks the parent into 3–7 ordered, self-contained sub-issues (each with the same four fields, wired together through `dependencies`) and deletes the parent.

```text Prompt icon="terminal" wrap theme={null}
Plan an org create API and a billing settings page.
```

This single request becomes two specs in two different modules, sequenced if one depends on the other.

#### Specs are module-type aware

The `goal`'s technical block follows the module's conventions, so the fixer gets the right vocabulary:

<Tabs>
  <Tab title="Backend (module / api / microservice)">
    `### Data Model` — TypeORM relations with the exact field, decorator, and inverse side:

    ```
    - `Organization.packs` → `@OneToMany(() => Pack, (p) => p.organization)` — one org has many packs
    - `Pack.organization` → `@ManyToOne(() => Organization, (o) => o.packs)` — many packs belong to one org
    ```
  </Tab>

  <Tab title="SPA (spa)">
    `### Front-End Structure` — the route, feature slice, layouts, and hooks to add:

    * `src/routes/<kebab>.tsx` — the file-based route
    * `src/features/<feature>/` — components, `hooks/` (`useGet<Name>`, `useUpdate<Name>`), `services/`, `store/`
    * `src/shared/` — anything two features share
  </Tab>

  <Tab title="Design (design)">
    `### Design System Structure` — the primitives to add under `src/`:

    * `src/components/<component>/` — one folder per component and its variants
    * `src/hooks/`, `src/icons/` (`fill/` + `outline/`), `src/styles/`, `src/utils/`
  </Tab>
</Tabs>

### 3. Fix — implement the spec

`/issue:fix` resolves which issues to implement (by ID, by module, or by description), sequences them in **dependency order**, and dispatches each to the **fixer sub-agent** for its module type:

| Module `type`      | Fixer                      |
| ------------------ | -------------------------- |
| `module` (or none) | `module-issue-fixer`       |
| `api`              | `api-issue-fixer`          |
| `microservice`     | `microservice-issue-fixer` |
| `spa`              | `spa-issue-fixer`          |
| `design`           | `design-issue-fixer`       |

Each fixer reads the spec, implements the artifacts the `goal` calls for following Clean Architecture and the module's conventions, runs `bun run fmt` and `bun run lint` from the monorepo root, checks off every satisfied `dod` box, and sets `state: "Done"` only when all of them pass.

```text Prompt icon="terminal" wrap theme={null}
Implement ABC-012345.
```

<Note>
  All commands — including the ones the fixers run — execute from the **monorepo
  root**, never inside an individual module. See [Monorepo](/getting-started/monorepo).
</Note>

<Tip>
  When a `goal` describes a multi-step business process — conditional, reversible
  steps that should roll back together on failure — the fixer reaches for the
  [`@ooneex/workflow`](/components/workflow) package instead of hand-rolling the
  orchestration.
</Tip>

## The loop end to end

The three skills compose into a single thread from "something's wrong" to "it's fixed and verified":

```text Prompt icon="terminal" wrap theme={null}
Audit the user module, then plan and fix everything you find.
```

<Steps>
  <Step title="Find">
    `/issue:found` audits `modules/user/` and surfaces a missing authorization
    check, citing the exact route file.
  </Step>

  <Step title="Plan">
    The finding flows into `/issue:plan`, which scaffolds `ABC-012345`,
    restructures it into a spec, labels it `Security`, sets it `High` / `Planned`.
  </Step>

  <Step title="Fix">
    `/issue:fix` hands `ABC-012345` to `module-issue-fixer`, which adds the guard
    and the tests, lints, ticks every `dod` box, and marks the issue `Done`.
  </Step>
</Steps>

You stay in plain language the whole way — the structure lives in the issue file, and each agent reads it as a precise instruction rather than a guess.

## Why specs

* **The agent never guesses the goal** — `goal` and `dod` are explicit, so the work and the finish line are unambiguous.
* **Self-verifying** — the fixer can only mark `Done` when every acceptance criterion is checked, so "done" means *verified against the spec you wrote*.
* **Sequenced automatically** — `dependencies` let the loop implement issues in the right order, even across modules.
* **Convention-aware** — specs carry the right structure for backend, SPA, or design modules, so generated code fits your codebase.
* **Reviewable before any code is written** — planning happens read-only; you approve the spec, then execution writes the change.

## Use with Claude and Codex

The skills ship with the CLI. Initialize them, then drive the whole workflow in natural language.

<Tabs>
  <Tab title="Claude">
    ```bash theme={null}
    ooneex claude:init
    ```

    ```text Prompt icon="terminal" wrap theme={null}
    Audit the billing module, plan the findings, and implement the
    highest-priority one.
    ```
  </Tab>

  <Tab title="Codex">
    ```bash theme={null}
    ooneex codex:init
    ```

    ```text Prompt icon="terminal" wrap theme={null}
    Audit the billing module, plan the findings, and implement the
    highest-priority one.
    ```
  </Tab>
</Tabs>

## Next steps

<CardGroup cols={2}>
  <Card title="issue:create" icon={<Icon icon="terminal" size={16} />} href="/cli/commands/issue-create">
    The command that scaffolds an issue's YAML skeleton.
  </Card>

  <Card title="Monorepo" icon={<Icon icon="cubes" size={16} />} href="/getting-started/monorepo">
    Where modules and their `issues/` directories live.
  </Card>

  <Card title="Module overview" icon={<Icon icon="cube" size={16} />} href="/module/overview">
    What a module is and how its `type` selects the founder and fixer.
  </Card>

  <Card title="Workflow component" icon={<Icon icon="diagram-project" size={16} />} href="/components/workflow">
    Orchestrate reversible multi-step processes that a fix may call for.
  </Card>
</CardGroup>
