diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..dd1fcc5 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Codigo de Altura + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index d69e6d9..e0b1762 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,15 @@ # Daedalus +

+ Latest release + Downloads + CI status + GitHub stars + Go version + License: MIT + Website +

+ Daedalus is an **opinionated Claude Code harness** that makes a capable-but-drifting model work with the discipline of a senior engineer: no guessing, research before implementing, verification with fresh eyes, state on disk, and short sessions that @@ -115,4 +125,4 @@ development/ Method planning artifacts (v2 plan, benchmark) — not shi ## License -See repository for license details. +[MIT](LICENSE) — use it, adapt it, ship it. If the Method serves your team, that's the point. diff --git a/development/v2/PLAN.md b/development/v2/PLAN.md index 63daedd..88c3807 100644 --- a/development/v2/PLAN.md +++ b/development/v2/PLAN.md @@ -100,6 +100,15 @@ Estado: frontmatter en cada ticket (`status`, `commit`, `verified`). `/plan` es --- +## Fase 6 — Lanzamiento *(agregada 2026-07-02, post-merge PR #20)* + +- [ ] Release `v0.2.0` — tag pusheado; GoReleaser publica binarios; verificar install scripts contra el release. +- [ ] **Reinvención del sitio** (rama `feat/web-v2`): la página actual es un índice de documentos sin personalidad. Nueva dirección: identidad "Daedalus el arquitecto" (estética blueprint/plano técnico, logo meandro griego, linework), landing digerible con: hero + terminal animada, la línea de pensamiento (el problema → los 5 principios como paradigma), diagrama del ciclo de vida, walkthroughs concretos (proyecto nuevo / bug fix), prueba del benchmark, instalación por OS, página del Método. Docs completas quedan secundarias (nav "Manual"). Nada de dump de documentación. +- [ ] Golden tickets desde centavo → `kit/eval/` (cierre pendiente de Fase 4). +- [ ] Publicar el Método como página propia del sitio (el estándar adoptable). + +**Done cuando:** release descargable funcionando + sitio nuevo desplegado en Pages + un tercero puede entender e instalar el tool en <5 minutos sin leer el repo. + ## Reglas de trabajo entre sesiones 1. Al terminar cada sesión de construcción se actualizan los checkboxes de este archivo y se anota en `## Bitácora` qué se decidió y qué sigue. diff --git a/docs/README.md b/docs/README.md index 57094e7..129bf58 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,58 +1,61 @@ # Daedalus manual -Welcome to the Daedalus user manual. Daedalus is an **opinionated Claude Code -harness**: the kit (a constitution, skills, agents, hooks, and templates) is the -product, and the `daedalus` CLI/TUI installs, checks, and updates it. Claude Code -is the runtime; Daedalus does not execute agents itself. - -New here? Start with the **[Overview](getting-started/overview.md)** — the Daedalus -Method and the four commands (`init`, `status`, `doctor`, `update`) on one page — -then [install the binary](getting-started/installation.md). - -## Start here (v2) - -1. **[Overview](getting-started/overview.md)** — the method and the four commands. -2. **[Install](getting-started/installation.md)** — run the one-line install - script (or download a prebuilt binary / build from source); verify with - `daedalus --version`. -3. **[`kit/METHOD.md`](../kit/METHOD.md)** — the full normative standard: lifecycle, - roles and models, the document contract, councils, manual gates, token economy. -4. **[`kit/README.md`](../kit/README.md)** — the kit layout and the rules for - editing it. +Daedalus is an opinionated harness for [Claude Code](https://claude.com/claude-code). +The **kit** — a constitution, skills, agents, hooks, and templates — is the +product; the `daedalus` CLI/TUI installs it into your repo, checks it, and keeps +it up to date. Claude Code is the runtime; Daedalus does not execute agents +itself. + +New here? Read the [Quickstart](quickstart.md) — an empty repo to a shipped change +in one pass — then keep the [command reference](commands/init.md) and +[Workflow](workflow.md) nearby. + +## Getting started + +- **[Overview](getting-started/overview.md)** — the Daedalus Method and the four + commands on one page. +- **[Installation](getting-started/installation.md)** — install the binary; verify + with `daedalus --version`. +- **[Quickstart](quickstart.md)** — empty repo → `init` → first `/brief` → first + `/ticket`, as one continuous story. + +## Commands + +The `daedalus` binary has four commands. Each takes an optional target directory +(default: the current directory). + +- **[`init`](commands/init.md)** — instantiate the kit into a repo (interactive or + flags mode; non-destructive). +- **[`status`](commands/status.md)** — read-only work map from the backlog and + `STATE.md`. +- **[`doctor`](commands/doctor.md)** — read-only integrity check, with meaningful + exit codes. +- **[`update`](commands/update.md)** — bring an installed kit up to the binary's + version, backing up what it replaces. + +## Using Daedalus + +- **[Workflow](workflow.md)** — day-to-day inside Claude Code: `/brief`, `/spec`, + `/council` (and when *not* to use it), `/plan`, `/ticket`, `/epic`, `/status`. +- **[Backlog](backlog.md)** — the `development/` layout, the ticket folder + contract, and every frontmatter field. +- **[Customization](customization.md)** — template variables, the attribution + option, per-repo overrides, and what `update` never touches. +- **[Troubleshooting](troubleshooting.md)** — doctor exit codes, common failures, + and how re-`init`/`update` recover. + +## The method itself + +- **[`kit/METHOD.md`](https://github.com/Codigo-de-Altura/Daedalus/blob/main/kit/METHOD.md)** — the full normative standard: lifecycle, + roles and models, the document contract, councils, manual gates, token economy. +- **[`kit/README.md`](https://github.com/Codigo-de-Altura/Daedalus/blob/main/kit/README.md)** — the kit layout and the rules for + editing it. ## Contributing -For working **on** Daedalus itself (building, tooling, CI) — separate from using -the product. - -- [Development environment](contributing/development-environment.md) — Make targets, Docker, and Compose. -- [Continuous integration](contributing/continuous-integration.md) — what CI runs and how to reproduce it. -- [Testing and golden files](contributing/testing-and-golden-files.md) — running the suite, what golden files are, and the determinism guarantee. - -## User guide (v1 — outdated) - -> The chapters below describe **Daedalus v1**, a backend-agnostic compiler with a -> `.daedalus/` workspace, a canonical model, DAG workflows, and a `build`/`sync` -> command. That product was superseded in v2; these pages are kept for reference -> while the manual is rewritten. Each is marked outdated at its top. For current -> behavior, use the [Overview](getting-started/overview.md) and -> [`kit/METHOD.md`](../kit/METHOD.md). - -- [Quickstart](getting-started/quickstart.md) -- [Concepts](guide/concepts.md) -- [Core workflow](guide/core-workflow.md) -- [Command reference](guide/command-reference.md) -- [Command line](guide/command-line.md) -- [Navigating the interface](guide/navigating-the-tui.md) -- [Configuration](guide/configuration.md) -- [Initializing a workspace](guide/initializing-a-workspace.md) -- [Managing agents](guide/managing-agents.md) -- [Managing prompts](guide/managing-prompts.md) -- [Managing workflows](guide/managing-workflows.md) -- [Managing specs](guide/managing-specs.md) -- [Managing architecture documents](guide/managing-architecture.md) -- [Managing epics and tickets](guide/managing-epics-and-tickets.md) -- [Tracing the backlog](guide/tracing-the-backlog.md) -- [Validating conventions](guide/validating-conventions.md) -- [Compiling to a backend](guide/compiling-to-a-backend.md) -- [Examples](guide/examples.md) +For working **on** Daedalus itself — separate from using the product: + +- [Development environment](contributing/development-environment.md) — Make targets, + Docker, and Compose. +- [Continuous integration](contributing/continuous-integration.md) — what CI runs + and how to reproduce it. diff --git a/docs/backlog.md b/docs/backlog.md new file mode 100644 index 0000000..be4a884 --- /dev/null +++ b/docs/backlog.md @@ -0,0 +1,123 @@ +# The backlog + +Everything about "where the project is" lives as versioned files under +`development/`. The filesystem is the database: ticket state is frontmatter, not a +service. This chapter is the contract — the layout, the ticket folder, every +frontmatter field, and how to edit the backlog by hand. + +## The `development/` layout + +`daedalus init` creates this tree (directories empty until the skills fill them): + +``` +development/ + METHOD.md # a self-contained copy of the Daedalus Method + STATE.md # current position: active epic/ticket, blockers, next step + briefs/ # /brief output — NN-.md + specs/ # /spec output — NN-.md + decisions/ # /council output — DECISION-NN.md (ADR-style) + lessons/ # one durable lesson per file; agents read before, write after + epics/ + epic-NN-/ + epic.md # goal, scope, ticket list, links to spec + decisions + tickets/ + ticket-NN-MM-/ # the ticket folder — its name is its id + spec.md # WHAT to build + acceptance criteria + status frontmatter + validation.md # HOW the verifier checks it (executable steps) + manual-validation.md # OPTIONAL: human test script → declares a manual gate + observations.md # created only on a REJECTED verdict; feedback for the fix loop +``` + +**Naming.** Everything is `kebab-case`. Epics are `epic-NN-`; tickets are +`ticket-NN-MM-`, where `NN` is the epic number and `MM` the sequence within +it. `epic-00-inbox` is reserved for standalone tickets (bugs, chores) that don't +belong to a planned epic — it is created on first use and always sorts last in +`status`. + +## The ticket folder contract + +A ticket is a **directory**, and its name is its id. Inside: + +| File | Produced by | Purpose | +| --- | --- | --- | +| `spec.md` | planner / `/brief` quick mode | The spec: context, task, acceptance criteria — plus the state frontmatter. Always present. | +| `validation.md` | planner | The verifier's executable checks — each an exact command + expected outcome. Always present. | +| `manual-validation.md` | planner (optional) | A plain-language human test script. **Its presence, with `gate: manual-pending`, stops the workflow** on that chain until you approve. | +| `observations.md` | orchestrator | Written only when the verifier returns REJECTED; the implementer fixes from this file alone. Absent on a clean ticket. | + +`spec.md` and `validation.md` are the minimum. `manual-validation.md` is added +only where a human check adds real signal (user-facing flows, visual output, +risky data ops, the last ticket of an epic). `observations.md` appears only if +something failed verification. + +## The frontmatter — every field and its values + +Ticket state lives in the `spec.md` frontmatter. This is what +[`daedalus status`](commands/status.md) and [`daedalus doctor`](commands/doctor.md) +read, so the values must stay valid. + +```yaml +--- +id: ticket-03-02-discount-engine +status: pending # pending | in-progress | done | blocked +type: feature # feature | bug | chore +risk: normal # low | normal | high — set by the planner +commit: null # hash, set on close +verified: null # date, set on verifier APPROVED (or "self" for risk: low) +gate: none # none | manual-pending | manual-approved +--- +``` + +| Field | Allowed values | Meaning | +| --- | --- | --- | +| `id` | `ticket-NN-MM-` | Must match the folder name. | +| `status` | `pending` · `in-progress` · `done` · `blocked` | Lifecycle position. `doctor` rejects anything else. | +| `type` | `feature` · `bug` · `chore` | For a `bug`, the first acceptance criterion is always a reproducing test. | +| `risk` | `low` · `normal` · `high` | Drives verification depth: `low` skips the verifier and uses `implementer-lite`; `normal`/`high` get a full verifier pass. | +| `commit` | `null`, then a hash | Set on close. `status: done` with `commit: null` is flagged as an inconsistency. | +| `verified` | `null`, a date, or `self` | Set when the verifier approves; `self` for `risk: low` (no verifier). | +| `gate` | `none` · `manual-pending` · `manual-approved` | `manual-pending` blocks the chain and lists the ticket under WAITING ON YOU. | + +`doctor` validates the four enum fields — `status`, `type`, `risk`, `gate` — on +every ticket. A value outside the set, an empty field, or missing frontmatter is a +failure (exit 2). `null` and empty are read as "unset" for `commit`/`verified`. + +## Editing and reordering tickets by hand + +The backlog is just markdown — you are meant to edit it. `/plan` even reminds you +of this before you execute. Safe manual operations: + +- **Reprioritize** within an epic by renaming ticket folders to change the `MM` + sequence (and update the `id` inside `spec.md` to match). `/epic` runs tickets + in `MM` order, so this reorders execution. +- **Edit a ticket's task or acceptance criteria** directly in `spec.md` before it + runs. Sharpening the spec by hand is expected. +- **Delete an unstarted ticket** by removing its folder. To re-plan an unstarted + epic, delete the whole epic folder (your explicit call) and run `/plan` fresh — + `/plan` itself is additive and never renumbers existing epics. +- **Unblock or re-gate** by editing frontmatter — e.g. set `gate: + manual-approved` after you've done a manual validation, or `status: blocked` + back to `pending`. + +After any hand-edit, run `daedalus doctor` to confirm the frontmatter still +parses, and `daedalus status` to confirm `STATE.md` still agrees with the backlog +(the `INCONSISTENCIES` section catches drift). + +**Do not** hand-edit `done` tickets or renumber existing epics — completed work is +immutable history that future planning reads but never rewrites. If a done +ticket's decision was wrong, that's a new ticket, not a rewrite. + +## `STATE.md` — the one source of "where are we" + +`STATE.md` is short by design: the active epic and ticket, the phase, anything +waiting on you, blockers, and the exact next step — not history (git and +frontmatter hold that). Every session starts by reading it. The orchestrator keeps +it current at every ticket close, gate, or blocker; if you edit the backlog by +hand and it drifts, `daedalus status` reports the mismatch and offers to fix +`STATE.md` after you confirm. + +## See also + +- [Workflow](workflow.md) — the skills that produce and consume these files. +- [`daedalus status`](commands/status.md) / [`daedalus doctor`](commands/doctor.md) + — reading and validating the backlog from your shell. diff --git a/docs/commands/doctor.md b/docs/commands/doctor.md new file mode 100644 index 0000000..50459f5 --- /dev/null +++ b/docs/commands/doctor.md @@ -0,0 +1,148 @@ +# `daedalus doctor` + +Read-only integrity check of an installed kit. It verifies, in order: the kit +marker parses; the marker's kit version matches the running binary; the required +files a full install writes are present; `settings.json` is valid JSON; every +hook script the settings reference exists; and every ticket spec's frontmatter +parses with valid enum values. It writes nothing. + +## Flags + +| Flag | Values | Default | Purpose | +| --- | --- | --- | --- | +| `-plain` | bool | `false` | Render without color, for machine-readable output. | + +The optional target directory comes after the flags and defaults to the current +directory. + +## Exit codes + +`doctor` maps the **worst** result across all checks to its exit code — this is +what makes it usable in CI: + +| Exit | Meaning | +| --- | --- | +| `0` | Every check passed. | +| `1` | Worst result is a **warning** (e.g. kit-version drift — resolvable with `daedalus update`). | +| `2` | At least one check **failed** (missing files, bad frontmatter, unreadable marker), or a usage error. | + +(A `1` is also returned, without a report, only when the target path itself can't +be resolved.) + +Each check renders as one line — `ok`, `warn`, or `fail` — with a short detail in +parentheses, followed by a summary count. + +## Example 1 — a healthy install + +```console +$ daedalus doctor --plain +Daedalus doctor /home/you/printquote + +ok marker present and parses (kit 0.1.0-dev) +ok kit version matches binary (0.1.0-dev) +ok CLAUDE.md present +ok development/METHOD.md present +ok development/STATE.md present +ok skills present (7/7) +ok agents present (9/9) +ok templates present (8/8) +ok settings.json present and parses +ok hook scripts referenced by settings.json exist (2 referenced) +ok ticket specs valid (no ticket specs found) + +Summary: 11 ok, 0 warning(s), 0 failure(s) +``` + +```console +$ echo $? +0 +``` + +## Example 2 — broken frontmatter (exit 2) + +Hand-edit a ticket spec so its `status` holds a value outside the allowed enum +(`in progress` instead of `in-progress`) and `doctor` pinpoints it: + +```console +$ daedalus doctor --plain +Daedalus doctor /home/you/printquote + +ok marker present and parses (kit 0.1.0-dev) +ok kit version matches binary (0.1.0-dev) +ok CLAUDE.md present +ok development/METHOD.md present +ok development/STATE.md present +ok skills present (7/7) +ok agents present (9/9) +ok templates present (8/8) +ok settings.json present and parses +ok hook scripts referenced by settings.json exist (2 referenced) +fail ticket specs valid (7 checked, 1 issue(s): ticket-02-03-pricing: invalid status "in progress") + +Summary: 10 ok, 0 warning(s), 1 failure(s) + +$ echo $? +2 +``` + +The `ticket specs valid` check validates four enum fields per spec — `status`, +`type`, `risk`, `gate` — and reports each issue as `: `. A +spec with no YAML frontmatter reports `: no YAML frontmatter`; a +missing field reports `missing `. + +## Example 3 — version drift (exit 1, a warning) + +When the marker records an older kit version than the binary, the +version check is a **warning**, not a failure — the install is intact, it just +needs an update: + +```console +$ daedalus doctor --plain +Daedalus doctor /home/you/printquote + +ok marker present and parses (kit 0.0.9-dev) +warn kit version matches binary (kit 0.0.9-dev, binary 0.1.0-dev — run `daedalus update`) +ok CLAUDE.md present +… +ok ticket specs valid (7 checked) + +Summary: 10 ok, 1 warning(s), 0 failure(s) + +$ echo $? +1 +``` + +## Example 4 — an un-initialized directory (all fail, exit 2) + +Point `doctor` at a directory that was never `init`-ed and every structural check +fails, starting with the missing marker: + +```console +$ daedalus doctor --plain /tmp/empty +Daedalus doctor /tmp/empty + +fail marker present and parses (.claude/daedalus-kit.yaml not found — run `daedalus init`) +fail kit version matches binary (no kit version recorded in the marker) +fail CLAUDE.md present (missing CLAUDE.md) +fail development/METHOD.md present (missing development/METHOD.md) +fail development/STATE.md present (missing development/STATE.md) +fail skills present (0/7 — missing: .claude/skills/brief/SKILL.md, …) +fail agents present (0/9 — missing: .claude/agents/analyst.md, …) +fail templates present (0/8 — missing: .claude/templates/DECISION.md.tmpl, …) +fail settings.json present and parses (.claude/settings.json not found) +fail hook scripts referenced by settings.json exist (settings.json unavailable) +ok ticket specs valid (no ticket specs found) + +Summary: 1 ok, 0 warning(s), 10 failure(s) + +$ echo $? +2 +``` + +(The `ticket specs valid` check reads `ok` here because there is no backlog to +validate — "no specs" is not an error.) + +## See also + +- [Troubleshooting](../troubleshooting.md) — what each failure means and how to fix it. +- [`daedalus update`](update.md) — resolve version-drift warnings. diff --git a/docs/commands/init.md b/docs/commands/init.md new file mode 100644 index 0000000..0834a94 --- /dev/null +++ b/docs/commands/init.md @@ -0,0 +1,132 @@ +# `daedalus init` + +Instantiate the embedded kit into a repository: writes the constitution +(`CLAUDE.md`), the method copy (`development/METHOD.md`), `development/STATE.md`, +the empty backlog tree, and the `.claude/` skills, agents, hooks, and templates. +It is **non-destructive** — it writes files that are missing and skips anything +already present, so re-running it never clobbers your work. + +## Flags + +Flags come **before** the optional target directory (default: current directory). + +| Flag | Values | Default | Purpose | +| --- | --- | --- | --- | +| `-name` | string | — | Project name (required). | +| `-description` | string | — | One-line project description (required). | +| `-stack` | string | — | Primary tech stack, e.g. `Go 1.23 + Charm` (required). | +| `-build-cmd` | string | — | Build command (required). | +| `-test-cmd` | string | — | Test command (required). | +| `-lint-cmd` | string | — | Lint command (required). | +| `-chat-language` | string | `Spanish` | Language for conversation with the user. Everything written to disk stays English. | +| `-attribution` | `default` \| `none` | `default` | Commit attribution rule baked into `CLAUDE.md`. `none` = no AI trailers. | +| `-yes` | bool | `false` | Run non-interactively. Requires all six required flags. | + +The six required values are `-name`, `-description`, `-stack`, `-build-cmd`, +`-test-cmd`, and `-lint-cmd`. Supply them all (with `-yes`, or simply by passing +them) and init runs without prompting; omit any and, in a terminal, init opens an +interactive form to collect them. + +**Exit codes:** `0` on success (including a fully-skipped re-run), `2` for a usage +error (bad flags, missing required flags under `-yes`, or no terminal for the +form), `1` for a hard write failure. + +## Example 1 — non-interactive (flags mode) + +```console +$ daedalus init --yes \ + --name printquote \ + --description "Instant 3D-print quotes from an uploaded STL" \ + --stack "Go 1.23 + Charm" \ + --build-cmd "make build" \ + --test-cmd "make test" \ + --lint-cmd "make lint" \ + --chat-language English \ + --attribution none +Initialized Daedalus kit 0.1.0-dev into /home/you/printquote + 31 written, 0 skipped (already present) +``` + +This is the scriptable path — CI-friendly, no prompts. The values are recorded in +`.claude/daedalus-kit.yaml` (the *marker*) and substituted into every `.tmpl` +file, so `CLAUDE.md` now names your stack, build/test/lint commands, chat +language, and attribution rule. + +## Example 2 — interactive (form mode) + +Run `init` in a terminal with any required value missing and it opens a Huh form +instead of erroring: + +```console +$ daedalus init +``` + +The form walks three groups of fields: + +``` + Project name printquote + One-line description Instant 3D-print quotes from an uploaded STL + Stack Go 1.23 + Charm + + Build command make build + Test command make test + Lint command make lint + + Chat language English + Commit attribution ▸ Keep the tooling's default attribution + No AI attribution (only the git account owner) +``` + +Project name, description, stack, and the three commands are required — the form +will not submit while one is blank. Chat language defaults to `Spanish`; the +attribution field is a two-option select. On submit, init writes exactly what the +flags-mode run above would. + +> If you pass some values as flags and leave the required ones incomplete, the +> form pre-fills what you gave it and prompts only for the rest. + +## Example 3 — idempotency (safe re-run) + +Running `init` a second time on the same repo writes nothing and reports every +file it skipped, so you can re-run it any time without fear: + +```console +$ daedalus init --yes --name printquote --description "…" --stack "Go 1.23 + Charm" \ + --build-cmd "make build" --test-cmd "make test" --lint-cmd "make lint" +Initialized Daedalus kit 0.1.0-dev into /home/you/printquote + 0 written, 31 skipped (already present) + skipped: .claude/agents/analyst.md + skipped: .claude/agents/council-member.md + … + skipped: CLAUDE.md + skipped: development/METHOD.md + skipped: development/STATE.md +``` + +Because it only ever *adds* missing files, `init` is the wrong tool for pulling in +kit changes from a newer binary — a file that already exists is skipped, not +refreshed. To upgrade an installed kit, use [`daedalus update`](update.md). + +## What gets written + +``` +CLAUDE.md # the constitution (your values substituted in) +.claude/ + daedalus-kit.yaml # marker: kit version + recorded init variables + settings.json # hooks wiring + skills/ # /brief /spec /council /plan /ticket /epic /status + agents/ # analyst, planner, researcher, implementer(-lite), + # verifier, documenter, council-member, synthesizer + hooks/ # post-edit.ps1, reanchor.ps1 + templates/ # brief, spec, DECISION, STATE, ticket/* +development/ + METHOD.md # a self-contained copy of the method + STATE.md # where-are-we, seeded with your project name + briefs/ specs/ decisions/ lessons/ epics/ # empty backlog tree +``` + +## See also + +- [Quickstart](../quickstart.md) — init in the context of a first end-to-end run. +- [`daedalus update`](update.md) — refresh an installed kit to the binary's version. +- [Customization](../customization.md) — the template variables and the attribution option. diff --git a/docs/commands/status.md b/docs/commands/status.md new file mode 100644 index 0000000..3892c47 --- /dev/null +++ b/docs/commands/status.md @@ -0,0 +1,112 @@ +# `daedalus status` + +Print a read-only work map built from disk: epic progress, per-ticket state, +tickets waiting on a human gate, blocked tickets, and the next step recorded in +`development/STATE.md`. It writes nothing and spawns no agents — cheap enough to +run casually from your shell. + +## Flags + +| Flag | Values | Default | Purpose | +| --- | --- | --- | --- | +| `-plain` | bool | `false` | Render without color, for machine-readable / pipe-friendly output. | + +The optional target directory comes after the flags and defaults to the current +directory. + +**Exit codes:** `0` on success (including an empty backlog), `1` when no kit is +installed (no `development/STATE.md`) or a file can't be read, `2` for a usage +error. + +Where the data comes from: `status` globs +`development/epics/*/tickets/*/spec.md` and reads only each spec's frontmatter, +plus the `Now`, `Blockers`, and `Next step` sections of `development/STATE.md`. +It never opens ticket bodies. + +## Example 1 — a fresh repo (empty backlog) + +Immediately after `init`, before any `/brief` or `/plan`: + +```console +$ daedalus status --plain +EPIC PROGRESS STATE + (no epics yet) + +WAITING ON YOU + none + +BLOCKED + none + +NEXT STEP (from STATE.md) + none set + +INCONSISTENCIES + none +``` + +## Example 2 — a real backlog with a manual gate and a blocker + +With two epics under way and an inbox chore, `status` collapses finished epics to +one line and expands the active ones ticket by ticket: + +```console +$ daedalus status --plain +EPIC PROGRESS STATE +epic-01-foundation 2/2 ✔ done +epic-02-quoting 1/4 ● active + ✔ 02-01 upload (c1a4f55) + ● 02-02 parsing in-progress + ○ 02-03 pricing pending + ⛔ 02-04 e2e pending · has manual gate +epic-00-inbox 0/1 ● active + ⛔ 00-01 bump-go blocked + +WAITING ON YOU + ⛔ ticket-02-04-e2e manual validation pending (development/epics/epic-02-quoting/tickets/ticket-02-04-e2e/manual-validation.md) + +BLOCKED + ⛔ ticket-00-01-bump-go + +NEXT STEP (from STATE.md) + /ticket ticket-02-02-parsing + +INCONSISTENCIES + none +``` + +Reading the map: + +- **Glyphs.** `✔` done, `●` in-progress, `○` pending, `⛔` blocked or gated. +- **Progress** is `done / total` per epic. A done epic collapses to its summary + line; active epics expand every ticket. +- **The commit hash** in parentheses on a done ticket comes from its `commit` + frontmatter, trimmed to 7 characters. +- **`· has manual gate`** flags a ticket whose frontmatter is `gate: + manual-pending`; the same ticket is listed under **WAITING ON YOU** with a + pointer to its `manual-validation.md`. +- **`epic-00-inbox`** always sorts to the bottom, wherever its number falls. + +## Example 3 — the consistency check + +`status` reports (never fixes) mismatches between `STATE.md` and frontmatter +reality under an `INCONSISTENCIES` heading. It fires when, for example: + +- `STATE.md`'s active ticket points at a spec that is already `status: done`, or + has no spec on disk; +- a ticket is `status: in-progress` but is not the active ticket in `STATE.md`; +- a ticket is `status: done` but its `commit` is still null. + +``` +INCONSISTENCIES + ⚠ ticket-02-02-parsing is done but has no commit + ⚠ STATE's active ticket ticket-02-05-quote-ui is already done +``` + +A clean run prints `none`. This is the cheapest way to catch a `STATE.md` that +drifted out of sync with the backlog after a manual edit. + +## See also + +- [Backlog](../backlog.md) — the frontmatter fields `status` reads and how to edit them. +- [`daedalus doctor`](doctor.md) — integrity check (does the install itself parse?). diff --git a/docs/commands/update.md b/docs/commands/update.md new file mode 100644 index 0000000..a2699e6 --- /dev/null +++ b/docs/commands/update.md @@ -0,0 +1,122 @@ +# `daedalus update` + +Bring an installed kit up to the running binary's embedded version. It rewrites +only the **managed** files whose content differs from what the current kit would +produce, backs up anything it replaces, re-stamps the marker, and leaves your own +content untouched. + +## Flags + +| Flag | Values | Default | Purpose | +| --- | --- | --- | --- | +| `-dry-run` | bool | `false` | List the files that would change without writing anything. | + +The optional target directory comes after the flags and defaults to the current +directory. + +**Exit codes:** `0` on success (including a no-op update and any dry-run), `2` +when the target has no kit marker (never `init`-ed) or on a usage error, `1` for +a hard read/write failure. + +## What update manages, and what it never touches + +Update re-resolves the managed slice of the kit from the **same init variables +the marker recorded**, then rewrites only files whose bytes actually differ. + +**Managed (update may rewrite):** + +- `.claude/skills/`, `.claude/agents/`, `.claude/templates/`, `.claude/hooks/` +- `development/METHOD.md` +- the `hooks` block of `.claude/settings.json` (and *only* that block) +- the marker `.claude/daedalus-kit.yaml` (re-stamped to the new version) + +**Never written:** + +- `CLAUDE.md` (your constitution) — if the upstream template diverged, update + *reports* it for manual review rather than overwriting it +- `development/STATE.md` +- the backlog: `development/{briefs,specs,decisions,lessons,epics}/` +- every key of `settings.json` other than `hooks` + +Any file update replaces is first copied to +`.claude/.backup-/`, preserving its relative path, so a bad upgrade +is always recoverable. + +## Example 1 — preview with `--dry-run` + +`--dry-run` writes nothing and lists what would change. Here the binary is newer +than the recorded kit, but the kit content is identical, so nothing would move — +only the marker stamp differs: + +```console +$ daedalus update --dry-run +Dry run for Daedalus kit 0.0.9-dev -> 0.1.0-dev in /home/you/printquote + 0 file(s) would change, 28 unchanged +``` + +When files *would* change, each is listed as `would update: `. + +## Example 2 — a real update that backs up a replaced file + +Suppose a managed file diverged from the kit (an upstream change, or a local edit +to `.claude/skills/status/SKILL.md`). A real `update` restores the kit's version +and backs up what it replaced: + +```console +$ daedalus update +Updated Daedalus kit 0.0.9-dev -> 0.1.0-dev in /home/you/printquote + 1 updated, 27 unchanged + updated: .claude/skills/status/SKILL.md + backup: .claude/.backup-0.0.9-dev/ +``` + +The backup directory mirrors the target tree: + +``` +.claude/.backup-0.0.9-dev/ + .claude/daedalus-kit.yaml # the old marker + .claude/skills/status/SKILL.md # your replaced copy +``` + +> Because managed files are overwritten to match the kit, `.claude/skills`, +> `.claude/agents`, `.claude/templates`, and `.claude/hooks` are **not** the place +> for per-repo customization — update will revert your edits (after backing them +> up). See [Customization](../customization.md) for where local overrides belong. + +## Example 3 — nothing to do (no-op) + +Running `update` when the kit already matches the binary re-stamps nothing and +reports a clean pass: + +```console +$ daedalus update +Updated Daedalus kit 0.1.0-dev -> 0.1.0-dev in /home/you/printquote + 0 updated, 28 unchanged +``` + +## Example 4 — not a kit (exit 2) + +```console +$ daedalus update /tmp/empty +update: /tmp/empty is not a Daedalus kit (no .claude/daedalus-kit.yaml). Run `daedalus init` first. + +$ echo $? +2 +``` + +## The constitution note + +If your `CLAUDE.md` no longer matches what the current template would render — +because you edited it, or because the template changed upstream — update appends: + +``` + constitution template changed upstream — review manually +``` + +It never rewrites `CLAUDE.md` for you. Compare it against the template under +`kit/constitution/CLAUDE.md.tmpl` and merge by hand what you want. + +## See also + +- [`daedalus doctor`](doctor.md) — detects the version drift update resolves. +- [Customization](../customization.md) — what is safe to edit and what update reverts. diff --git a/docs/contributing/continuous-integration.md b/docs/contributing/continuous-integration.md index b3677f8..c7a7c15 100644 --- a/docs/contributing/continuous-integration.md +++ b/docs/contributing/continuous-integration.md @@ -3,8 +3,8 @@ [← Back to the manual index](../README.md) Daedalus uses three GitHub Actions workflows: one keeps the repository building, -tested, and clean on every change; one publishes the documentation site; and one -publishes release binaries. +tested, and clean on every change; one publishes the site (marketing pages plus +this manual); and one publishes release binaries. ## The CI workflow @@ -32,26 +32,32 @@ make lint If all three succeed locally, the CI gate will pass. See [Development environment](development-environment.md) for the Make targets. -## The docs workflow +## The site workflow -The docs workflow (`.github/workflows/docs.yml`) builds the documentation site -from `docs/` with **MkDocs Material** and deploys it to **GitHub Pages**. It runs -when `docs/` or `mkdocs.yml` changes on `main`. The build is run with -`mkdocs build --strict`, so a broken internal link or an orphaned page **fails** -the build — keeping the published manual consistent. +The site workflow (`.github/workflows/pages.yml`) builds the marketing + +documentation single-page app in `web/` and deploys it to **GitHub Pages**. The +SPA renders the manual authored in `docs/`, so it runs when either `web/` or +`docs/` changes on `main` (and on manual dispatch). The job installs with +`npm ci` and builds with `npm run build`, setting `VITE_BASE: /Daedalus/` so the +emitted asset paths match the project Pages URL +(`https://.github.io/Daedalus/`). The built `web/dist` is uploaded and +deployed by a second job. This supersedes the old MkDocs pipeline. ### Preview the site locally -Install the pinned tooling (`docs-requirements.txt` pins -`mkdocs-material==9.5.39`) and serve or build the site: +Build the SPA exactly as CI does — from the `web/` directory, with `VITE_BASE` +set so links and assets resolve under the Pages path: ```sh -pip install -r docs-requirements.txt -mkdocs serve # live preview at http://127.0.0.1:8000 -mkdocs build --strict # exactly what CI runs +cd web +npm ci +npm run dev # live preview at http://localhost:5173 +VITE_BASE=/Daedalus/ npm run build # exactly what CI runs; output in web/dist ``` -If `mkdocs build --strict` succeeds locally, the docs gate will pass. +On Windows PowerShell, set the env var separately (a leading-slash value gets +mangled if inlined): `$env:VITE_BASE="/Daedalus/"; npm run build`. If +`npm run build` succeeds, the site gate will pass. ## The release workflow diff --git a/docs/contributing/testing-and-golden-files.md b/docs/contributing/testing-and-golden-files.md deleted file mode 100644 index 7557ab0..0000000 --- a/docs/contributing/testing-and-golden-files.md +++ /dev/null @@ -1,75 +0,0 @@ -# Testing and golden files - -[← Back to the manual index](../README.md) - -This page is for working on Daedalus itself. It covers the test suite, the -golden files that pin the expected compilation output, and the workflow for -updating them when a change is intentional. - -## Running the tests - -Run the whole suite from the repository root: - -```sh -go test ./... -``` - -If your environment has the Make targets available, `make test` runs the same -suite. See [Development environment](development-environment.md) for the targets, -and [Continuous integration](continuous-integration.md) for what CI runs. - -The tests live next to the code they cover, in `_test.go` files across the core -packages under `internal/`. They exercise the domain model, schema validation, -and (de)serialization, and they are **hermetic**: each test uses a temporary -directory (`t.TempDir()`) and avoids the network, the clock, and absolute paths, -so the suite runs the same way on Windows, macOS, and Linux. - -## What golden files are - -A **golden file** is a checked-in copy of the expected output. The test compiles -(or serializes) a known input and compares the result against the golden, -**byte for byte**. The golden is the reviewed, expected output; if a change makes -the real output differ, the test fails. That failure is the safety net — it -catches unintended changes to compiled artifacts before they reach a pull -request. - -The compilation goldens fix the expected `build` output under: - -``` -internal/compile/testdata/golden/.claude/... -``` - -`TestClaudeGolden` compares the compiled `.claude/` tree against that golden. -In addition, per-domain golden serialization tests live in eight packages — -`architecture`, `backlog`, `catalog`, `compile`, `prompts`, `specs`, -`workflows`, and `workspace` — each pinning the canonical serialized form of its -domain. - -## Updating goldens when a change is intentional - -When output changes **on purpose** (for example, you deliberately adjust the -compiled layout or a serialized format), regenerate the affected golden with the -`-update` flag, then review the resulting diff: - -```sh -go test ./internal/ -run Golden -update -``` - -Regenerate per package, then inspect the golden diff as part of your change so a -reviewer can see exactly what the output became. A golden diff in a pull request -should always be intentional and explained. - -> Scope `-update` per package. Packages that have no golden tests (such as -> `internal/tui`) do not register the flag, so running it across every package -> at once fails with `flag provided but not defined: -update`. Target the -> specific package — `go test ./internal/ -run Golden -update` — rather than -> the whole tree. - -## Determinism and git-friendliness - -Golden comparison only works because compilation is **deterministic**: the same -input always produces byte-identical artifacts, no matter how many times you run -it. Output is also **ordered and stable**, so it diffs cleanly in Git. This is -what makes the goldens trustworthy — a difference always means the input or the -compiler changed, never incidental noise from ordering, timestamps, the network, -or machine-specific paths. diff --git a/docs/customization.md b/docs/customization.md new file mode 100644 index 0000000..f8e0917 --- /dev/null +++ b/docs/customization.md @@ -0,0 +1,110 @@ +# Customization + +Daedalus is opinionated, but three things are yours to shape: the values baked in +at `init`, the attribution rule, and per-repo overrides. This chapter covers what +you can change, how, and — critically — what survives `daedalus update` and what +does not. + +## Template variables + +Kit files ending in `.tmpl` contain `{{VARIABLE}}` placeholders that `daedalus +init` resolves from the values you provide (as flags or through the form). These +are the variables it resolves: + +| Variable | Init flag | Example | +| --- | --- | --- | +| `{{PROJECT_NAME}}` | `-name` | `printquote` | +| `{{PROJECT_DESCRIPTION}}` | `-description` | One-sentence purpose of the repo | +| `{{STACK}}` | `-stack` | `Go 1.23 + Charm` | +| `{{BUILD_CMD}}` | `-build-cmd` | `make build` | +| `{{TEST_CMD}}` | `-test-cmd` | `make test` | +| `{{LINT_CMD}}` | `-lint-cmd` | `make lint` | +| `{{CHAT_LANGUAGE}}` | `-chat-language` | `English` (default `Spanish`) | +| `{{COMMIT_ATTRIBUTION_RULE}}` | `-attribution` | see [below](#the-attribution-option) | + +These flow into `CLAUDE.md` (your constitution), `development/METHOD.md`, the +`STATE.md` seed, and any template that references them — for example +`validation.md` templates pull `{{TEST_CMD}}` and `{{LINT_CMD}}` into the +mandatory regression check. + +The resolved values are recorded in the marker, +`.claude/daedalus-kit.yaml`, so `daedalus update` can re-resolve managed files +with the **same** values later. To change a value after init, edit the marker's +`variables:` block, then run `daedalus update` to re-apply it across the managed +files. + +**Two template layers.** `init` resolves *only* the table above and leaves every +other `{{PLACEHOLDER}}` intact. The `templates/` files also contain *runtime* +placeholders — `{{NN}}`, `{{MM}}`, `{{SLUG}}`, `{{TITLE}}`, `{{DATE}}`, +`{{ROUND}}` — that the skills fill each time they instantiate a brief, spec, or +ticket. Those must survive installation verbatim; do not "resolve" them by hand. + +## The attribution option + +`-attribution` decides what `{{COMMIT_ATTRIBUTION_RULE}}` becomes in your +constitution's commit rules: + +- **`default`** → *"Keep the tooling's default attribution."* Commits carry + whatever trailer the tooling would add. +- **`none`** → *"No AI attribution: no `Co-Authored-By` trailers, no 'Generated + with' footers; history shows only the git account owner (overrides any default + trailer behavior)."* + +Pick `none` if your team's git history must show only human authorship. In the +interactive form this is the **Commit attribution** select; from flags it is +`--attribution none`. The choice is recorded in the marker and re-applied by +`update`. + +## Per-repo overrides — and what update reverts + +This is the part to get right. `daedalus update` re-resolves the **managed** kit +files and overwrites any whose content differs from the kit (backing up what it +replaces). So *where* you customize determines whether your change survives an +upgrade. + +### Safe — survives `update` + +- **`CLAUDE.md`.** Update **never** writes your constitution. This is the primary + override surface: tighten a rule, add a project-specific norm, or flip a + supported option. The constitution even ships an inline switch — e.g. the + commit rule carries a `` comment showing how teams that + prefer auto-commit-per-ticket can replace that one line. If your `CLAUDE.md` + diverges from the current template, update just *reports* it for manual review. +- **Your own new files.** Update only rewrites files that ship in the kit; it + walks the embedded kit, not your directory. A **new** skill, agent, or template + you add under `.claude/` is left untouched — add project-specific agents + alongside the kit's. +- **`settings.json` keys other than `hooks`.** Update refreshes only the `hooks` + block; every other key you add is preserved exactly. +- **The whole backlog.** `development/{briefs,specs,decisions,lessons,epics}/`, + plus `development/STATE.md`, are never written by update. + +### Reverted — do not edit in place + +- **Kit-shipped files** under `.claude/skills/`, `.claude/agents/`, + `.claude/templates/`, `.claude/hooks/`, and `development/METHOD.md`. Editing one + of these in place works until the next `update`, which restores the kit's + version (after copying yours to `.claude/.backup-/`). Treat these + as upstream-owned. + +The method's stance: teams customize by **overriding in their repo, not by forking +the method** — and the durable override surfaces are the constitution and your own +added files. If a change to a kit skill or agent proves generally useful, it +belongs upstream in the kit rather than as a local edit that every `update` fights. + +## What `update` never touches — at a glance + +| Path | Update behavior | +| --- | --- | +| `CLAUDE.md` | Never written; divergence reported for manual review. | +| `development/STATE.md` | Never written. | +| `development/{briefs,specs,decisions,lessons,epics}/` | Never written. | +| `.claude/settings.json` (non-`hooks` keys) | Preserved; only `hooks` refreshed. | +| Files you added that aren't in the kit | Never written or deleted. | +| `.claude/{skills,agents,templates,hooks}`, `development/METHOD.md` (kit files) | Rewritten to match the kit; old copy backed up. | + +## See also + +- [`daedalus update`](commands/update.md) — the mechanics of managed vs preserved files. +- [`daedalus init`](commands/init.md) — where these variables are first set. +- [`kit/README.md`](https://github.com/Codigo-de-Altura/Daedalus/blob/main/kit/README.md) — the kit layout and rules for editing it upstream. diff --git a/docs/getting-started/installation.md b/docs/getting-started/installation.md index ed126b5..90d8aec 100644 --- a/docs/getting-started/installation.md +++ b/docs/getting-started/installation.md @@ -129,7 +129,8 @@ installed correctly. ## Next steps -- Follow the [Quickstart](quickstart.md) to go from zero to a compiled - workspace. -- Learn the ideas behind the workspace in [Concepts](../guide/concepts.md). -- See every command in the [Command reference](../guide/command-reference.md). +- Read the [Overview](overview.md) — the Daedalus Method and the four commands + (`init`, `status`, `doctor`, `update`) on one page. +- Run `daedalus init` in a repo, then drive the workflow inside Claude Code with + the `/brief`, `/spec`, `/plan`, `/ticket`, and `/epic` skills. +- Read [`kit/METHOD.md`](https://github.com/Codigo-de-Altura/Daedalus/blob/main/kit/METHOD.md) for the full normative standard. diff --git a/docs/getting-started/overview.md b/docs/getting-started/overview.md index d87a12b..120ec20 100644 --- a/docs/getting-started/overview.md +++ b/docs/getting-started/overview.md @@ -37,7 +37,7 @@ IDEA ──► SPEC ──► DESIGN ──► PLAN ──► EXECUTE (per ticke The full normative standard — roles and models, the document contract, councils, manual gates, and the token economy — lives in -[`kit/METHOD.md`](../../kit/METHOD.md). +[`kit/METHOD.md`](https://github.com/Codigo-de-Altura/Daedalus/blob/main/kit/METHOD.md). ## The four commands @@ -75,9 +75,5 @@ progress from your shell with `daedalus status`. ## Where to go next - [Installation](installation.md) — install the `daedalus` binary. -- [`kit/METHOD.md`](../../kit/METHOD.md) — the full method. -- [`kit/README.md`](../../kit/README.md) — the kit layout and how to edit it. - -> Chapters under **User guide** below the v1 line describe the previous version of -> Daedalus (a backend-agnostic compiler with a `.daedalus/` workspace) and are kept -> for reference while the manual is rewritten for v2. +- [`kit/METHOD.md`](https://github.com/Codigo-de-Altura/Daedalus/blob/main/kit/METHOD.md) — the full method. +- [`kit/README.md`](https://github.com/Codigo-de-Altura/Daedalus/blob/main/kit/README.md) — the kit layout and how to edit it. diff --git a/docs/getting-started/quickstart.md b/docs/getting-started/quickstart.md deleted file mode 100644 index deb8752..0000000 --- a/docs/getting-started/quickstart.md +++ /dev/null @@ -1,154 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Quickstart - -[← Back to the manual index](../README.md) - -This walkthrough takes you from zero to a **compiled workspace** in a few -commands. Follow it top to bottom in a throwaway directory and you will end with -an initialized `.daedalus/` workspace and a generated `.claude/settings.json`. -Every command and output below matches Daedalus's actual behavior. - -## 1. Install and verify - -Install Daedalus with the one-line script (see [Installation](installation.md) -for pinning a version, manual downloads, and building from source): - -```sh -# Linux and macOS -curl -fsSL https://raw.githubusercontent.com/Codigo-de-Altura/Daedalus/main/scripts/install.sh | sh -``` - -```powershell -# Windows (PowerShell) -irm https://raw.githubusercontent.com/Codigo-de-Altura/Daedalus/main/scripts/install.ps1 | iex -``` - -Then confirm it runs: - -```sh -daedalus --version -# daedalus 0.1.0-dev -``` - -## 2. Initialize a workspace - -Move to the repository you want to manage and create the `.daedalus/` -workspace: - -```sh -cd /path/to/your-repo -daedalus init -``` - -``` -Created Daedalus workspace at .daedalus from scratch. -Seeded factory workflow "sdd-default" at .daedalus/workflows/sdd-default.yaml. -``` - -This creates the canonical `.daedalus/` structure — the backend-agnostic source -of truth for your project's AI scaffolding — and seeds the default SDD workflow, -`sdd-default`, so you start with a ready-to-use pipeline. It is safe to run in an -existing repository: it never touches files outside `.daedalus/`. - -## 3. Inspect the workspace - -A freshly initialized workspace contains the canonical layout, the manifest, the -project guideline, and the seeded workflow: - -``` -.daedalus/ - agents/ - prompts/ - workflows/ - sdd-default.yaml # the seeded factory workflow - specs/ - architecture/ - epics/ - tickets/ - docs/ - .state/ - daedalus.yaml # the workspace manifest - init.md # the project guideline -``` - -See [Concepts](../guide/concepts.md) for what each part is, and -[Initializing a workspace](../guide/initializing-a-workspace.md) for `init`'s -options. - -## 4. Validate - -Check that the workspace follows the conventions and that its definitions are -well-formed. A fresh workspace passes both axes clean: - -```sh -daedalus validate -``` - -``` -Conventions: workspace conforms (no violations). -Definitions: all agents, workflows and manifest are valid. -``` - -Exit code `0` means the workspace is ready to compile. - -## 5. Preview the build - -`daedalus build` compiles the canonical definition into your backend's native -format. Preview it first — `--preview` shows the diff and writes nothing. A bare -workspace has just one artifact to compile, `.claude/settings.json`: - -```sh -daedalus build --preview -``` - -``` -Preview of compiling . (no files written): - claude-code: 1 new, 0 modified, 0 unchanged (of 1 artifact) - [new] .claude/settings.json - + { - + "$schema": "https://json.schemastore.org/claude-code-settings.json", - + "daedalus": { - + "managed": true, - + "generator": "daedalus" - + } - + } -``` - -## 6. Build - -In an interactive terminal, run `daedalus build` and confirm at the gate. To -compile non-interactively (or from a script/CI), pass `--yes`: - -```sh -daedalus build --yes -``` - -``` -Compiled .: - claude-code: 1 created, 0 updated, 0 unchanged (of 1 artifact) - + .claude/settings.json -``` - -You now have a compiled workspace: `.claude/settings.json` exists. Re-running the -build with nothing changed is an idempotent no-op: - -```sh -daedalus build --yes -``` - -``` -Compiled .: - claude-code: 0 created, 0 updated, 1 unchanged (of 1 artifact) -``` - -## Where to go next - -- [Concepts](../guide/concepts.md) — the workspace, the canonical model, and - compilation. -- [Core workflow](../guide/core-workflow.md) — the everyday edit → validate → - build loop. -- [Command reference](../guide/command-reference.md) — every command, its flags, - and exit codes. -- [Examples](../guide/examples.md) — add an agent, a prompt, and a workflow, then - compile. diff --git a/docs/guide/command-line.md b/docs/guide/command-line.md deleted file mode 100644 index 26b117a..0000000 --- a/docs/guide/command-line.md +++ /dev/null @@ -1,71 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Command line - -[← Back to the manual index](../README.md) - -Daedalus is a terminal application. Run it with no arguments to open the -interface, or use a subcommand such as `init`. - -## Launching the interface - -In an interactive terminal: - -```sh -./daedalus -``` - -The interface opens on a **root menu** listing the six areas of your workspace — -**Init**, **Agents**, **Prompts**, **Workflows**, **Backlog**, and **Build**. -Press `enter` to enter an area, `esc` to go back, and `h` to return to the root -menu; a help line at the bottom shows the keys available on the current screen. -The interface is **read-only** — it shows you what is there; you create and edit -artifacts with the `daedalus` commands. - -[Navigating the interface](navigating-the-tui.md) is the authoritative chapter on -the TUI: the six areas, moving in and out, the breadcrumb, reading documents, -filtering lists, contextual help, and the full keyboard reference. - -### Quitting - -Press `q` or `Ctrl+C`. The interface closes cleanly, restores your terminal, and -the process exits with code `0`. - -## Non-interactive use - -When Daedalus runs without an interactive terminal — piped input, a script, CI, -or a container without a TTY — it does not start the full interface. Instead it -prints a short notice and exits with code `0`: - -```sh -echo q | ./daedalus -# daedalus 0.1.0-dev — run in an interactive terminal to launch the TUI. -``` - -This makes Daedalus safe to invoke from automation without leaving the terminal -in an unexpected state. - -## Version and help - -```sh -./daedalus --version # print the version and exit -./daedalus --help # print usage and exit -``` - -## Subcommands - -Daedalus dispatches subcommands **positionally**. The core subcommands are: - -| Command | Purpose | -| ------------------ | -------------------------------------------------------------- | -| `daedalus init` | Create (or non-destructively upgrade) the `.daedalus/` workspace. | -| `daedalus build` | Compile the canonical definition to your backend (alias `sync`). | -| `daedalus validate`| Check the workspace against the conventions and lint definitions. | -| `daedalus trace` | Verify or navigate the spec → epic → ticket traceability chain. | - -Daedalus also provides definition-management and SDD-backlog subcommands — -`agent`, `prompt`, `workflow`, `spec`, `architecture`, `epic`, and `ticket`. - -Each subcommand supports `--help`, for example `daedalus init --help`. For the -full surface — purpose, flags, exit codes, and examples — see the -[Command reference](command-reference.md). diff --git a/docs/guide/command-reference.md b/docs/guide/command-reference.md deleted file mode 100644 index 4afd300..0000000 --- a/docs/guide/command-reference.md +++ /dev/null @@ -1,304 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Command reference - -[← Back to the manual index](../README.md) - -This is the reference for the **core** Daedalus commands: the version flag, the -interactive interface, and the subcommands `init`, `build` (alias `sync`), -`validate`, and `trace`. Each entry lists the command's purpose, its -flags/parameters, its exit codes, and at least one example. - -Daedalus dispatches subcommands **positionally** — `daedalus init`, -`daedalus build`, `daedalus validate`, `daedalus trace`. Each subcommand has its -own `--help`, for example `daedalus init --help`. - -The **definition-management** and **SDD-backlog** commands -(`agent`, `prompt`, `workflow`, `spec`, `architecture`, `epic`, `ticket`) are -documented in their own chapters — see [Managing agents](managing-agents.md), -[Managing prompts](managing-prompts.md), -[Managing workflows](managing-workflows.md), [Managing specs](managing-specs.md), -[Managing architecture documents](managing-architecture.md), and -[Managing epics and tickets](managing-epics-and-tickets.md). Running any of those -with no operation prints its usage and exits `2`. - -> **Output convention.** Daedalus prints the **human-readable summary** to -> **standard output (stdout)** and **structured JSON logs** to **standard error -> (stderr)**. The log threshold is controlled by `DAEDALUS_LOG_LEVEL` (default -> `info`); see [Configuration](configuration.md#logging). The examples below show -> the stdout summary. - -## `--version` - -Print the Daedalus version and exit. - -```sh -daedalus --version -# daedalus 0.1.0-dev -``` - -Exit code: `0`. - -## The interface (no subcommand) - -Run `daedalus` with **no subcommand** to launch the interactive TUI. It requires -an interactive terminal. - -```sh -daedalus -``` - -In an interactive terminal this opens the interface; see -[Navigating the interface](navigating-the-tui.md) for the areas and keys. When -there is no interactive terminal (piped input, a script, CI, or a container with -no TTY), Daedalus does **not** start the interface — it prints a short notice and -exits `0`. See [Command line](command-line.md#non-interactive-use). - -## `daedalus init` - -Create the canonical `.daedalus/` workspace. If a workspace already exists, -`init` performs a **non-destructive upgrade** — it adds only the missing -directories and root artifacts and never overwrites your content. - -Full chapter: [Initializing a workspace](initializing-a-workspace.md). - -### Flags - -| Flag | Default | Description | -|---|---|---| -| `-backend ` | `claude-code` | Target backend(s) recorded in the manifest, comma-separated. The MVP supports only `claude-code`. | -| `-path ` | `.` | Target repository directory. | -| `-preview` | off | Dry run: show the changes without writing anything. | - -### Exit codes - -| Exit code | Meaning | -|---|---| -| `0` | The workspace was created or upgraded (or, with `-preview`, the preview was shown). | -| `2` | Usage error — for example, an unsupported `-backend` value. Nothing is written. | - -### Examples - -First run in an empty directory: - -```sh -daedalus init -``` - -``` -Created Daedalus workspace at .daedalus from scratch. -Seeded factory workflow "sdd-default" at .daedalus/workflows/sdd-default.yaml. -``` - -Exit `0`. This creates the workspace directories plus the root artifacts and -seeds the factory workflow `sdd-default`. - -Re-running on a workspace that is already complete: - -```sh -daedalus init --preview -``` - -``` -Existing Daedalus workspace at .daedalus is already complete — nothing to update. -``` - -Exit `0`, nothing written. - -## `daedalus build` (alias `daedalus sync`) - -Compile the canonical `.daedalus/` definition into the configured backend's -native format (`.claude/` for Claude Code). The definition is **validated -first**; an invalid definition aborts the build with nothing written. `sync` is -an exact alias. - -In an interactive terminal, `build` shows a diff/preview and asks you to confirm -before writing. `--preview` shows the diff and never writes. `--yes` writes -without the gate (for CI). Without a TTY and without `--yes`, `build` prints the -diff and writes nothing. - -Full chapter: [Compiling to a backend](compiling-to-a-backend.md). - -### Flags - -| Flag | Default | Description | -|---|---|---| -| `-path ` | `.` | Repository directory to compile. | -| `-preview` | off | Dry run: show the diff and exit without writing. | -| `-yes` | off | Write without the interactive confirmation gate (for scripts and CI). | - -### Exit codes - -| Exit code | Meaning | -|---|---| -| `0` | Success — the definition was compiled (or previewed). | -| `2` | Usage error — an invalid flag or argument. | -| `3` | Validation error — the canonical definition is invalid; nothing written. | -| `4` | Compilation or write error (for example, no adapter for the configured backend); nothing written. | - -### Examples - -Preview the plan without writing (a fresh workspace has only `settings.json` to -compile): - -```sh -daedalus build --preview -``` - -``` -Preview of compiling . (no files written): - claude-code: 1 new, 0 modified, 0 unchanged (of 1 artifact) - [new] .claude/settings.json - + { - + "$schema": "https://json.schemastore.org/claude-code-settings.json", - + "daedalus": { - + "managed": true, - + "generator": "daedalus" - + } - + } -``` - -Exit `0`. - -Write non-interactively: - -```sh -daedalus build --yes -``` - -``` -Compiled .: - claude-code: 1 created, 0 updated, 0 unchanged (of 1 artifact) - + .claude/settings.json -``` - -Exit `0`. Re-running with nothing changed is an idempotent no-op: - -```sh -daedalus build --yes -``` - -``` -Compiled .: - claude-code: 0 created, 0 updated, 1 unchanged (of 1 artifact) -``` - -Exit `0`. - -## `daedalus validate` - -Validate the workspace along two axes and **report** — it never fixes anything. - -- **Conventions** — kebab-case and id patterns (`epic-NN-`, - `ticket-NN-MM-`), the canonical layout, YAML/Markdown formatting, and - spec → epic → ticket traceability. -- **Definitions** — the agent, workflow (DAG), and manifest schemas: required - fields, DAG cycles, missing artifacts, unknown agents, unsupported backends. - -Full chapter: [Validating conventions](validating-conventions.md). - -### Flags - -| Flag | Default | Description | -|---|---|---| -| `-path ` | `.` | Target repository directory whose `.daedalus/` workspace is validated. | - -### Exit codes - -| Exit code | Meaning | -|---|---| -| `0` | No errors — the workspace conforms. | -| `1` | Errors found in either axis. | -| `2` | Usage error. | - -### Examples - -A clean workspace: - -```sh -daedalus validate -``` - -``` -Conventions: workspace conforms (no violations). -Definitions: all agents, workflows and manifest are valid. -``` - -Exit `0`. - -A workspace with an error — here the manifest lists an unsupported backend: - -```sh -daedalus validate -``` - -``` -Conventions: workspace conforms (no violations). -Definitions: 1 error and 0 warnings: - - [error] .daedalus/daedalus.yaml: backends[nonexistent-backend]: schema: observed unsupported backend "nonexistent-backend"; expected one of the supported backends: claude-code -``` - -Exit `1`. Each finding names the file, the spot (`backends[...]`), the rule -(`schema`), and observed-vs-expected — the **actionable report** you act on. See -[Troubleshooting](troubleshooting.md) for how to read findings. - -## `daedalus trace ` - -Read-only navigation and verification of the spec → epic → ticket traceability -chain, using the links already recorded in your artifacts. Running -`daedalus trace` with **no operation** is a usage error and exits `2`. - -Full chapter: [Tracing the backlog](tracing-the-backlog.md). - -### `daedalus trace verify` - -Check that the chain is consistent and report inconsistencies, worst-first. - -| Flag | Default | Description | -|---|---|---| -| `-path ` | `.` | Target repository directory whose `.daedalus/` chain is verified. | - -Exit codes: - -| Exit code | Meaning | -|---|---| -| `0` | The chain is consistent, or has only warnings. | -| `1` | At least one hard error (a `broken-link` or an `orphan-ticket`). | -| `2` | Usage or load error. | - -Example on a fresh workspace (no specs/epics/tickets yet): - -```sh -daedalus trace verify -``` - -``` -Traceability chain is consistent (no inconsistencies). -``` - -Exit `0`. - -### `daedalus trace show ` - -Navigate the chain from an artifact, with the direction inferred from the id -shape: - -- a **spec slug** descends — spec → its epics → their tickets; -- an **epic id** (`epic-NN-`) shows both — the epic's origin and its - tickets; -- a **ticket id** (`ticket-NN-MM-`) ascends — ticket → its epic → its - origin spec/architecture. - -| Flag | Default | Description | -|---|---|---| -| `-path ` | `.` | Target repository directory whose `.daedalus/` chain is navigated. | - -Example: - -```sh -daedalus trace show epic-05-sdd-backlog -``` - -See [Tracing the backlog](tracing-the-backlog.md#navigating-the-chain) for the -full output shapes. (`trace show` needs an existing artifact id; a freshly -initialized workspace has none yet.) diff --git a/docs/guide/compiling-to-a-backend.md b/docs/guide/compiling-to-a-backend.md deleted file mode 100644 index 8ad4599..0000000 --- a/docs/guide/compiling-to-a-backend.md +++ /dev/null @@ -1,400 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Compiling to a backend - -[← Back to the manual index](../README.md) - -Your `.daedalus/` workspace is the **canonical, backend-agnostic** definition of -your project's AI structure — agents, prompts, workflows, and the SDD backlog. -Before an agent tool such as Claude Code can use it, that definition has to be -**compiled** into the tool's own native format. The `daedalus build` command (and -its alias `daedalus sync`) does exactly that: it reads your canonical -definition, validates it, and writes the native artifacts for the backend you -configured in the manifest. - -## The task, end to end - -- **You have** a `.daedalus/` workspace (created with - [`daedalus init`](initializing-a-workspace.md)) and a target backend recorded - in [`daedalus.yaml`](configuration.md#the-workspace-manifest-daedalusyaml). -- **You run** `daedalus build` from inside the repository. -- **Daedalus** validates the canonical definition, selects the adapter for your - configured backend, and compiles the definition into that backend's native - format — or stops with an actionable error and **writes nothing** if anything - is wrong. - -## Usage - -From the root of a repository that contains a `.daedalus/` workspace: - -```sh -daedalus build -``` - -`sync` is an exact alias and behaves identically — use whichever name you prefer: - -```sh -daedalus sync -``` - -Daedalus reads the target backend from `daedalus.yaml`, validates your canonical -definition, and — **in an interactive terminal** — shows you a -[preview of every change and asks you to confirm](#previewing-and-confirming-changes) -before writing anything. - -To target a repository in a different directory, use `--path`: - -```sh -daedalus build --path ./my-repo -``` - -See all options with: - -```sh -daedalus build --help -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Repository directory to compile. Defaults to the current directory. | -| `--preview` | Show the diff/preview and **exit without writing** anything (a read-only dry run). | -| `--yes` | Write **without** the interactive confirmation, for scripts and CI. See [Writing from a script or CI](#writing-from-a-script-or-ci). | -| `--help` | Show all available options. | - -> By default, running `build` in a terminal opens an interactive preview and -> writes only after you confirm — nothing is written silently. The exact behavior -> depends on whether you are in a terminal and which flags you pass; see -> [Previewing and confirming changes](#previewing-and-confirming-changes). - -## Safe by design: validate first, write nothing on error - -`build` is built to fail **before** it touches your files, never half-way -through. In each of the cases below it stops and reports an actionable error, and -**no artifacts are written**: - -- **No workspace.** If there is no `.daedalus/` workspace in the target - directory, `build` aborts and points you at - [`daedalus init`](initializing-a-workspace.md) to create one first. -- **Invalid canonical definition.** Before compiling, `build` validates your - canonical definition. If it finds problems, it reports them and stops without - writing — so a broken definition can never produce broken output. Fix the - reported issues and run the command again. -- **No adapter for the backend.** If the backend configured in `daedalus.yaml` - has no registered adapter, `build` fails with a clear message and writes - nothing. - -This validate-first behavior means a failed `build` always leaves your repository -exactly as it was. - -## Previewing and confirming changes - -`build` never writes silently. In an interactive terminal it first opens a -**preview** of every change and waits for your explicit confirmation before it -touches disk — so you always see exactly what would change and decide whether to -apply it. - -### The interactive preview - -Run `build` in a terminal: - -```sh -daedalus build -``` - -Daedalus computes the full plan and opens a preview screen. At the top is a -**summary** of the counts per backend; below it, the artifacts are listed and -classified as **new**, **modified**, or **unchanged**; and for the artifact you -select, the **content diff** is shown — added lines prefixed with `+`, removed -lines with `-`. At the bottom is the **confirmation gate**: - -``` -claude-code: 1 new, 1 modified, 3 unchanged - - [new] commands/summarize.md - [modified] agents/reviewer.md - [unchanged] agents/planner.md - [unchanged] settings.json - [unchanged] commands/release-notes.md - - agents/reviewer.md - - You are the code reviewer. Report correctness and style issues. - + You are the code reviewer. Inspect the proposed changes and report any - + correctness, security, or style issues, worst-first. - -Write these changes? y/enter to confirm · n/esc to cancel (nothing is written) -``` - -Controls: - -- **↑ / ↓** — move between artifacts in the list. -- **pgup / pgdn**, and **g / G** — scroll the diff of the selected artifact (top - and bottom). -- **y** or **enter** — confirm and write the changes. -- **n** or **esc** — cancel; **nothing is written** and your repository is left - exactly as it was. -- **ctrl+c** — exit at any time. - -If there is nothing to write, the preview says so plainly and there is nothing to -confirm: - -``` -No changes — every artifact is already up to date. -``` - -#### Orphans in the preview - -Any [orphans](#orphans-are-reported-never-deleted) — generated files whose -canonical source you removed — appear in their own read-only section, headed -**“Orphans — left untouched · not selectable.”** They are shown for your -awareness only: you cannot navigate into them, and Daedalus never deletes them. -Remove an orphan yourself if you no longer want it. - -### Preview only, never write (`--preview`) - -Use `--preview` to inspect the plan **without the option to write**: - -```sh -daedalus build --preview -``` - -In a terminal this opens the same preview screen in **read-only** mode — you can -browse the list and diffs, but there is no confirmation gate, and the footer -reads *“Read-only preview — nothing will be written.”* Outside a terminal it -prints the plan and diff as text. Either way, `--preview` never writes. - -### Writing from a script or CI - -When `build` runs **without an interactive terminal** — a script, CI, or a -container with no TTY — there is no one to confirm at the gate. To keep the safe -default, a plain `build` in that situation **writes nothing**: it prints the plan -and diff, then tells you how to proceed: - -``` -Nothing written; pass --yes to write, or run in a terminal to confirm. -``` - -To actually write from automation, pass `--yes`, which skips the interactive gate -and compiles directly: - -```sh -daedalus build --yes -``` - -`--yes` is the non-interactive write path; it works with or without a terminal. -(If you pass both `--preview` and `--yes`, `--preview` wins — an explicit dry-run -request never writes.) - -## Exit codes - -`build` sets a distinct exit code for each outcome, so you can gate on it from a -script or CI: - -| Exit code | Meaning | -|---|---| -| `0` | Success — the canonical definition was compiled to the configured backend. | -| `2` | Usage error — an invalid flag or argument. | -| `3` | Validation error — the canonical definition is invalid; nothing was written. | -| `4` | Compilation or write error (for example, no adapter for the configured backend); nothing was written. | - -## What it produces - -`build` compiles your canonical `.daedalus/` definition into the native format of -the backend recorded in `daedalus.yaml`. The build is **deterministic**: the same -`.daedalus/` always produces the same output, byte for byte. File names are in -**kebab-case**, derived from each item's canonical id, and stay stable from one -build to the next. - -You keep editing the clean, backend-agnostic definition in `.daedalus/`, and -Daedalus generates the native files for you — you never hand-edit the generated -output to keep it in sync. - -### The Claude Code backend → `.claude/` - -When `daedalus.yaml` targets **Claude Code**, `build` writes the `.claude/` -structure that Claude Code reads: - -``` -.claude/ - agents/ - .md # one file per canonical agent - commands/ - .md # one file per workspace prompt (your slash commands) - settings.json # a minimal, Daedalus-managed settings file -``` - -#### Agents → `.claude/agents/.md` - -Each agent in your workspace becomes one Markdown file under `.claude/agents/`. -The file has a small **frontmatter** block followed by the agent's prompt as its -body. The frontmatter carries: - -- `name` — the agent's canonical id; -- `description` — the agent's role; -- `model` — included **only** when the agent defines that parameter. - -For an agent whose id is `reviewer`, role is `Reviews code changes`, and prompt -is its body, `build` generates: - -```md ---- -name: reviewer -description: Reviews code changes -model: opus ---- -You are the code reviewer. Inspect the proposed changes and report any -correctness, security, or style issues, worst-first. -``` - -> Daedalus writes only what your canonical definition actually specifies. In this -> release the agent frontmatter does **not** include `tools` or `color` — they are -> not generated. - -#### Prompts → `.claude/commands/.md` (your slash commands) - -In Claude Code, the files under `.claude/commands/` are its **slash commands**. -Daedalus builds them from the **prompts** in your workspace: **every prompt in -`.daedalus/prompts/`** — both `global` and `shared` prompts — is compiled into one -command file. This is the key correspondence to keep in mind: - -> **A workspace prompt becomes a Claude Code slash command.** Author a prompt -> once in `.daedalus/prompts/`, and after a build you can invoke it as a slash -> command in Claude Code. - -Each command file's name derives from the prompt's id. Its frontmatter carries a -single key, `description`, set to the prompt's **title** — and that key is -**omitted entirely** when the prompt has no title. The body is the **resolved** -prompt: any inclusions the prompt references are already expanded inline, so the -command is self-contained. - -For a prompt with id `summarize` and title `Summarize a document`, `build` -generates: - -```md ---- -description: Summarize a document ---- -Summarize the document below in five bullet points, then give a one-line -takeaway. -``` - -#### Settings → `.claude/settings.json` - -`build` writes a **minimal, honest** `settings.json`. It contains the official -Claude Code `$schema` and a `daedalus` marker noting that these files are managed -by Daedalus — nothing more: - -```json -{ - "$schema": "https://json.schemastore.org/claude-code-settings.json", - "daedalus": { - "managed": true, - "generator": "daedalus" - } -} -``` - -Daedalus deliberately does **not** fabricate `permissions`, `env`, `hooks`, or a -`model` here — it never writes configuration you did not define yourself. You stay -in control of those settings. - -## Re-running build: idempotent and non-destructive - -`build` is safe to run as often as you like. Every run classifies each artifact it -manages as **created**, **updated**, or **unchanged**, and prints a short summary -so you can see exactly what happened — with no surprises and no noise. - -### Re-running with no changes does nothing - -If you run `build` again without touching `.daedalus/`, the output is already -correct, so Daedalus rewrites **nothing**. Every artifact is reported as -`unchanged`, the files stay byte-identical, and there is no churn in your working -tree (or your Git diff): - -``` -Compiled .: - claude-code: 0 created, 0 updated, 5 unchanged (of 5 artifacts) -``` - -This is the **idempotency** guarantee: the same `.daedalus/` always yields the -same `.claude/`, run after run. - -### Changing part of the definition updates only what changed - -When you edit one part of your canonical definition — say, the prompt of a single -agent — the next build updates **only** the artifact(s) affected and leaves the -rest `unchanged`. The summary lists each created artifact with a `+` and each -updated one with a `~`: - -``` -Compiled .: - claude-code: 0 created, 1 updated, 4 unchanged (of 5 artifacts) - ~ agents/reviewer.md -``` - -So a small change to your definition produces a correspondingly small, scoped -change to the generated files — never a wholesale rewrite. - -### Your own files are preserved - -`build` only manages the files it **produces** — its **managed area**. Any file -you place by hand that the build does not generate is **preserved intact**, -whether it sits inside `.claude/` or anywhere else in your repository. `build` -never deletes or overwrites content outside its managed area. This is the safe -default: re-compiling can never destroy your manual work. - -### Orphans are reported, never deleted - -If you remove the canonical source of an artifact that an earlier build generated -— for example, you delete an agent from your workspace — the previously generated -native file becomes an **orphan**: a file the current build no longer produces. -Daedalus **detects** orphans and **reports** them in the summary, marked with a -`?`, but it does **not** delete them — so nothing is ever removed behind your -back: - -``` -Compiled .: - claude-code: 0 created, 0 updated, 4 unchanged (of 4 artifacts) - ? agents/reviewer.md (orphan: no longer produced; left untouched) -``` - -An orphan is harmless — it is simply a leftover file Daedalus no longer manages. -If you no longer want it, **delete it yourself**; Daedalus leaves that decision to -you. - -To review these classifications artifact by artifact — and the exact content -changes — before anything is written, use the -[interactive preview](#previewing-and-confirming-changes). - -## Notes and limitations - -- **Deterministic.** The same workspace state always produces the same output, - byte for byte, with stable, kebab-case file names derived from canonical ids. -- **Idempotent.** Re-running `build` with no canonical changes rewrites nothing — - every artifact is reported `unchanged` and the files stay byte-identical, so - there is no churn in your working tree. -- **Non-destructive.** `build` manages only the files it produces; your own - hand-made files are preserved, and orphaned artifacts (whose canonical source - you removed) are reported but never deleted. -- **Nothing is written without your say-so.** In a terminal, `build` shows an - interactive preview and writes only after you confirm; cancel and nothing - changes. Without a terminal it writes nothing unless you pass `--yes`, and - `--preview` never writes. -- **Validate-first, all-or-nothing.** If the workspace is missing, the canonical - definition is invalid, or the configured backend has no adapter, `build` aborts - and writes nothing — your repository is left untouched. -- **Backend comes from the manifest.** `build` compiles to whatever backend is - recorded in `daedalus.yaml`; set it with `daedalus init --backend` (see - [Choosing a backend](initializing-a-workspace.md#choosing-a-backend)). Claude - Code is the implemented backend in this release. -- **Prompts are your slash commands.** Every prompt in `.daedalus/prompts/` - (global and shared) is compiled into a Claude Code slash command under - `.claude/commands/`. -- **Daedalus generates only what you defined.** The Claude Code settings file is - intentionally minimal — Daedalus never writes `permissions`, `env`, `hooks`, or - a default `model` you did not specify, and agent frontmatter omits `tools` and - `color`. -- **Phase 1: Daedalus configures the AI structure; it does not execute agents.** - After building, you run the agents yourself in your chosen backend (for - example, Claude Code). diff --git a/docs/guide/concepts.md b/docs/guide/concepts.md deleted file mode 100644 index e355864..0000000 --- a/docs/guide/concepts.md +++ /dev/null @@ -1,109 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Concepts - -[← Back to the manual index](../README.md) - -This chapter explains the few ideas you need to use Daedalus with confidence: -what the workspace is, the canonical model it holds, how compilation turns that -model into a backend's native format, and where Phase 1 draws the line. It is -intentionally short — just enough to operate with judgment, not a tour of the -internals. - -## The `.daedalus/` workspace - -Daedalus keeps everything it manages in a single directory at the root of your -repository: **`.daedalus/`**. This is the **canonical, backend-agnostic source -of truth** for your project's AI structure. You create it once with -[`daedalus init`](initializing-a-workspace.md), version it with Git alongside -your code, and edit it like any other set of project files. - -A freshly initialized workspace looks like this: - -``` -.daedalus/ - agents/ # agent definitions (a role plus a prompt) - prompts/ # reusable global and shared prompts - workflows/ # DAG workflows - sdd-default.yaml # the factory SDD workflow, seeded by init - specs/ # specifications / PRD briefs - architecture/ # architecture documents - epics/ # epics (with their tickets nested inside) - tickets/ # tickets - docs/ # derived documentation - .state/ # progress state (tracked in git) - daedalus.yaml # the workspace manifest - init.md # the project guideline -``` - -Everything is plain text — YAML and Markdown — so it diffs cleanly and reads -well in a pull request. Daedalus writes it **deterministically**: the same input -always produces the same bytes, which keeps Git history quiet. - -## The canonical model - -Inside the workspace, Daedalus manages a small set of artifact kinds. Together -they are the **canonical model** — the description of your project's AI -structure, independent of any particular tool. - -| Artifact | What it is | Managed with | -|---|---|---| -| **Agents** | A role plus a prompt — the unit a backend runs. | [`daedalus agent`](managing-agents.md) | -| **Prompts** | Reusable `global` and `shared` text fragments. | [`daedalus prompt`](managing-prompts.md) | -| **Workflows** | Declarative **DAG** pipelines: ordered phases, each with an agent, inputs/outputs, a gate, and dependencies. | [`daedalus workflow`](managing-workflows.md) | -| **Specs** | Briefs and the specifications derived from them. | [`daedalus spec`](managing-specs.md) | -| **Architecture** | Architecture documents, optionally linked to a spec. | [`daedalus architecture`](managing-architecture.md) | -| **Epics & tickets** | The SDD backlog, with traceability links up to specs. | [`daedalus epic`](managing-epics-and-tickets.md) / [`daedalus ticket`](managing-epics-and-tickets.md) | -| **Manifest** | `daedalus.yaml`: project name, schema version, target backend(s), and conventions. | [Configuration](configuration.md) | - -The specs, architecture, epics, and tickets together form the **SDD backlog** — -a traceable chain from a spec down to the tickets that implement it. You can -verify and navigate that chain with [`daedalus trace`](tracing-the-backlog.md). - -## Backend-agnostic compilation - -The canonical model is not what an agent tool reads directly. Daedalus -**compiles** it into the native format of the backend you target. That step is -[`daedalus build`](compiling-to-a-backend.md) (alias `sync`). - -- You **edit** the clean, backend-agnostic definition in `.daedalus/`. -- Daedalus **validates** it, then **generates** the backend's native files for - you. -- For the **Claude Code** backend — the one implemented in this release — - compilation writes the `.claude/` directory: `agents/`, `commands/` (built - from your prompts), and a minimal `settings.json`. - -Because the canonical model is backend-agnostic, the same workspace can target -different backends in the future without rewriting your definitions. You never -hand-edit the generated `.claude/` output — you re-run `build`. - -## Conventions - -Daedalus is built for **teams** that share one workspace, so the way files are -named, laid out, and formatted is written down and **machine-checkable**. -[`daedalus validate`](validating-conventions.md) reports any drift — a stray -name, a misplaced file, a broken backlog link — so problems are caught before -they reach the shared repository. The conventions (kebab-case names, the -canonical layout, ordered YAML and structured Markdown) are recorded in the -manifest's `conventions` block. - -## The Phase 1 boundary - -One boundary matters above all others: - -> **Daedalus manages your AI structure's *definitions*; it does not *execute* -> the agents.** Running the agents stays with your runtime — for example, Claude -> Code. - -In Phase 1, every Daedalus command creates, edits, validates, traces, or -compiles **definitions**. None of them call an agent, contact a model, or run a -workflow. This is why the management commands say, in their help, that Daedalus -"manages the definition only; it does not run the analyst/architect/planner -agent." After you `build`, you run the agents yourself in your chosen backend. - -## Where to go next - -- [Core workflow](core-workflow.md) — the everyday loop of edit → validate → - build. -- [Command reference](command-reference.md) — every core command with its flags - and exit codes. diff --git a/docs/guide/configuration.md b/docs/guide/configuration.md deleted file mode 100644 index 97d722f..0000000 --- a/docs/guide/configuration.md +++ /dev/null @@ -1,167 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Configuration - -[← Back to the manual index](../README.md) - -## The workspace manifest (`daedalus.yaml`) - -Every Daedalus workspace has a manifest at `.daedalus/daedalus.yaml`. It is the -central configuration file for your workspace: a small, human-readable YAML file -that records your project's name, the workspace schema version, the target agent -backend(s), and the project conventions. Later operations (agent management and -compilation to a backend) read it. - -`daedalus init` generates the manifest for you. It is written with **ordered, -stable keys** so its diffs stay clean in Git, and it is **deterministic** — the -same project always produces the same file, byte for byte. You can edit it by -hand and version it alongside your code. - -### What it looks like - -For a project in a directory named `my-app`, `init` generates: - -```yaml -# Daedalus workspace manifest. -# Generated by `daedalus init`. Keys are ordered and stable for clean diffs. -name: my-app -version: "1" -backends: - - claude-code -conventions: - naming: kebab-case - markdown: hierarchical-headings - yaml: ordered-deterministic -``` - -### The keys - -| Key | Meaning | -|---|---| -| `name` | The project name. Derived automatically from the name of the target directory (the folder you initialize). | -| `version` | The Daedalus **workspace schema** version — the version of the `.daedalus/` layout and manifest format. It is currently `"1"`. This is not the version of the Daedalus binary; the two evolve independently. | -| `backends` | The list of target agent backend(s) your AI structure compiles to. A fresh manifest contains a single default entry, `claude-code`. Set it at init time with `daedalus init --backend` — see [Choosing a backend](initializing-a-workspace.md#choosing-a-backend). | -| `conventions` | The project conventions, as a nested mapping. See below. | - -The `conventions` block records the conventions Daedalus follows for your -project. It mirrors the conventions described in your project's `init.md`: - -| Convention | Default value | Meaning | -|---|---|---| -| `naming` | `kebab-case` | Naming style for files and ids (epics, tickets, agents, workflows). | -| `markdown` | `hierarchical-headings` | Markdown is written with hierarchical headings. | -| `yaml` | `ordered-deterministic` | YAML is written with stable, ordered keys for deterministic output and clean diffs. | - -### Editing the manifest - -The manifest is yours to edit. Open `.daedalus/daedalus.yaml` to review or adjust -the values, then commit it with the rest of your project. Because `init` is -non-destructive, once the manifest exists with your content, re-running `init` -never overwrites it — see -[Re-running `init`: detect and upgrade](initializing-a-workspace.md#re-running-init-detect-and-upgrade). - -> Note on quoting: `version` is written as a quoted string (`"1"`) so it is -> always read as text, never as a number. The other generated values are plain -> scalars. If a value could be misread by a YAML parser, Daedalus quotes it -> automatically. - -## Logging - -By default Daedalus is **quiet**: each command prints human-readable output, and -the logger only surfaces **warnings and errors** — as a compact, readable console -line, not JSON. Detailed telemetry is one environment variable away. Logs are -written to **standard error**, so they never interfere with the interface, which -uses standard output. - -### Levels and format - -| Variable | Values | Default | Purpose | -| --------------------- | -------------------------------- | ------- | --------------------------------------------------------- | -| `DAEDALUS_LOG_LEVEL` | `debug`, `info`, `warn`, `error` | `warn` | Minimum level; `info`/`debug` are opt-in. | -| `DAEDALUS_LOG_FORMAT` | `text`, `json` | `text` | Rendering: human console (`text`) or structured (`json`). | - -Unknown or empty values fall back to the defaults (`warn`, `text`). - -```sh -# Quiet by default: only warnings and errors, as readable console lines. -./daedalus - -# Detailed, human-readable telemetry -DAEDALUS_LOG_LEVEL=debug ./daedalus - -# Structured JSON for tooling/telemetry (at any level) -DAEDALUS_LOG_FORMAT=json DAEDALUS_LOG_LEVEL=info ./daedalus -``` - -### What the logs look like - -The default **text** format is a single, human-friendly line per record — the -level, the message, then any contextual `key=value` fields (colored on a -terminal): - -```text -warning: definition rejected definition=agents/reviewer.md result=invalid reason=missing required field: name -``` - -The **json** format emits one structured object per record — a timestamp, level, -message, and the same fields — meant for machine parsing and telemetry: - -```json -{"time":"2026-06-23T10:00:00Z","level":"INFO","msg":"daedalus starting","version":"0.1.0-dev","interactive":true} -``` - -### Capturing logs - -Because logs go to standard error, you can redirect them independently of normal -output: - -```sh -DAEDALUS_LOG_FORMAT=json ./daedalus 2> daedalus.log -``` - -### Privacy - -Daedalus does not log secrets, tokens, credentials, or personal data. Log -records contain identifiers and the decisions taken, never the sensitive values -behind them. - -### Reading operation logs to troubleshoot - -`init`, `build` (alias `sync`), and `daedalus validate` emit events at their -**decision points**, not just at the start and end. By default you see the -warnings and errors among them as readable lines; for the full trace (including -the `info`-level started/accepted events) and machine-parseable records, run with -`DAEDALUS_LOG_LEVEL=info DAEDALUS_LOG_FORMAT=json`. When an operation does not do -what you expected, the log shows what Daedalus decided and why — so you rarely -have to guess. Every path to a definition is recorded **relative to the -workspace**, which makes the offending file easy to locate. - -What to look for: - -- **`init`** records whether a workspace already existed, whether it created or - upgraded one, and what it seeded — useful when a re-run does less than you - expected because the workspace was already present. -- **`build`/`sync`** records that the workspace was located, the definition was - validated, the backend was compiled, and how many files it created, updated, - or left unchanged. The created/updated/unchanged counts make an idempotent - no-op visible: a re-build with everything unchanged is working as intended. -- When a build **aborts on an invalid definition**, look for a - `definition rejected` event. It is logged at `WARN` with `result=invalid` (or - `malformed`), the `reason` it was refused, and the `definition` path so you - know which file to fix. Accepted definitions log the matching - `definition accepted` event at `INFO`. -- When `daedalus validate` reports problems, each finding is a - `convention violated` event — `ERROR` for hard violations, `WARN` for - advisories — naming the `family`, the `convention`, the `definition` location, - and the `reason`. These mirror the report printed to the interface and let you - scan or filter the violations programmatically. - -For example, a rejected definition during a build, in `json` format, looks like: - -```json -{"time":"2026-06-23T10:00:00Z","level":"WARN","msg":"definition rejected","operation":"build","result":"invalid","definition":"agents/reviewer.md","reason":"missing required field: name"} -``` - -To capture only these events for inspection, run with `DAEDALUS_LOG_FORMAT=json`, -redirect standard error as shown above, and filter the resulting file for the -message you need (for example, `definition rejected` or `convention violated`). diff --git a/docs/guide/core-workflow.md b/docs/guide/core-workflow.md deleted file mode 100644 index d581646..0000000 --- a/docs/guide/core-workflow.md +++ /dev/null @@ -1,85 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Core workflow - -[← Back to the manual index](../README.md) - -Day to day, using Daedalus is a short, repeatable loop. You **edit** your -canonical definitions, **validate** them, and **build** them into your backend's -native format. This chapter describes that loop and when to reach for each -command. For the full flags and exit codes of each command, see the -[Command reference](command-reference.md). - -## The loop - -``` -edit definitions → daedalus validate → daedalus build - (in .daedalus/) (catch drift early) (compile to .claude/) - ▲ │ - └───────────────── iterate ─────────────────┘ -``` - -1. **Edit definitions.** Add or change agents, prompts, workflows, specs, - architecture, epics, and tickets in `.daedalus/`. Use the matching - `daedalus` commands (for example [`daedalus agent`](managing-agents.md), - [`daedalus prompt`](managing-prompts.md), - [`daedalus workflow`](managing-workflows.md)) or edit the files by hand — - they are plain YAML and Markdown. -2. **Validate.** Run [`daedalus validate`](validating-conventions.md) to check - the workspace along two axes — the team **conventions** and the - **definitions** themselves — before the changes reach your shared - repository. It is read-only and never auto-fixes. -3. **Build.** Run [`daedalus build`](compiling-to-a-backend.md) (alias `sync`) - to compile the canonical definition into your backend's native format - (`.claude/` for Claude Code). `build` validates first, then shows you a - preview and asks you to confirm before writing. - -Repeat as your project grows. Because every step is deterministic and -non-destructive, the loop is safe to run as often as you like. - -## When to use each command - -| You want to… | Command | -|---|---| -| Create the workspace in a repository | [`daedalus init`](initializing-a-workspace.md) | -| Add, clone, edit, or import an agent | [`daedalus agent`](managing-agents.md) | -| Author reusable prompts | [`daedalus prompt`](managing-prompts.md) | -| Define or edit a DAG workflow | [`daedalus workflow`](managing-workflows.md) | -| Build the SDD backlog | [`daedalus spec`](managing-specs.md), [`daedalus architecture`](managing-architecture.md), [`daedalus epic`](managing-epics-and-tickets.md), [`daedalus ticket`](managing-epics-and-tickets.md) | -| Check the workspace follows the conventions | [`daedalus validate`](validating-conventions.md) | -| Verify or navigate the backlog's traceability | [`daedalus trace`](tracing-the-backlog.md) | -| Compile the definition to your backend | [`daedalus build`](compiling-to-a-backend.md) | -| Browse the workspace interactively | [The interface](navigating-the-tui.md) (`daedalus` with no subcommand) | - -## The build gate - -`build` never writes silently — this is the heart of the safe workflow: - -- **In an interactive terminal**, `build` shows a preview of every change and - asks you to confirm. Press `y`/`enter` to write, or `n`/`esc` to cancel - (nothing is written). -- **`daedalus build --preview`** shows the diff and **never writes**, in a - terminal or out of one. Use it to inspect a plan. -- **`daedalus build --yes`** writes **without** the interactive gate. Use it in - scripts and CI. -- **Without a terminal and without `--yes`**, `build` prints the diff and - **writes nothing**, telling you to pass `--yes` or run in a terminal. - -See [Compiling to a backend](compiling-to-a-backend.md) for the full preview UI -and the idempotent, non-destructive guarantees. - -## Gating in CI - -Both `validate` and `build` set exit codes you can gate on: - -- `daedalus validate` exits `0` (conforms), `1` (errors), or `2` (usage). Run - it in CI to reject a workspace that drifts from the conventions or has an - invalid definition. -- `daedalus build --yes` writes the backend output non-interactively and exits - `0` on success. - -## The Phase 1 boundary - -This loop **configures** your AI structure; it does not **run** it. After a -successful `build`, you execute the agents yourself in your chosen backend (for -example, Claude Code). See [Concepts](concepts.md#the-phase-1-boundary). diff --git a/docs/guide/examples.md b/docs/guide/examples.md deleted file mode 100644 index 640ee9d..0000000 --- a/docs/guide/examples.md +++ /dev/null @@ -1,203 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Examples - -[← Back to the manual index](../README.md) - -Realistic, end-to-end scenarios that string the commands together. Every command -and output below matches Daedalus's actual behavior. For the full flags and exit -codes of each command, see the [Command reference](command-reference.md). - -## Start a new project - -Move into the repository you want to manage and create the workspace: - -```sh -cd /path/to/your-repo -daedalus init -``` - -``` -Created Daedalus workspace at .daedalus from scratch. -Seeded factory workflow "sdd-default" at .daedalus/workflows/sdd-default.yaml. -``` - -You now have a `.daedalus/` workspace with the canonical layout, a manifest, the -project `init.md`, and the seeded `sdd-default` workflow. Commit it with your -project. - -## Add an agent - -List the built-in catalog, then materialize the one you want: - -```sh -daedalus agent list -``` - -``` -Built-in agents (5): - analyst Turns a brief into a spec/PRD. - architect Defines the architecture from the spec. - documenter Produces derived documentation. - planner Derives epics and tickets from spec and architecture. - validator Verifies artifacts and implementation against gates and criteria. -``` - -```sh -daedalus agent add analyst -``` - -``` -Materialized agent "analyst" at .daedalus/agents/analyst (created 2 files). -``` - -The agent's editable source of truth (`agent.yaml` and `prompt.md`) now lives -under `.daedalus/agents/analyst/`. See [Managing agents](managing-agents.md) for -cloning, editing, and importing. - -## Add a prompt - -Author a reusable prompt — for Claude Code, a prompt becomes a slash command -after you build: - -```sh -daedalus prompt create summarize --kind global --title "Summarize a document" -``` - -```sh -daedalus prompt list -``` - -See [Managing prompts](managing-prompts.md) for editing, composition, and -rendering. - -## Define a workflow - -A fresh workspace already has the seeded `sdd-default` workflow: - -```sh -daedalus workflow list -``` - -``` -sdd-default 6 phases -``` - -Create your own and add a phase to it: - -```sh -daedalus workflow create release-pipeline -daedalus workflow add-phase release-pipeline --id draft --agent analyst --gate review -``` - -See [Managing workflows](managing-workflows.md) for the phase schema, editing, -and the DAG validation. - -## Validate the workspace - -Before compiling — or in CI — check that the workspace follows the conventions -and that the definitions are well-formed: - -```sh -daedalus validate -``` - -``` -Conventions: workspace conforms (no violations). -Definitions: all agents, workflows and manifest are valid. -``` - -Exit `0`. A clean run is your signal that the workspace is ready to compile. If -`validate` reports a finding, see [Troubleshooting](troubleshooting.md). - -## Compile to your backend - -Preview what the build would write, then write it: - -```sh -daedalus build --preview -``` - -``` -Preview of compiling . (no files written): - claude-code: 1 new, 0 modified, 0 unchanged (of 1 artifact) - [new] .claude/settings.json - + { - + "$schema": "https://json.schemastore.org/claude-code-settings.json", - + "daedalus": { - + "managed": true, - + "generator": "daedalus" - + } - + } -``` - -In an interactive terminal, run `daedalus build` and confirm at the gate. From a -script or CI, pass `--yes`: - -```sh -daedalus build --yes -``` - -``` -Compiled .: - claude-code: 1 created, 0 updated, 0 unchanged (of 1 artifact) - + .claude/settings.json -``` - -As you add agents and prompts, the build produces more artifacts (one -`.claude/agents/.md` per agent, one `.claude/commands/.md` per prompt). -A re-build with nothing changed is an idempotent no-op: - -```sh -daedalus build --yes -``` - -``` -Compiled .: - claude-code: 0 created, 0 updated, 1 unchanged (of 1 artifact) -``` - -See [Compiling to a backend](compiling-to-a-backend.md) for the interactive -preview and the non-destructive guarantees. - -## Read a validation report - -When `validate` finds a problem, it prints one finding per line. For example, a -manifest whose `backends` lists an unsupported value: - -```sh -daedalus validate -``` - -``` -Conventions: workspace conforms (no violations). -Definitions: 1 error and 0 warnings: - - [error] .daedalus/daedalus.yaml: backends[nonexistent-backend]: schema: observed unsupported backend "nonexistent-backend"; expected one of the supported backends: claude-code -``` - -Exit `1`. Read the finding left to right: - -- **`[error]`** — the severity (errors fail the check; warnings do not). -- **`.daedalus/daedalus.yaml`** — the file at fault. -- **`backends[nonexistent-backend]`** — the exact spot inside it. -- **`schema`** — the rule that was broken. -- **observed vs. expected** — what was found and what was expected. - -Fix the manifest to a supported backend (`claude-code`) and run `daedalus -validate` again to confirm the workspace conforms. See -[Troubleshooting](troubleshooting.md) for more error patterns. - -## Verify the backlog's traceability - -Once you have specs, epics, and tickets, confirm the chain is consistent: - -```sh -daedalus trace verify -``` - -``` -Traceability chain is consistent (no inconsistencies). -``` - -Navigate it from any artifact with `daedalus trace show `. See -[Tracing the backlog](tracing-the-backlog.md). diff --git a/docs/guide/initializing-a-workspace.md b/docs/guide/initializing-a-workspace.md deleted file mode 100644 index f0e0bb0..0000000 --- a/docs/guide/initializing-a-workspace.md +++ /dev/null @@ -1,253 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Initializing a workspace - -[← Back to the manual index](../README.md) - -`daedalus init` creates the canonical `.daedalus/` workspace inside your -repository. This workspace is the single, backend-agnostic source of truth for -your project's AI structure (agents, prompts, workflows, and the SDD backlog). - -## Usage - -From the root of your repository: - -```sh -daedalus init -``` - -When the workspace does not exist yet, you will see a confirmation that it was -created from scratch, followed by a line reporting the factory workflow that -`init` seeds into it: - -``` -Created Daedalus workspace at .daedalus from scratch. -Seeded factory workflow "sdd-default" at .daedalus/workflows/sdd-default.yaml. -``` - -See [The default SDD workflow](managing-workflows.md#the-default-sdd-workflow) -for what `sdd-default` contains. - -To target a different directory, use `--path`: - -```sh -daedalus init --path ./my-repo -``` - -See all options with: - -```sh -daedalus init --help -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Directory to initialize. Defaults to the current directory. | -| `--backend ` | Target agent backend(s) to record in the manifest, comma-separated. Defaults to `claude-code`. See [Choosing a backend](#choosing-a-backend). | -| `--preview` | Dry run: show what would be created or added without writing anything. | -| `--help` | Show all available options. | - -## What it creates - -``` -.daedalus/ - daedalus.yaml # project manifest - init.md # project guideline - agents/ # agent definitions - prompts/ # shared prompts - workflows/ # DAG workflows - sdd-default.yaml # the factory SDD workflow, seeded by init - specs/ # specifications / PRD - architecture/ # architecture documents - epics/ # epics - tickets/ # tickets - docs/ # derived documentation - .state/ # progress state (tracked in git) -``` - -### The seeded factory workflow - -Besides the directory structure and the two root artifacts, `init` seeds one -ready-to-use workflow — `sdd-default.yaml` — into `workflows/`, so you start with -the default SDD pipeline instead of an empty directory. Like everything `init` -produces it is **non-destructive**: if you have already created or edited an -`sdd-default.yaml`, `init` leaves your file untouched and reports it as already -present. See [The default SDD workflow](managing-workflows.md#the-default-sdd-workflow) -for its phases and what each one does. - -## The root artifacts: manifest & project `init.md` - -Two of the files `init` creates are the workspace's **root artifacts**, and -Daedalus generates real, ready-to-use content for both. Like everything `init` -produces, they are **deterministic** (the same project always yields the same -file, byte for byte) and they are **non-destructive**: if either file already -exists with your own content, `init` leaves it untouched (see -[Re-running `init`: detect and upgrade](#re-running-init-detect-and-upgrade)). - -### `daedalus.yaml` — the manifest - -`.daedalus/daedalus.yaml` is the workspace **manifest**: the central -configuration file recording your project's name, the workspace schema version, -the target backend(s), and the project conventions. For a project in a directory -named `my-app`, `init` generates: - -```yaml -# Daedalus workspace manifest. -# Generated by `daedalus init`. Keys are ordered and stable for clean diffs. -name: my-app -version: "1" -backends: - - claude-code -conventions: - naming: kebab-case - markdown: hierarchical-headings - yaml: ordered-deterministic -``` - -The `name` is derived automatically from the name of the directory you -initialize. The `backends` list records the target backend(s) you select with -`--backend` (see [Choosing a backend](#choosing-a-backend)). For a full -description of every key and how to edit the manifest, see -[The workspace manifest](configuration.md#the-workspace-manifest-daedalusyaml). - -### `init.md` — the project guideline - -`.daedalus/init.md` is the **master guideline** for your project — the entry -point for anyone, or any agent, working on it. It is the first thing they read, -and it defines the project's vision, conventions, and structure so work can -start without ambiguity. `init` generates a base version, instantiated for your -project, with these sections: - -1. **Vision & purpose** — a placeholder for you to describe what your project is, - the problem it solves, and who it is for. -2. **Workspace structure (`.daedalus/`)** — a map of the `.daedalus/` layout. -3. **Conventions** — the project's naming, Markdown, YAML, Git, idempotency, and - traceability conventions. -4. **References** — pointers to the manifest and the other key locations in the - workspace. - -Open it and replace the placeholder **Vision & purpose** section with your -project's specifics; the rest is ready to use. - -## Choosing a backend - -A **backend** is the agent tool your AI structure will compile to. Use the -`--backend` flag to record which backend(s) the workspace targets; the selection -is saved to the `backends` list in the manifest (see -[The workspace manifest](configuration.md#the-workspace-manifest-daedalusyaml)). - -If you do not pass `--backend`, `init` records the default backend, -`claude-code`: - -```sh -daedalus init # records: claude-code (the default) -daedalus init --backend claude-code # same result, stated explicitly -``` - -```yaml -backends: - - claude-code -``` - -The MVP supports exactly one backend, **`claude-code`**, which is also the -default. The flag accepts a comma-separated list so the manifest is ready for -multiple backends in the future. Surrounding whitespace is trimmed and repeated -entries are collapsed, so `--backend claude-code, claude-code` records a single -`claude-code` entry. - -### Unsupported backends - -If you request a backend that is not supported, `init` rejects the run with a -clear error, exits with status code `2`, and **writes nothing** — no `.daedalus/` -directory is created and no invalid value is recorded: - -```sh -daedalus init --backend foo -``` - -``` -daedalus: unsupported backend: "foo" (supported: claude-code) -``` - -Re-run the command with a supported backend (or no `--backend` flag) to proceed. - -## Safe to run on existing repositories - -`init` is **non-destructive**: it never modifies or deletes anything outside the -`.daedalus/` directory it creates, so it is safe to run in a repository that -already contains your code. It is also **deterministic** — the same repository -always produces the same structure, which keeps Git diffs clean. - -## Re-running `init`: detect and upgrade - -`init` is safe to run as many times as you like. When a `.daedalus/` workspace -already exists, Daedalus detects it and performs a **non-destructive upgrade** -instead of creating a new one. It never overwrites or deletes files and folders -that contain your own content — it only **adds whatever is missing** so the -workspace structure stays complete. - -There are two possible outcomes: - -**The workspace is already complete.** Nothing needs to change, so Daedalus -leaves every file untouched and reports that the workspace is up to date. The -factory workflow is reported as already present, confirming your copy was left -intact: - -``` -Existing Daedalus workspace at .daedalus is already complete — nothing to update. -Factory workflow "sdd-default" already present at .daedalus/workflows/sdd-default.yaml — left intact. -``` - -**The workspace is missing some pieces.** Daedalus first prints a preview of -exactly what it will add, then completes the structure and reports how many -directories and files it created: - -``` -Preview of changes to the Daedalus workspace at .daedalus: - + docs/ (directory) - + init.md (file) -Upgraded existing Daedalus workspace at .daedalus (added 1 directories, 1 files). -``` - -Because the upgrade only fills in what is absent, any edits you have made inside -`.daedalus/` — for example, content you added to `init.md` or files you created -under `agents/` — are always preserved. - -## Previewing changes without writing - -Use the `--preview` flag to perform a **dry run**. Daedalus inspects the target -directory and prints the same preview of what it would create or add, but -**writes nothing** to disk: - -```sh -daedalus init --path ./my-repo --preview -``` - -``` -Preview of changes to the Daedalus workspace at ./my-repo: - + docs/ (directory) - + init.md (file) -``` - -When the preview is for a brand-new workspace, the factory workflow appears in -the list too, marked as a factory workflow — but, like every preview, nothing is -written: - -``` -Preview of changes to the Daedalus workspace at .daedalus: - + agents/ (directory) - + prompts/ (directory) - + workflows/ (directory) - ... - + daedalus.yaml (file) - + init.md (file) - + .daedalus/workflows/sdd-default.yaml (factory workflow) -``` - -The factory-workflow line is shown only when it would actually be written: if an -`sdd-default.yaml` already exists, the preview does not list it as a change. - -This lets you see what an `init` run would do before committing to it. Run the -command again without `--preview` to apply the changes. diff --git a/docs/guide/managing-agents.md b/docs/guide/managing-agents.md deleted file mode 100644 index e3bfc0e..0000000 --- a/docs/guide/managing-agents.md +++ /dev/null @@ -1,516 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Managing agents - -[← Back to the manual index](../README.md) - -Daedalus ships with a **built-in agent catalog**: a small, fixed set of canonical -agents that cover the Spec-Driven Development (SDD) pipeline out of the box. The -catalog lets you start from proven roles instead of writing agents from scratch. -You can **list** the agents the catalog offers and **add** (materialize) any of -them into your workspace as an editable definition. - -The catalog is embedded in the Daedalus binary, so it works offline and needs no -external files. The agents are the units (a role plus a prompt) that, in later -phases, compile to the native format of your backend. - -## The built-in agents - -The catalog provides five canonical agents, one for each stage of the SDD -pipeline: - -| Id | Role | -|---|---| -| `analyst` | Turns a brief into a spec/PRD. | -| `architect` | Defines the architecture from the spec. | -| `planner` | Derives epics and tickets from spec and architecture. | -| `validator` | Verifies artifacts and implementation against gates and criteria. | -| `documenter` | Produces derived documentation. | - -## Listing the catalog - -Use `daedalus agent list` to see every built-in agent with its id and role: - -```sh -daedalus agent list -``` - -The agents are listed in id order: - -``` -Built-in agents (5): - analyst Turns a brief into a spec/PRD. - architect Defines the architecture from the spec. - documenter Produces derived documentation. - planner Derives epics and tickets from spec and architecture. - validator Verifies artifacts and implementation against gates and criteria. -``` - -## Adding an agent to your workspace - -Use `daedalus agent add ` to materialize a catalog agent into your -workspace. The id may appear before or after the flags, so both -`daedalus agent add analyst --path ./my-repo` and -`daedalus agent add --path ./my-repo analyst` work. - -```sh -daedalus agent add analyst -``` - -On success, Daedalus reports the directory and how many files it created: - -``` -Materialized agent "analyst" at .daedalus/agents/analyst (created 2 files). -``` - -See all options with: - -```sh -daedalus agent add --help -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/agents/` the agent is added to. Defaults to the current directory. | -| `--preview` | Dry run: show the files that would be created without writing anything. | -| `--help` | Show all available options. | - -### It will not overwrite your work - -Adding an agent is **non-destructive**. If an agent with the same id already -exists in the workspace, Daedalus leaves the existing files — including any -manual edits — untouched and tells you nothing was overwritten: - -``` -Agent "analyst" already exists at .daedalus/agents/analyst — not overwritten (skipped 2 files). -``` - -If only some of the agent's files are present (for example, you deleted one), -Daedalus fills in the missing file and preserves the rest, reporting both: - -``` -Agent "analyst" partially materialized at .daedalus/agents/analyst (created 1, skipped 1 existing file). -``` - -### Previewing without writing - -Use the `--preview` flag to perform a **dry run**. Daedalus prints the files it -would create but **writes nothing** to disk: - -```sh -daedalus agent add planner --preview -``` - -``` -Preview of materializing agent "planner" into .daedalus/agents/planner: - + planner/agent.yaml (file) - + planner/prompt.md (file) -``` - -Run the command again without `--preview` to apply the changes. - -### Unknown agents - -If you ask for an id that is not in the catalog, Daedalus rejects the run, exits -with status code `2`, and writes nothing. It also points you to `agent list`: - -```sh -daedalus agent add bogus -``` - -``` -daedalus: agent not found in catalog: "bogus" -run 'daedalus agent list' to see the available agents -``` - -## What gets created on disk - -Each agent is materialized into its own directory under your workspace's -`.daedalus/agents/`, as two files: - -``` -.daedalus/ - agents/ - analyst/ - agent.yaml # canonical agent definition (editable source of truth) - prompt.md # the agent's prompt, as Markdown -``` - -`agent.yaml` is the **canonical definition**: a small, diff-friendly metadata -file. The prompt itself lives alongside it in `prompt.md`, so you can edit it as -Markdown without touching the definition. A materialized `analyst/agent.yaml` -looks like this: - -```yaml -# Daedalus canonical agent definition. -# Managed by Daedalus. Keys are ordered and stable for clean diffs. -# This file is the editable source of truth; the prompt lives in prompt.md. -id: analyst -version: "1" -role: Turns a brief into a spec/PRD. -prompt: prompt.md -parameters: - model: default -``` - -These files are your **editable source of truth**: change the role, the prompt, -or the parameters as your project needs. The output is **deterministic** — adding -the same agent into a clean workspace always produces the same files, byte for -byte, which keeps Git diffs clean. - -## Cloning an agent - -`daedalus agent add` materializes a catalog agent under its own id. When you want -to start from a catalog agent but keep your own customized copy under a different -name, use `daedalus agent clone `. The clone is an -**independent** copy: editing it never changes the original built-in agent. - -```sh -daedalus agent clone analyst analyst-custom -``` - -The destination id must be `kebab-case`. On success, Daedalus reports the new -directory and how many files it created: - -``` -Materialized agent "analyst-custom" at .daedalus/agents/analyst-custom (created 2 files). -``` - -The ids may appear before or after the flags. See all options with: - -```sh -daedalus agent clone --help -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/agents/` the clone is written to. Defaults to the current directory. | -| `--preview` | Dry run: show the files that would be created without writing anything. | -| `--help` | Show all available options. | - -### It will not overwrite an existing clone - -Cloning is **non-destructive**. If the destination id already exists in the -workspace, Daedalus leaves the existing files untouched and tells you nothing was -overwritten: - -``` -Agent "analyst-custom" already exists at .daedalus/agents/analyst-custom — not overwritten (skipped 2 files). -``` - -### Previewing a clone without writing - -Use `--preview` to perform a **dry run** that prints the files it would create -but **writes nothing**: - -```sh -daedalus agent clone analyst analyst-custom --preview -``` - -``` -Preview of materializing agent "analyst-custom" into .daedalus/agents/analyst-custom: - + analyst-custom/agent.yaml (file) - + analyst-custom/prompt.md (file) -``` - -### Unknown source or invalid destination - -If the source id is not in the catalog, Daedalus rejects the run, exits with -status code `2`, and points you to `agent list`: - -```sh -daedalus agent clone bogus my-agent -``` - -``` -daedalus: agent not found in catalog: "bogus" -run 'daedalus agent list' to see the available agents -``` - -If the destination id is not valid `kebab-case`, the run is rejected with status -code `2` and writes nothing: - -```sh -daedalus agent clone analyst Bad_Id -``` - -``` -daedalus: destination agent id "Bad_Id" is not valid kebab-case -``` - -## Editing an agent - -Once an agent exists in your workspace — whether you added it or cloned it — you -can change its role, prompt, and parameters with `daedalus agent edit `. -Edits are written directly to the agent's `agent.yaml` and `prompt.md`. You can, -of course, also edit those files by hand; this command is the scriptable -alternative. - -```sh -daedalus agent edit analyst-custom --role "Drafts product specs for the mobile team" -``` - -On success, Daedalus confirms the change: - -``` -Edited agent "analyst-custom" at .daedalus/agents/analyst-custom. -``` - -The id may appear before or after the flags. See all options with: - -```sh -daedalus agent edit --help -``` - -### Options - -At least one edit flag is required. - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/agents/` holds the agent. Defaults to the current directory. | -| `--role ` | Set the agent's role/description. | -| `--prompt ` | Set the agent's prompt inline. | -| `--prompt-file ` | Set the agent's prompt from a file. Takes precedence over `--prompt` if both are given. | -| `--set-param key=value` | Add or update a parameter. **Repeatable.** | -| `--remove-param key` | Remove a parameter by key. **Repeatable.** | -| `--help` | Show all available options. | - -You can combine several flags in one run. For example, set the prompt from a -file, add a parameter, and drop another: - -```sh -daedalus agent edit analyst-custom \ - --prompt-file ./prompts/analyst.md \ - --set-param temperature=0.2 \ - --remove-param model -``` - -Parameters set through the CLI are stored as **strings** — Daedalus does not -infer number or boolean types from the value you type. (Typed parameters that -came from the built-in catalog keep their type until you edit them via the CLI.) - -### Edits are validated before anything is written - -An edit is checked against the [canonical schema](#agent-validation) **before** it -touches disk, and the write is **atomic**. If the result would be invalid — for -example, an empty role — Daedalus rejects the edit with status code `2`, lists -every problem it found, and leaves your existing definition completely intact -(never half-written): - -```sh -daedalus agent edit analyst-custom --role "" -``` - -``` -daedalus: agent "analyst-custom" is invalid; the edit was not applied: - - role: observed empty; expected a non-empty role/description -``` - -### Editing requires at least one change - -Running `edit` with no edit flag is treated as a usage error (status code `2`), -not as a silent no-op: - -```sh -daedalus agent edit analyst-custom -``` - -``` -daedalus: agent edit requires at least one edit flag (--role, --prompt, --prompt-file, --set-param, --remove-param) -``` - -### Editing an agent that does not exist - -`edit` only works on an agent that already lives in your workspace. If the id is -not there, Daedalus rejects the run with status code `2` and tells you to create -it first: - -```sh -daedalus agent edit ghost --role "anything" -``` - -``` -daedalus: agent not found in catalog: "ghost" -the agent must already exist in the workspace; clone or add it first -``` - -## Importing agents - -If your project already has agents defined outside Daedalus — for example a -Claude Code `.claude/agents/` directory — you do not have to rewrite them by -hand. `daedalus agent import ` reads those definitions and converts them -into the workspace's canonical format under `.daedalus/agents/`. - -The source may be a single **file** or a **directory**, and may appear before or -after the flags: - -```sh -daedalus agent import .claude/agents/reviewer.md -``` - -On success, Daedalus reports each imported agent and a summary: - -``` - + reviewer imported to .daedalus/agents/reviewer (created 2 files). -Import summary: 1 imported, 0 already existed, 0 failed. -``` - -See all options with: - -```sh -daedalus agent import --help -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/agents/` receives the import. Defaults to the current directory. | -| `--preview` | Dry run: show what would be imported without writing anything. | -| `--help` | Show all available options. | - -### What gets recognized and how it is converted - -Import understands two source formats: - -- **Claude Code agents** (`.claude/agents/*.md`): a Markdown file with a YAML - frontmatter block followed by the prompt body. -- **Canonical definitions**: an agent already in Daedalus's own format. - -When importing a Claude Code agent, Daedalus maps its fields to the canonical -definition like this: - -| Claude Code field | Becomes | Notes | -|---|---|---| -| `name` | the agent **id** | Normalized to `kebab-case`. If `name` is missing, the id is derived from the file name. | -| `description` | the **role** | | -| the Markdown body | the **prompt** | Everything after the closing `---`. | -| `model` | a `model` **parameter** | Only when present. | -| `tools` | *dropped* | Backend-specific to Claude Code; not part of the canonical model in Phase 1. | -| `color` | *dropped* | A Claude Code UI affordance with no canonical meaning. | - -`tools` and `color` are intentionally **not** carried over: they are specific to -Claude Code and have no backend-agnostic meaning yet. When Daedalus later -compiles your canonical agents back to `.claude/`, those concerns are resolved at -that point. - -### Importing a whole directory - -Point `import` at a directory and Daedalus imports every valid agent it finds, -reporting each one and a final summary: - -```sh -daedalus agent import .claude/agents -``` - -``` - + reviewer imported to .daedalus/agents/reviewer (created 2 files). - + planner imported to .daedalus/agents/planner (created 2 files). -Import summary: 2 imported, 0 already existed, 0 failed. -``` - -If one source in the directory is invalid, it is reported and skipped — it does -**not** abort the valid ones (see [Invalid sources](#invalid-sources)). - -### Previewing without writing - -Use `--preview` to perform a **dry run** that lists what would be imported but -**writes nothing**: - -```sh -daedalus agent import .claude/agents --preview -``` - -``` -Preview of importing 2 agent(s): - + reviewer -> .daedalus/agents/reviewer - + planner -> .daedalus/agents/planner -``` - -If nothing in the source is importable, the preview says so: - -``` -Preview: no importable agents found. -``` - -### It will not overwrite existing agents - -Import is **non-destructive**. If an agent id already exists in the workspace, -Daedalus leaves the existing files untouched and marks it as skipped: - -``` - = reviewer already exists at .daedalus/agents/reviewer — not overwritten (skipped 2 files). -Import summary: 0 imported, 1 already existed, 0 failed. -``` - -### Invalid sources - -A source that cannot be converted — for example, one whose role ends up empty — -fails the [canonical schema](#agent-validation) and is reported with the -offending file and every problem it found, prefixed with `!`. Other valid agents -are still imported, but the run exits with status code `2` so you notice the -failure: - -``` - ! .claude/agents/broken.md: agent "broken" is invalid (1 issue): - - role: observed empty; expected a non-empty role/description -Import summary: 0 imported, 0 already existed, 1 failed. -``` - -If the source **path** itself cannot be read at all (for example, it does not -exist), the run fails with status code `1` and writes nothing. - -## Agent validation - -Every agent definition Daedalus writes must satisfy a single **canonical -schema**. This schema is the quality gate behind all four operations above — it -runs on `add`, `clone`, `edit`, and `import` — so a definition is only ever -written when it is valid. The check looks at the definition itself; it never -executes the agent or contacts a backend. - -### What the schema requires - -| Field | Required | Rule | -|---|---|---| -| `id` | Yes | Non-empty, `kebab-case` (lowercase letters/digits in dash-separated segments, e.g. `my-agent`). | -| `role` | Yes | Non-empty. | -| `prompt` | Yes | Non-empty. | -| `parameters` | No | Optional. Each key must be non-empty and unique, and each value must have a known type (string, number, or bool). | -| `version` | — | Stamped by Daedalus; not something you author. | - -### Actionable validation errors - -When a definition is invalid, Daedalus does not just say "invalid". It reports -**every** problem at once — not only the first — so you can fix them in a single -pass. Each finding names the **field**, what was **observed**, and what was -**expected**: - -``` -daedalus: agent "analyst-custom" is invalid; the edit was not applied: - - role: observed empty; expected a non-empty role/description - - prompt: observed empty; expected a non-empty prompt -``` - -The findings are listed in a stable order (`id`, `role`, `prompt`, then -`parameters`), so the same definition always produces the same report. - -## Notes and limitations - -- The catalog ships **embedded in the binary**. A remote catalog or marketplace - is out of scope for Phase 1. -- Adding, cloning, and importing agents are **non-destructive**: existing - definitions and your manual edits are never overwritten. -- A clone is **independent** of the built-in agent it came from — editing the - clone never changes the original. -- Import converts definitions only; it does **not** carry over backend-specific - Claude Code fields (`tools`, `color`), which have no canonical meaning yet. -- Phase 1 **configures** your project's AI structure; it does not **execute** - agents — that stays with your runtime (for example, Claude Code). -- Every operation that writes an agent validates it against the - [canonical schema](#agent-validation) first; an invalid definition is reported - with actionable findings and never written. diff --git a/docs/guide/managing-architecture.md b/docs/guide/managing-architecture.md deleted file mode 100644 index ad9478e..0000000 --- a/docs/guide/managing-architecture.md +++ /dev/null @@ -1,457 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Managing architecture documents - -[← Back to the manual index](../README.md) - -An **architecture document** is the next artifact after the spec in the SDD -(spec-driven development) pipeline: a blueprint of your project's high-level -structure and decisions — *what* the system is, not *how* to type it. The -*architect* agent derives it from a [spec](managing-specs.md), and the later -stages of the pipeline build on it. You create these documents in your -workspace, version them with Git, and manage them with the -`daedalus architecture` command. - -As with specs, Daedalus manages the **definition** of this step: it creates the -document, optionally wires it to its originating spec, and reserves a -deterministic place for it. It does **not** generate the document's content for -you — see -[Phase 1: Daedalus does not run the agent](#phase-1-daedalus-does-not-run-the-agent) -below. - -## The task, end to end - -Working with an architecture document follows four steps. Daedalus handles the -first two; the last two are yours: - -1. **Create the document.** Run `daedalus architecture create` to create the - document at its canonical path, with a seeded placeholder body. -2. **Link it to its spec (optional).** Pass `--spec ` to record the - `spec → architecture` trace and wire the document to the *architect* step of - the `sdd-default` workflow. You can link at create time or later, with `edit`. -3. **Run the architect on your backend.** Generate the architecture content from - the spec by running the *architect* agent in your own runtime (for example, - Claude Code) — Daedalus does not do this for you. -4. **Refine the document by hand.** Drop the generated content into the file and - edit it. The document is yours; Daedalus never overwrites it. - -## Where architecture documents live - -Every architecture document is persisted as one Markdown file under your -workspace's `.daedalus/architecture/` directory, named after its slug: - -``` -.daedalus/ - architecture/ - payments-arch.md -``` - -Each file is a diff-friendly Markdown document: a **YAML frontmatter** block with -the document's metadata, followed by the **body** (your Markdown, stored -verbatim). - -A document **with no spec linked** carries only its identity in the frontmatter: - -```markdown ---- -slug: payments-arch -kind: architecture -title: Payments Architecture ---- -# Payments Architecture - -> Architecture document placeholder. Daedalus manages this artifact's definition -> but does not run the architect agent (phase 1). Generate the architecture by -> running the "architect" agent (workflow "sdd-default", phase "architecture") on your backend, then replace -> this placeholder with the result and refine it. -``` - -A document **linked to its originating spec** adds a provenance block recording -the trace: - -```markdown ---- -slug: payments-arch -kind: architecture -title: Payments Architecture -spec: payments.md -agent: architect -workflow: sdd-default -phase: architecture -generated: false ---- -# Payments Architecture - -> Architecture document placeholder. Daedalus manages this artifact's definition -> but does not run the architect agent (phase 1). Generate the architecture by -> running the "architect" agent (workflow "sdd-default", phase "architecture") on your backend, using the spec -> below, then replace this placeholder with the result and refine it. - -Source spec: payments.md -``` - -When linked, the frontmatter keeps the **trace** back to its origin: `spec` names -the spec file it derives from, `agent` is the *architect* that produces it, and -`generated: false` records that Daedalus did **not** generate the body — it -seeded a placeholder for you to replace. The provenance block is -**all-or-nothing**: an **unlinked** document carries *none* of those keys, so a -document with no spec never shows misleading *architect* wiring. - -The frontmatter keys are always written in the same order, and for a given link -state every key is always present, so the output is **deterministic**: the same -document always produces the same file, byte for byte, which keeps your Git diffs -clean. These files are your **editable source of truth** — you can edit them by -hand, but the commands below are the scriptable alternative. - -## The slug - -Every architecture document is identified by a **slug**: a stable, unique, -`kebab-case` slug (lowercase letters and digits in dash-separated segments, e.g. -`payments-arch`). The slug is the file name, so it must be unique within the -workspace. A slug that is empty or not valid `kebab-case` is rejected with an -explicit error and nothing is written. - -## Creating a document - -Use `daedalus architecture create ` to create a new architecture document. -The `--title` flag is required; the slug may appear before or after the flags. - -```sh -daedalus architecture create payments-arch --title "Payments Architecture" -``` - -On success, Daedalus reports the file it created and reminds you of the next -step — running the architect on your backend: - -``` -Created architecture document "payments-arch" at .daedalus/architecture/payments-arch.md. -Generate the architecture by running the "architect" agent on your backend, then refine it. -``` - -### Linking to the originating spec - -Pass `--spec ` to link the document to an existing spec — this records -the `spec → architecture` trace. Give the spec's **slug** (for example -`payments`); the frontmatter stores the file reference `payments.md`: - -```sh -daedalus architecture create payments-arch \ - --title "Payments Architecture" \ - --spec payments -``` - -When linked, the confirmation names the spec it was wired to: - -``` -Created architecture document "payments-arch" at .daedalus/architecture/payments-arch.md. -Linked to spec payments.md. Generate the architecture by running the "architect" agent on your backend, then refine it. -``` - -The referenced spec must already exist in `.daedalus/specs/`. If it does not, -Daedalus rejects the run and tells you to capture it first (or to omit `--spec`), -and nothing is written: - -```sh -daedalus architecture create payments-arch --title "Payments Architecture" --spec ghost -``` - -``` -daedalus: spec "ghost" not found in .daedalus/specs; capture it first or omit --spec -``` - -> Capture the spec with `daedalus spec capture` — see -> [Managing specs](managing-specs.md). - -You can also set the document body inline with `--body`, or from a file with -`--body-file`. See all options with: - -```sh -daedalus architecture create --help -``` - -### Options - -| Option | Description | -|---|---| -| `--title ` | The document's title. **Required.** | -| `--spec ` | Link the document to an existing spec by slug (optional). The spec must exist in `.daedalus/specs/`. | -| `--body ` | Set the document body inline. | -| `--body-file ` | Set the document body from a file. Takes precedence over `--body` if both are given. | -| `--path ` | Target repository directory whose `.daedalus/architecture/` the document is added to. Defaults to the current directory. | -| `--preview` | Dry run: show the file that would be created without writing anything. | -| `--help` | Show all available options. | - -### Previewing without writing - -Use `--preview` to perform a **dry run**. Daedalus validates the document and -prints the exact file it would write, but **writes nothing** to disk: - -```sh -daedalus architecture create payments-arch --title "Payments Architecture" --preview -``` - -``` -Preview of creating architecture document "payments-arch" at .daedalus/architecture/payments-arch.md: ---- -slug: payments-arch -kind: architecture -title: Payments Architecture ---- -# Payments Architecture - -> Architecture document placeholder. Daedalus manages this artifact's definition -> but does not run the architect agent (phase 1). Generate the architecture by -> running the "architect" agent (workflow "sdd-default", phase "architecture") on your backend, then replace -> this placeholder with the result and refine it. -``` - -Run the command again without `--preview` to apply it. - -### It will not overwrite your work - -Creating a document is **non-destructive**. If a document with the same slug -already exists, Daedalus leaves the existing file — including any manual edits — -untouched and reports the conflict instead of overwriting it: - -```sh -daedalus architecture create payments-arch --title "Something else" -``` - -``` -daedalus: architecture document already exists: "payments-arch" — not overwritten -``` - -### Invalid input is rejected before anything is written - -A document is checked **before** it touches disk. If the slug or title is -invalid, Daedalus rejects the run, lists **every** problem it found — not just -the first — and writes nothing. Each finding names the field, what was observed, -and what was expected, so you can fix them in one pass: - -```sh -daedalus architecture create Bad_Slug --title "" -``` - -``` -daedalus: architecture document "Bad_Slug" is invalid; it was not created: - - slug: observed "Bad_Slug"; expected kebab-case: lowercase letters/digits in dash-separated segments (e.g. my-architecture) - - title: observed empty; expected a non-empty title -``` - -## Listing documents - -Use `daedalus architecture list` to see every document with its slug, its linked -spec, and its title: - -```sh -daedalus architecture list -``` - -The documents are listed in slug order; the middle column shows the linked spec -file, or `-` when the document has no spec linked: - -``` -Architecture documents (2): - cart-arch - Cart Architecture - payments-arch payments.md Payments Architecture -``` - -When there are no documents yet, the count is zero: - -``` -Architecture documents (0): -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/architecture/` is listed. Defaults to the current directory. | - -## Showing a document - -Use `daedalus architecture show ` to print a document's file content -**verbatim** — frontmatter and body, exactly as it is stored: - -```sh -daedalus architecture show payments-arch -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/architecture/` holds the document. Defaults to the current directory. | - -If the slug does not exist, Daedalus tells you so and writes nothing: - -``` -daedalus: architecture document "ghost" not found -``` - -## Editing a document - -Once a document exists, refine it with `daedalus architecture edit `. This -is how you replace the seeded placeholder with the real architecture content — -for example, after running the architect on your backend — change the title, or -manage the spec link. At least one edit flag is required; the slug may appear -before or after the flags. Writes are atomic. - -```sh -daedalus architecture edit payments-arch --body-file ./generated/payments-arch.md -``` - -On success, Daedalus confirms the change: - -``` -Edited architecture document "payments-arch" at .daedalus/architecture/payments-arch.md. -``` - -### Managing the spec link - -The `--spec` flag attaches or repoints the document's link to its originating -spec; the referenced spec must exist: - -```sh -daedalus architecture edit payments-arch --spec payments -``` - -To **clear** the link — turning the document back into an unlinked one, dropping -its whole provenance block — pass an empty `--spec`: - -```sh -daedalus architecture edit payments-arch --spec= -``` - -> **PowerShell note:** write the clear as a single token, `--spec=`. Passing two -> tokens (`--spec ""`) is misinterpreted by the shell and will not clear the -> link. - -### Options - -At least one edit flag is required. - -| Option | Description | -|---|---| -| `--title ` | Set the document's title. | -| `--spec ` | Set the originating spec link by slug. An empty value (`--spec=`) clears the link. A non-empty one must reference an existing spec. | -| `--body ` | Set the document's body inline. | -| `--body-file ` | Set the document's body from a file. Takes precedence over `--body` if both are given. | -| `--path ` | Target repository directory whose `.daedalus/architecture/` holds the document. Defaults to the current directory. | -| `--help` | Show all available options. | - -### Edits are validated before anything is written - -An edit is checked **before** it touches disk, and the write is **atomic**. If -the result would be invalid — for example, an empty title — Daedalus rejects the -edit, reports the problem, and leaves your existing file completely intact (never -half-written): - -```sh -daedalus architecture edit payments-arch --title "" -``` - -``` -daedalus: architecture document "payments-arch" is invalid; the edit was not applied: - - title: observed empty; expected a non-empty title -``` - -A non-empty `--spec` that names a spec which does not exist is rejected the same -way, and the link is left unchanged: - -```sh -daedalus architecture edit payments-arch --spec ghost -``` - -``` -daedalus: spec "ghost" not found in .daedalus/specs; capture it first or pass --spec "" to clear the link -``` - -### Editing requires at least one change - -Running `edit` with no edit flag is treated as a usage error, not a silent no-op: - -```sh -daedalus architecture edit payments-arch -``` - -``` -daedalus: architecture edit requires at least one edit flag (--title, --spec, --body, --body-file) -``` - -### Editing a document that does not exist - -`edit` only works on a document that already lives in your workspace. If the slug -is not there, Daedalus rejects the run and tells you to create it first: - -```sh -daedalus architecture edit ghost --title "anything" -``` - -``` -daedalus: architecture document "ghost" not found -the document must already exist; create it first -``` - -## Removing a document - -Use `daedalus architecture remove ` to delete a document. **Only** that -document's file is removed; no other file in the workspace is touched. - -```sh -daedalus architecture remove payments-arch -``` - -``` -Removed architecture document "payments-arch" from .daedalus/architecture/payments-arch.md. -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/architecture/` holds the document. Defaults to the current directory. | - -Removing a document that does not exist is reported as an explicit error, not a -silent success: - -``` -daedalus: architecture document "ghost" not found -``` - -## Phase 1: Daedalus does not run the agent - -Daedalus **configures** the `spec → architecture` step; it does not **execute** -it. When you create a document, Daedalus: - -- creates the document at its canonical path with a seeded placeholder body, -- optionally records its link to the originating spec (the `architecture` phase - of the `sdd-default` workflow), and -- does **not** call a model or launch the *architect*. - -Generating the document's real content from the spec is done **by you**, running -the *architect* agent in your own backend (for example, Claude Code). The seeded -document says so in its body, and a linked document's frontmatter carries -`generated: false` to make that explicit. Once you have the generated -architecture, drop it into the file — with `daedalus architecture edit` or by -hand — and refine it. - -## Notes and limitations - -- Architecture documents are persisted as Markdown files under - `.daedalus/architecture/`, one file per document, named `.md`, in a - deterministic, git-friendly format. The same document always renders the same - bytes: fixed key order, a single trailing newline, and an all-or-nothing - provenance block. -- The spec link is **optional**. A linked document records the `spec → - architecture` trace and its *architect*-step provenance; an unlinked document - carries only its identity. `--spec=` on `edit` clears the link. -- Creating is **non-destructive**: it never overwrites an existing document you - have refined. `edit` is **atomic** and validated before writing, so an invalid - edit leaves your file intact. -- Bodies are stored **verbatim** as arbitrary Markdown — Daedalus does not - interpret or rewrite them. -- Phase 1 **configures** the `spec → architecture` step; it does not **run** the - *architect* agent — generating the architecture stays with your runtime (for - example, Claude Code). - diff --git a/docs/guide/managing-epics-and-tickets.md b/docs/guide/managing-epics-and-tickets.md deleted file mode 100644 index a16b7b0..0000000 --- a/docs/guide/managing-epics-and-tickets.md +++ /dev/null @@ -1,537 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Managing epics and tickets - -[← Back to the manual index](../README.md) - -**Epics** and **tickets** are the planning artifacts of the SDD (spec-driven -development) pipeline — the backlog that follows your -[spec](managing-specs.md) and [architecture](managing-architecture.md). An -**epic** describes an objective and its scope; a **ticket** describes one -feature and always belongs to an epic. The *planner* agent derives them from -your spec and architecture, and you refine them. You manage them in your -workspace, version them with Git, and edit them with the `daedalus epic` and -`daedalus ticket` commands. - -As with the earlier artifacts, Daedalus manages the **definition**: it creates -the epic and ticket folders, records their metadata and origin links, and seeds -each with a placeholder body. It does **not** generate their content or run the -implementation — see -[Phase 1: Daedalus does not run the agent](#phase-1-daedalus-does-not-run-the-agent) -below. - -## The task, end to end - -Working with a backlog follows four steps. Daedalus handles the first two; the -last two are yours: - -1. **Create the epic.** Run `daedalus epic create`, optionally linking it to its - originating spec and architecture, and set its status, priority, and - dependencies. -2. **Create tickets under it.** Run `daedalus ticket create` for each feature. - Every ticket is nested under its parent epic and carries its own metadata and - dependencies. -3. **Run the planner on your backend.** Generate the epic and ticket content from - the spec and architecture by running the *planner* agent in your own runtime - (for example, Claude Code) — Daedalus does not do this for you. -4. **Refine by hand.** Drop the generated content into each file and edit it. The - artifacts are yours; Daedalus never overwrites them. - -## Where epics and tickets live - -The backlog is a **nested** tree under your workspace's `.daedalus/epics/` -directory. Each epic is a folder named after its id; its tickets live in a -`tickets/` subfolder, each in a folder named after the ticket id: - -``` -.daedalus/ - epics/ - epic-05-sdd-backlog/ - epic.md - tickets/ - ticket-05-03-epics-tickets-management/ - ticket.md -``` - -The **folder name is the id**. An epic id is `epic-NN-` (a number `NN` -and a `kebab-case` slug); a ticket id is `ticket-NN-MM-`, where `NN` is the -parent epic's number and `MM` is the ticket's sequence within that epic. The -markdown file inside is named by kind — `epic.md` or `ticket.md` — so renaming a -slug renames only the folder and keeps the file name stable. - -Each file is a diff-friendly Markdown document: a **YAML frontmatter** block with -the artifact's metadata, followed by the **body** (your Markdown, stored -verbatim). An `epic.md` linked to its spec and architecture looks like this: - -```markdown ---- -id: epic-05-sdd-backlog -kind: epic -title: SDD Backlog -status: todo -priority: medium -spec: sdd-backlog.md -architecture: sdd-backlog-arch.md -depends_on: [epic-04-workflows] -agent: planner -workflow: sdd-default -phase: epics -generated: false ---- - -``` - -A `ticket.md` adds the mandatory `epic` link to its parent, right after its -identity: - -```markdown ---- -id: ticket-05-03-epics-tickets-management -kind: ticket -title: Epics & Tickets Management -epic: epic-05-sdd-backlog -status: todo -priority: high -spec: sdd-backlog.md -architecture: sdd-backlog-arch.md -depends_on: [ticket-05-02-architecture-docs] -agent: planner -workflow: sdd-default -phase: tickets -generated: false ---- - -``` - -A few things to note about the frontmatter: - -- `status`, `priority`, and `depends_on` are **always present** (`depends_on` is - `[]` when empty), so the metadata shape is stable and a diff never has to tell - "absent" from "empty". -- The origin links `spec` and `architecture` are **optional** and **omitted** - when not set — an unlinked artifact carries neither key. -- The *planner*-step provenance block (`agent`, `workflow`, `phase`, - `generated`) is **all-or-nothing**: it is written only when the artifact - records at least one origin link (spec or architecture). The `phase` is `epics` - for an epic and `tickets` for a ticket. `generated: false` records that - Daedalus did **not** generate the body. - -The output is **deterministic** — the same epic or ticket always produces the -same file, byte for byte — which keeps your Git diffs clean. These files are your -**editable source of truth**: you can edit them by hand, but the commands below -are the scriptable alternative. - -## Status and priority - -`status` and `priority` are **closed sets** — a value outside them is rejected. - -| `status` | Meaning | -|---|---| -| `todo` | Defined, not yet started. **The default.** | -| `in-progress` | Work is underway. | -| `blocked` | Work cannot proceed (for example, an unmet dependency). | -| `done` | Completed. | - -| `priority` | | -|---|---| -| `low` | | -| `medium` | The default. | -| `high` | | -| `critical` | | - -When you omit `--status` or `--priority`, the defaults (`todo` and `medium`) -apply. - -## Dependencies and origin links - -- **`--depends-on`** records an explicit, comma-separated list of artifact ids - this epic or ticket depends on (other ticket or epic ids). The list is stored - in `depends_on`, with duplicates removed and the order you wrote preserved. In - this phase Daedalus **records** the dependencies; it does not yet verify that - the referenced ids exist or that the graph is free of cycles. -- **`--spec`** and **`--architecture`** link the artifact to its originating spec - and architecture document, by slug. These are **optional**, but when given the - referenced artifact must already exist in `.daedalus/specs/` or - `.daedalus/architecture/`; otherwise the command is rejected. Together with a - ticket's mandatory `epic` link, these preserve the trace - `ticket → epic → spec / architecture`. - -# `daedalus epic` - -Manage epics with the `epic` subcommands: `create`, `list`, `show`, `edit`, and -`remove`. - -## Creating an epic - -Use `daedalus epic create ` to create an epic. You supply the number -and the slug explicitly — they compose the id `epic-NN-` (no -auto-numbering). The `--title` flag is required. - -```sh -daedalus epic create 05 sdd-backlog --title "SDD Backlog" -``` - -On success, Daedalus reports the folder it created: - -``` -Created epic "epic-05-sdd-backlog" at .daedalus/epics/epic-05-sdd-backlog. -``` - -Set metadata and origin links in the same run. A non-existent `--spec` or -`--architecture` is rejected before anything is written: - -```sh -daedalus epic create 05 sdd-backlog \ - --title "SDD Backlog" \ - --status in-progress \ - --priority high \ - --spec sdd-backlog \ - --architecture sdd-backlog-arch \ - --depends-on epic-04-workflows -``` - -See all options with: - -```sh -daedalus epic create --help -``` - -### Options - -| Option | Description | -|---|---| -| `--title ` | The epic's title. **Required.** | -| `--status ` | One of `todo`, `in-progress`, `blocked`, `done`. Defaults to `todo`. | -| `--priority ` | One of `low`, `medium`, `high`, `critical`. Defaults to `medium`. | -| `--spec ` | Link to an existing spec by slug (optional; must exist in `.daedalus/specs/`). | -| `--architecture ` | Link to an existing architecture document by slug (optional; must exist in `.daedalus/architecture/`). | -| `--depends-on ` | Comma-separated dependency ids (optional). | -| `--body ` | Set the epic body inline. | -| `--body-file ` | Set the epic body from a file. Takes precedence over `--body` if both are given. | -| `--path ` | Target repository directory whose `.daedalus/epics/` the epic is added to. Defaults to the current directory. | -| `--preview` | Dry run: show the file that would be created without writing anything. | -| `--help` | Show all available options. | - -### Previewing without writing - -Use `--preview` to perform a **dry run**. Daedalus validates the epic and prints -the file it would write, but **writes nothing** to disk: - -```sh -daedalus epic create 05 sdd-backlog --title "SDD Backlog" --preview -``` - -Run the command again without `--preview` to apply it. - -### It will not overwrite your work - -Creating an epic is **non-destructive**. If an epic with the same id already -exists, Daedalus leaves the existing folder untouched and reports the conflict: - -```sh -daedalus epic create 05 sdd-backlog --title "Something else" -``` - -``` -daedalus: epic already exists: "epic-05-sdd-backlog" — not overwritten -``` - -### Invalid input is rejected before anything is written - -An epic is checked **before** it touches disk. Daedalus lists **every** problem -it found — not just the first — and writes nothing. Each finding names the field, -what was observed, and what was expected: - -```sh -daedalus epic create 05 sdd-backlog --title "" --status nope --priority urgent -``` - -``` -daedalus: epic "epic-05-sdd-backlog" is invalid; it was not created: - - title: observed empty; expected a non-empty title - - status: observed "nope"; expected one of: todo, in-progress, blocked, done - - priority: observed "urgent"; expected one of: low, medium, high, critical -``` - -## Listing epics - -Use `daedalus epic list` to see every epic with its id, status, priority, and -title, in id order: - -```sh -daedalus epic list -``` - -``` -Epics (1): - epic-05-sdd-backlog todo medium SDD Backlog -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/epics/` is listed. Defaults to the current directory. | - -## Showing an epic - -Use `daedalus epic show ` to print an epic's `epic.md` content -**verbatim**: - -```sh -daedalus epic show epic-05-sdd-backlog -``` - -If the id does not exist, Daedalus tells you so: - -``` -daedalus: epic "epic-05-sdd-backlog" not found -``` - -## Editing an epic - -Once an epic exists, change its metadata or body with -`daedalus epic edit `. At least one edit flag is required. The write is -**atomic** and validated first, so an invalid edit leaves your file intact. - -```sh -daedalus epic edit epic-05-sdd-backlog --status done --priority critical -``` - -``` -Edited epic "epic-05-sdd-backlog" at .daedalus/epics/epic-05-sdd-backlog/epic.md. -``` - -The list flags (`--depends-on`) and link flags (`--spec`, `--architecture`) -**replace** the current value. Passing an empty `--spec`, `--architecture`, or -`--depends-on` **clears** it: - -```sh -daedalus epic edit epic-05-sdd-backlog --spec= -``` - -> **PowerShell note:** write a clear as a single token, `--spec=`. Passing two -> tokens (`--spec ""`) is misinterpreted by the shell and will not clear the -> link. The same applies to `--architecture=` and `--depends-on=`. - -The epic's **id** is its structural identity and is not editable; to renumber or -rename, remove the epic and create it anew. See all options with -`daedalus epic edit --help`. - -### Options - -At least one edit flag is required. - -| Option | Description | -|---|---| -| `--title ` | Set the title. | -| `--status ` | Set the status (`todo`, `in-progress`, `blocked`, `done`). | -| `--priority ` | Set the priority (`low`, `medium`, `high`, `critical`). | -| `--spec ` | Set the originating spec link by slug. An empty value (`--spec=`) clears it. A non-empty one must exist. | -| `--architecture ` | Set the originating architecture link by slug. An empty value clears it. A non-empty one must exist. | -| `--depends-on ` | Set the dependency ids (comma-separated). An empty value clears them. | -| `--body ` | Set the body inline. | -| `--body-file ` | Set the body from a file. Takes precedence over `--body`. | -| `--path ` | Target repository directory whose `.daedalus/epics/` holds the epic. Defaults to the current directory. | - -Running `edit` with no edit flag is a usage error, not a silent no-op: - -``` -daedalus: epic edit requires at least one edit flag -``` - -## Removing an epic - -Use `daedalus epic remove ` to delete an epic. **This removes the epic -folder and all of its nested tickets** — the removal cascades: - -```sh -daedalus epic remove epic-05-sdd-backlog -``` - -``` -Removed epic "epic-05-sdd-backlog" (and its tickets) from .daedalus/epics/epic-05-sdd-backlog. -``` - -Removing an epic that does not exist is reported as an explicit error. - -# `daedalus ticket` - -Manage tickets with the `ticket` subcommands: `create`, `list`, `show`, `edit`, -and `remove`. Because a ticket is nested under its epic, every operation takes -the parent epic id. - -## Creating a ticket - -Use `daedalus ticket create ` to create a ticket under an -existing epic. You supply the sequence `MM` and the slug; the epic number `NN` is -**derived from the parent epic id**, so the ticket id `ticket-NN-MM-` stays -consistent with its epic. The `--title` flag is required. - -```sh -daedalus ticket create epic-05-sdd-backlog 03 epics-tickets-management \ - --title "Epics & Tickets Management" -``` - -On success, Daedalus reports the folder it created: - -``` -Created ticket "ticket-05-03-epics-tickets-management" at .daedalus/epics/epic-05-sdd-backlog/tickets/ticket-05-03-epics-tickets-management. -``` - -The ticket takes the same metadata, link, and dependency flags as an epic: - -```sh -daedalus ticket create epic-05-sdd-backlog 03 epics-tickets-management \ - --title "Epics & Tickets Management" \ - --priority high \ - --spec sdd-backlog \ - --architecture sdd-backlog-arch \ - --depends-on ticket-05-02-architecture-docs -``` - -### The parent epic must exist - -A ticket cannot exist without its epic — it lives inside the epic's folder. If -the parent epic is not there, Daedalus rejects the run and tells you to create it -first, writing nothing: - -```sh -daedalus ticket create epic-99-ghost 01 something --title "Something" -``` - -``` -daedalus: parent epic does not exist; create the epic first -``` - -### Options - -| Option | Description | -|---|---| -| `--title ` | The ticket's title. **Required.** | -| `--status ` | One of `todo`, `in-progress`, `blocked`, `done`. Defaults to `todo`. | -| `--priority ` | One of `low`, `medium`, `high`, `critical`. Defaults to `medium`. | -| `--spec ` | Link to an existing spec by slug (optional; must exist). | -| `--architecture ` | Link to an existing architecture document by slug (optional; must exist). | -| `--depends-on ` | Comma-separated dependency ids (optional). | -| `--body ` | Set the ticket body inline. | -| `--body-file ` | Set the ticket body from a file. Takes precedence over `--body`. | -| `--path ` | Target repository directory whose `.daedalus/epics/` holds the parent epic. Defaults to the current directory. | -| `--preview` | Dry run: show the file that would be created without writing anything. | -| `--help` | Show all available options. | - -Creating a ticket is **non-destructive**: an existing ticket id is preserved, not -overwritten: - -``` -daedalus: ticket already exists: "ticket-05-03-epics-tickets-management" — not overwritten -``` - -## Listing tickets - -Use `daedalus ticket list ` to see an epic's tickets, in id order: - -```sh -daedalus ticket list epic-05-sdd-backlog -``` - -``` -Tickets of epic-05-sdd-backlog (1): - ticket-05-03-epics-tickets-management todo high Epics & Tickets Management -``` - -## Showing a ticket - -Use `daedalus ticket show ` to print a ticket's `ticket.md` -content **verbatim**: - -```sh -daedalus ticket show epic-05-sdd-backlog ticket-05-03-epics-tickets-management -``` - -If the ticket is not found under that epic, Daedalus tells you so: - -``` -daedalus: ticket "ticket-05-03-epics-tickets-management" not found under "epic-05-sdd-backlog" -``` - -## Editing a ticket - -Change a ticket's metadata or body with -`daedalus ticket edit `. At least one edit flag is required; -the write is **atomic** and validated first. - -```sh -daedalus ticket edit epic-05-sdd-backlog ticket-05-03-epics-tickets-management --status in-progress -``` - -``` -Edited ticket "ticket-05-03-epics-tickets-management" at .daedalus/epics/epic-05-sdd-backlog/tickets/ticket-05-03-epics-tickets-management/ticket.md. -``` - -The edit flags match `daedalus ticket create` (`--title`, `--status`, -`--priority`, `--spec`, `--architecture`, `--depends-on`, `--body`, -`--body-file`, `--path`); an empty `--spec`, `--architecture`, or `--depends-on` -clears that field (use the single-token form `--spec=` on PowerShell, as above). -A ticket's **id** and its parent **epic** are its structural identity and are not -editable. - -## Removing a ticket - -Use `daedalus ticket remove ` to delete a single ticket. The -epic and its sibling tickets are left intact: - -```sh -daedalus ticket remove epic-05-sdd-backlog ticket-05-03-epics-tickets-management -``` - -``` -Removed ticket "ticket-05-03-epics-tickets-management" from .daedalus/epics/epic-05-sdd-backlog/tickets/ticket-05-03-epics-tickets-management. -``` - -## Phase 1: Daedalus does not run the agent - -Daedalus **configures** the backlog; it does not **execute** the planning or the -implementation. When you create an epic or ticket, Daedalus: - -- creates the folder and its `epic.md` / `ticket.md` with a seeded placeholder - body, -- records the metadata, dependencies, and origin links (and, for a ticket, the - mandatory parent-epic link), and -- does **not** call a model or launch the *planner*. - -Generating the real epic and ticket content from your spec and architecture is -done **by you**, running the *planner* agent in your own backend (for example, -Claude Code); the implementation those tickets describe also happens outside -Daedalus. The seeded body says so, and a linked artifact's frontmatter carries -`generated: false` to make that explicit. Once you have the generated content, -drop it into the file — with `edit` or by hand — and refine it. - -## Notes and limitations - -- The backlog is a **nested** tree under `.daedalus/epics/`: each epic is a - folder (`epic-NN-/epic.md`) and its tickets live in `tickets/` - (`ticket-NN-MM-/ticket.md`). The folder name is the id; the markdown file - is named by kind. -- `status` and `priority` are **closed sets** (`todo`/`in-progress`/`blocked`/`done` - and `low`/`medium`/`high`/`critical`); an invalid value is rejected with the - list of valid values. Defaults are `todo` and `medium`. -- **Dependencies are recorded, not yet verified.** `--depends-on` stores an - explicit, deduplicated list; checking that the ids exist and that the - dependency graph has no cycles is a later feature. -- **Origin links are optional but checked.** A non-empty `--spec` or - `--architecture` must reference an artifact that exists; together with a - ticket's mandatory `epic` link they preserve the - `ticket → epic → spec / architecture` trace. -- **Non-destructive.** Creating never overwrites an existing artifact; `edit` is - atomic and validated before writing. Removing an **epic** cascades to its - tickets; removing a **ticket** leaves the epic and siblings intact. -- Structural identity (an epic's `id`, a ticket's `id` and parent `epic`) is - **not editable**; status, priority, dependencies, spec/architecture links, - title, and body are. -- **Editing files by hand on Windows:** save without a BOM (for example, - `Out-File -Encoding utf8NoBOM`, or an editor that does not inject a byte-order - mark). A BOM at the start of the file breaks frontmatter parsing. -- Phase 1 **configures** the backlog; it does not **run** the *planner* agent or - the implementation — that stays with your runtime (for example, Claude Code). - diff --git a/docs/guide/managing-prompts.md b/docs/guide/managing-prompts.md deleted file mode 100644 index 2d5cdd0..0000000 --- a/docs/guide/managing-prompts.md +++ /dev/null @@ -1,591 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Managing prompts - -[← Back to the manual index](../README.md) - -**Prompts** are reusable pieces of text that feed your project's AI structure — -the guidelines, conventions, and shared fragments your agents build on. Instead -of rewriting the same style rules, glossary, or role definitions in every -project, you keep them as prompts in your workspace, version them with Git, and -edit them with the `daedalus prompt` command. - -Daedalus manages two **kinds** of prompt: - -| Kind | What it is for | -|---|---| -| `global` | Project-wide guidelines that apply across the board — for example style, language, or SDD conventions. | -| `shared` | Reusable fragments other prompts and agents can reference — for example a glossary, role definitions, or a commit policy. | - -Both kinds live side by side in your workspace and never collide: each prompt is -a single file, identified by a unique id. - -## Where prompts live - -Every prompt is persisted as one Markdown file under your workspace's -`.daedalus/prompts/` directory, named after its id: - -``` -.daedalus/ - prompts/ - project-style.md - glossary.md -``` - -Each file is a small, diff-friendly Markdown document: a **YAML frontmatter** -block with the prompt's metadata, followed by the **body** (your Markdown, -stored verbatim). A `project-style.md` global prompt looks like this: - -```markdown ---- -id: project-style -kind: global -title: Project Style -description: House writing and code conventions ---- -Write in clear, concise English. Prefer short sentences. Document only -behavior that exists. -``` - -The frontmatter keys are always written in the same order — `id`, `kind`, -`title`, then `description` — and `description` is omitted entirely when you do -not set one. The body is stored exactly as you wrote it. This makes the output -**deterministic**: the same prompt always produces the same file, byte for byte, -which keeps your Git diffs clean. These files are your **editable source of -truth** — you can edit them by hand, but the commands below are the scriptable -alternative. - -## The id - -Every prompt is identified by an **id**: a stable, unique, `kebab-case` slug -(lowercase letters and digits in dash-separated segments, e.g. `project-style`). -The id is the file name, so it must be unique within the workspace. An id that -is empty or not valid `kebab-case` is rejected with an explicit error and nothing -is written. - -## Listing prompts - -Use `daedalus prompt list` to see every persisted prompt with its id, kind, and -title: - -```sh -daedalus prompt list -``` - -The prompts are listed in id order: - -``` -Prompts (2): - glossary shared Project Glossary - project-style global Project Style -``` - -Filter by kind with `--kind global` or `--kind shared`: - -```sh -daedalus prompt list --kind global -``` - -``` -Prompts (1, kind=global): - project-style global Project Style -``` - -### Options - -| Option | Description | -|---|---| -| `--kind ` | Show only prompts of that kind. Defaults to all. | -| `--path ` | Target repository directory whose `.daedalus/prompts/` is listed. Defaults to the current directory. | - -## Creating a prompt - -Use `daedalus prompt create ` to add a new prompt. The `--kind` and -`--title` flags are required; the id may appear before or after the flags. - -```sh -daedalus prompt create project-style --kind global --title "Project Style" -``` - -On success, Daedalus reports the kind and the file it created: - -``` -Created prompt "project-style" (global) at .daedalus/prompts/project-style.md. -``` - -You can set the body inline with `--body`, or from a file with `--body-file`, -and add an optional one-line `--description`: - -```sh -daedalus prompt create glossary \ - --kind shared \ - --title "Project Glossary" \ - --description "Shared domain vocabulary" \ - --body-file ./notes/glossary.md -``` - -See all options with: - -```sh -daedalus prompt create --help -``` - -### Options - -| Option | Description | -|---|---| -| `--kind ` | The prompt's kind. **Required.** | -| `--title ` | The prompt's title. **Required.** | -| `--description ` | An optional one-line description. | -| `--body ` | Set the prompt body inline. | -| `--body-file ` | Set the prompt body from a file. Takes precedence over `--body` if both are given. | -| `--path ` | Target repository directory whose `.daedalus/prompts/` the prompt is added to. Defaults to the current directory. | -| `--preview` | Dry run: show the file that would be created without writing anything. | -| `--help` | Show all available options. | - -### Previewing without writing - -Use `--preview` to perform a **dry run**. Daedalus validates the prompt and -prints the exact file it would write, but **writes nothing** to disk: - -```sh -daedalus prompt create project-style --kind global --title "Project Style" --preview -``` - -``` -Preview of creating prompt "project-style" (global) at .daedalus/prompts/project-style.md: ---- -id: project-style -kind: global -title: Project Style ---- -``` - -Run the command again without `--preview` to apply it. - -### It will not overwrite your work - -Creating a prompt is **non-destructive**. If a prompt with the same id already -exists, Daedalus leaves the existing file — including any manual edits — -untouched and reports the conflict instead of overwriting it: - -```sh -daedalus prompt create project-style --kind global --title "Something else" -``` - -``` -daedalus: prompt already exists: "project-style" — not overwritten -``` - -### Invalid input is rejected before anything is written - -A prompt is checked against its schema **before** it touches disk. If the id, -kind, or title is invalid, Daedalus rejects the run, lists **every** problem it -found — not just the first — and writes nothing. Each finding names the field, -what was observed, and what was expected, so you can fix them in one pass: - -```sh -daedalus prompt create Bad_Id --kind nope --title "" -``` - -``` -daedalus: prompt "Bad_Id" is invalid; it was not created: - - id: observed "Bad_Id"; expected kebab-case: lowercase letters/digits in dash-separated segments (e.g. my-prompt) - - kind: observed "nope"; expected one of: global, shared - - title: observed empty; expected a non-empty title -``` - -## Showing a prompt - -Use `daedalus prompt show ` to print a prompt's file content **verbatim** — -frontmatter and body, exactly as it is stored: - -```sh -daedalus prompt show project-style -``` - -``` ---- -id: project-style -kind: global -title: Project Style -description: House writing and code conventions ---- -Write in clear, concise English. Prefer short sentences. Document only -behavior that exists. -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/prompts/` holds the prompt. Defaults to the current directory. | - -If the id does not exist, Daedalus tells you so and writes nothing: - -``` -daedalus: prompt "ghost" not found -``` - -## Editing a prompt - -Once a prompt exists, change its title, description, or body with -`daedalus prompt edit `. At least one edit flag is required; the id may -appear before or after the flags. Edits are written directly to the prompt's -file. - -```sh -daedalus prompt edit project-style --title "House Style" -``` - -On success, Daedalus confirms the change: - -``` -Edited prompt "project-style" at .daedalus/prompts/project-style.md. -``` - -You can combine flags in one run — for example, set a new description and -replace the body from a file: - -```sh -daedalus prompt edit project-style \ - --description "House writing and code conventions" \ - --body-file ./notes/style.md -``` - -Passing `--description ""` **clears** the description. See all options with: - -```sh -daedalus prompt edit --help -``` - -### Options - -At least one edit flag is required. - -| Option | Description | -|---|---| -| `--title ` | Set the prompt's title. | -| `--description ` | Set the prompt's description. An empty value clears it. | -| `--body ` | Set the prompt's body inline. | -| `--body-file ` | Set the prompt's body from a file. Takes precedence over `--body` if both are given. | -| `--path ` | Target repository directory whose `.daedalus/prompts/` holds the prompt. Defaults to the current directory. | -| `--help` | Show all available options. | - -The prompt's `id` and `kind` are part of its identity and are not editable -through `edit`. - -### Edits are validated before anything is written - -An edit is checked against the schema **before** it touches disk, and the write -is **atomic**. If the result would be invalid — for example, an empty title — -Daedalus rejects the edit, reports the problem, and leaves your existing file -completely intact (never half-written): - -```sh -daedalus prompt edit project-style --title "" -``` - -``` -daedalus: prompt "project-style" is invalid; the edit was not applied: - - title: observed empty; expected a non-empty title -``` - -### Editing requires at least one change - -Running `edit` with no edit flag is treated as a usage error, not a silent -no-op: - -```sh -daedalus prompt edit project-style -``` - -``` -daedalus: prompt edit requires at least one edit flag (--title, --description, --body, --body-file) -``` - -### Editing a prompt that does not exist - -`edit` only works on a prompt that already lives in your workspace. If the id is -not there, Daedalus rejects the run and tells you to create it first: - -```sh -daedalus prompt edit ghost --title "anything" -``` - -``` -daedalus: prompt not found: "ghost" -the prompt must already exist; create it first -``` - -## Removing a prompt - -Use `daedalus prompt remove ` to delete a prompt. **Only** that prompt's -file is removed; no other file in the workspace is touched. - -```sh -daedalus prompt remove glossary -``` - -``` -Removed prompt "glossary" from .daedalus/prompts/glossary.md. -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/prompts/` holds the prompt. Defaults to the current directory. | - -Removing a prompt that does not exist is reported as an explicit error, not a -silent success: - -``` -daedalus: prompt not found: "glossary" -``` - -## Composing prompts (includes) - -To keep your prompts **DRY**, one prompt can pull in the content of another -instead of copying it. A shared fragment — a glossary, a style guide, a role -definition — lives in exactly one file and is reused **by reference**. When you -render the prompt, Daedalus expands every reference into a single composed text. -The source files are never modified. - -### The include directive - -To include another prompt, put an **include directive** on a line of its own in -the body: - -``` -{{include: }} -``` - -where `` is the `kebab-case` id of the prompt to pull in. The rules are -deliberately simple: - -- The directive must be the **only content on its line** (surrounding whitespace - and indentation are ignored). A line that has other text alongside the - `{{include: ...}}` token is **not** a directive — it is left exactly as - written. This lets you mention the literal token in prose without it being - expanded. -- `` must name a real prompt; it is matched the same way as a file name. - -For example, a `project-style` prompt can reuse a shared `glossary`: - -```markdown ---- -id: project-style -kind: global -title: Project Style ---- -Write in clear, concise English. - -Use the project's vocabulary consistently: - -{{include: glossary}} -``` - -The `glossary` fragment lives in its own file and can be reused by any number of -prompts: - -```markdown ---- -id: glossary -kind: shared -title: Project Glossary ---- -- **Workspace**: the `.daedalus/` directory managed by Daedalus. -- **Prompt**: a reusable piece of text under `.daedalus/prompts/`. -``` - -### Rendering a composed prompt - -`daedalus prompt show` always prints the **raw** file, with the directive left -unresolved — it is what is stored on disk: - -```sh -daedalus prompt show project-style -``` - -``` ---- -id: project-style -kind: global -title: Project Style ---- -Write in clear, concise English. - -Use the project's vocabulary consistently: - -{{include: glossary}} -``` - -`daedalus prompt render` prints the **composed** prompt, with every include -expanded in place: - -```sh -daedalus prompt render project-style -``` - -``` -Write in clear, concise English. - -Use the project's vocabulary consistently: - -- **Workspace**: the `.daedalus/` directory managed by Daedalus. -- **Prompt**: a reusable piece of text under `.daedalus/prompts/`. -``` - -Use `show` when you want to read or edit a prompt's own content, and `render` -when you want the final assembled text. - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/prompts/` holds the prompt. Defaults to the current directory. | - -### Includes are recursive and deterministic - -Composition is **recursive**: an included prompt can itself include others, and -Daedalus resolves the whole chain until nothing is left to expand. It is also -**deterministic** — rendering the same set of prompts always produces the same -text, byte for byte — and **read-only**: `render` never rewrites your prompt -files. - -### A missing reference is reported - -If a directive references an id that has no prompt file, Daedalus rejects the -render and names both the missing id and the prompt that referenced it, so you -know exactly where to look. Nothing is written: - -```sh -daedalus prompt render project-style -``` - -``` -daedalus: included prompt "glossary" not found (referenced by "project-style") -``` - -### Inclusion cycles are detected - -If prompts include each other in a loop — for example `a` includes `b` and `b` -includes `a` — Daedalus detects the cycle instead of looping forever. It rejects -the render and prints the full chain so the loop is self-evident: - -```sh -daedalus prompt render a -``` - -``` -daedalus: include cycle detected: a -> b -> a -``` - -A prompt that includes itself is reported the same way. - -## Previewing prompts in the interface - -Besides the commands above, Daedalus has an interactive terminal interface for -**browsing and previewing** your prompts. The preview shows a prompt's fully -**composed** text — every `{{include: ...}}` already resolved — rendered as -Markdown, so you see exactly what the final prompt looks like. The interface is -**read-only**: it never edits or saves a prompt. - -### Opening the prompt browser - -Run `daedalus` with no subcommand in an interactive terminal: - -```sh -daedalus -``` - -The interface opens on the **root menu**, which lists the six areas of your -workspace. Move the selection to **Prompts** and press `enter` to open it. The -breadcrumb reads `Daedalus › Prompts` and the list shows every prompt in the -current directory's `.daedalus/prompts/` with its id, kind, and title: - -``` -Daedalus › Prompts - - glossary [shared] Project Glossary - project-style [global] Project Style -``` - -> The interface reads the `.daedalus/prompts/` of the directory you launch it -> from, so run it from inside your project. - -Press `esc` to step back to the root menu, or `h` to jump there from anywhere. -See [Navigating the interface](navigating-the-tui.md) for the full set of areas -and keys. - -### Browsing the list - -| Key | Action | -|---|---| -| `↑` / `k` | Move the selection up. | -| `↓` / `j` | Move the selection down. | -| `enter` / `l` | Open the preview for the selected prompt. | -| `/` | Filter the list. | -| `esc` / `backspace` | Go back to the root menu. | -| `h` | Jump to the root menu. | -| `?` | Toggle the help footer (short ↔ full). | -| `q` / `Ctrl+C` | Quit. | - -### Reading the preview - -Press `enter` on a prompt to open its preview. Daedalus composes the prompt and -renders the result as Markdown — headings, lists, emphasis, and code blocks are -formatted for the terminal. A header names the prompt, and a hint at the bottom -shows your scroll position through long content. - -In the preview: - -| Key | Action | -|---|---| -| `↑` / `↓` | Scroll one line. | -| `pgup` / `pgdn` | Scroll one page (also `b` / `f` / `space`). | -| `g` / `G` | Jump to the top / bottom. | -| `esc` | Return to the list. | -| `?` | Toggle the help footer. | -| `Ctrl+C` | Quit. | - -`esc` is the way back to the list; inside the preview, `q` is reserved so you do -not leave the app by accident while reading. The preview never changes the -prompt — to edit it, use `daedalus prompt edit` (above). - -### Empty and error states - -If the directory has no prompts, the list says so and points you to the next -step instead of showing an empty screen: - -``` -No prompts found. - -Create one with `daedalus prompt create`, or run `daedalus init` -if this directory is not a Daedalus workspace yet. -``` - -If a prompt cannot be composed — for example it has an inclusion cycle or -references a prompt that does not exist — the preview shows a readable error -message instead of broken content, and the app keeps running. Return to the list -with `esc`, fix the prompt with `daedalus prompt edit`, and open the preview -again. - -## Notes and limitations - -- Prompts are persisted as Markdown files under `.daedalus/prompts/`, one file - per prompt, in a deterministic, git-friendly format. The same prompt always - renders the same bytes. -- Composition is **DRY** and **non-mutating**: a shared fragment lives in a - single file, is reused by reference, and `daedalus prompt render` resolves - includes in memory without ever rewriting the source files. -- Every write operation is **non-destructive**: creating a prompt never - overwrites an existing one, and an invalid create or edit is rejected before - anything is written, leaving your files intact. -- The body is stored **verbatim** as arbitrary Markdown — Daedalus does not - interpret or rewrite it. -- A prompt's `id` and `kind` define its identity and are not editable; to change - them, remove the prompt and create it anew. -- Phase 1 **configures** your project's AI structure; it does not **execute** - agents — that stays with your runtime (for example, Claude Code). diff --git a/docs/guide/managing-specs.md b/docs/guide/managing-specs.md deleted file mode 100644 index 2b7e8ca..0000000 --- a/docs/guide/managing-specs.md +++ /dev/null @@ -1,444 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Managing specs - -[← Back to the manual index](../README.md) - -A **brief** is the human-authored entry point of the SDD (spec-driven -development) pipeline: a short Markdown statement of intent. The *analyst* agent -turns that brief into a **spec** (a spec/PRD) — a plan that says *what* you are -building and *why*, which the later stages of the pipeline build on. Instead of -keeping these artifacts loose in your repository, you capture them into your -workspace, version them with Git, and manage them with the `daedalus spec` -command. - -Daedalus manages the **definition** of this step: it captures the brief, wires -it to the *analyst* agent, and reserves a deterministic place for the spec to -land. It does **not** generate the spec's content for you — see -[Phase 1: Daedalus does not run the agent](#phase-1-daedalus-does-not-run-the-agent) -below. - -## The task, end to end - -Working with a spec follows four steps. Daedalus handles the first two; the last -two are yours: - -1. **Capture the brief.** Run `daedalus spec capture` to persist your brief and - seed the spec's destination. -2. **Get the spec destination.** Daedalus wires the brief to the *analyst* step - of the `sdd-default` workflow and creates a seeded spec file at the canonical - path, ready to receive the generated content. -3. **Run the analyst on your backend.** Generate the spec/PRD from the brief by - running the *analyst* agent in your own runtime (for example, Claude Code) — - Daedalus does not do this for you. -4. **Refine the spec by hand.** Drop the generated content into the spec file - and edit it. The spec is yours; Daedalus never overwrites it. - -## Where briefs and specs live - -A brief and its spec are a **pair**, sharing one `kebab-case` **slug**. Both live -side by side under your workspace's `.daedalus/specs/` directory: - -``` -.daedalus/ - specs/ - my-feature.brief.md # the brief you captured - my-feature.md # the spec it seeded -``` - -The slug is the file name. The brief is `.brief.md`; the spec is -`.md`. Each is a single, diff-friendly Markdown document: a **YAML -frontmatter** block with the artifact's metadata, followed by the **body** (your -Markdown, stored verbatim). - -A captured `my-feature.brief.md` looks like this: - -```markdown ---- -slug: my-feature -kind: brief -title: My Feature -consumed-by: analyst -workflow: sdd-default -phase: spec ---- - -``` - -The brief's frontmatter records the **link** Daedalus manages: it is -`consumed-by` the `analyst` agent, at the `spec` phase of the `sdd-default` -workflow — the `brief → spec/PRD` step of the -[default SDD pipeline](managing-workflows.md#the-default-sdd-workflow). - -Its seeded spec, `my-feature.md`, looks like this: - -```markdown ---- -slug: my-feature -kind: spec -title: My Feature -brief: my-feature.brief.md -agent: analyst -workflow: sdd-default -phase: spec -generated: false ---- -# My Feature - -> Spec/PRD placeholder. Daedalus manages this artifact's definition but does -> not run the analyst agent (phase 1). Generate the spec by running the -> "analyst" agent (workflow "sdd-default", phase "spec") on your backend, using the brief below, -> then replace this placeholder with the result and refine it. - -Source brief: my-feature.brief.md -``` - -The spec's frontmatter keeps the **trace** back to its origin: `brief` names the -file it was seeded from, `agent` is the *analyst* that produces it, and -`generated: false` records that Daedalus did **not** generate the body — it -seeded a placeholder for you to replace. The frontmatter keys are always written -in the same order and every key is always present, so the output is -**deterministic**: the same brief always produces the same files, byte for byte, -which keeps your Git diffs clean. These files are your **editable source of -truth** — you can edit them by hand, but the commands below are the scriptable -alternative. - -## The slug - -Every brief/spec pair is identified by a **slug**: a stable, unique, -`kebab-case` slug (lowercase letters and digits in dash-separated segments, e.g. -`my-feature`). The slug is the file name, so it must be unique within the -workspace. A slug that is empty or not valid `kebab-case` is rejected with an -explicit error and nothing is written. - -## Capturing a brief - -Use `daedalus spec capture ` to persist a brief and seed its spec -destination. The `--title` flag is required; the slug may appear before or after -the flags. - -```sh -daedalus spec capture my-feature --title "My Feature" -``` - -On success, Daedalus reports both files it created and reminds you of the next -step — running the analyst on your backend: - -``` -Captured brief "my-feature" at .daedalus/specs/my-feature.brief.md and seeded its spec at .daedalus/specs/my-feature.md. -Generate the spec by running the "analyst" agent on your backend, then refine .daedalus/specs/my-feature.md. -``` - -You can set the brief body inline with `--body`, or from a file with -`--body-file`: - -```sh -daedalus spec capture my-feature \ - --title "My Feature" \ - --body-file ./notes/my-feature-brief.md -``` - -See all options with: - -```sh -daedalus spec capture --help -``` - -### Options - -| Option | Description | -|---|---| -| `--title ` | The brief's title. **Required.** | -| `--body ` | Set the brief body inline. | -| `--body-file ` | Set the brief body from a file. Takes precedence over `--body` if both are given. | -| `--path ` | Target repository directory whose `.daedalus/specs/` the brief is captured into. Defaults to the current directory. | -| `--preview` | Dry run: show the files that would be created without writing anything. | -| `--help` | Show all available options. | - -### Previewing without writing - -Use `--preview` to perform a **dry run**. Daedalus validates the brief and lists -the files it would create, but **writes nothing** to disk: - -```sh -daedalus spec capture my-feature --title "My Feature" --preview -``` - -``` -Preview of capturing brief "my-feature" into .daedalus/specs: - + my-feature.brief.md (brief) - + my-feature.md (spec, seeded; generate with the analyst on your backend) -``` - -Run the command again without `--preview` to apply it. - -### It will not overwrite your work - -Capturing is **non-destructive**. If you have already captured a brief and -refined its spec, re-capturing the same slug leaves both files exactly as they -are and tells you nothing was overwritten: - -```sh -daedalus spec capture my-feature --title "My Feature" -``` - -``` -Brief "my-feature" and its spec already exist — left intact (nothing overwritten). -``` - -If only one half of the pair is present — for example you deleted the seeded -spec, or the spec exists but the brief was removed — Daedalus re-creates only the -missing file and preserves the one that is there: - -``` -Brief "my-feature" already existed; re-seeded the missing spec at .daedalus/specs/my-feature.md. -``` - -``` -Spec for "my-feature" already existed and was preserved; re-created the missing brief at .daedalus/specs/my-feature.brief.md. -``` - -This is what protects a spec you have edited: re-capturing never clobbers it. - -### Invalid input is rejected before anything is written - -A brief is checked **before** it touches disk. If the slug or title is invalid, -Daedalus rejects the run, lists **every** problem it found — not just the first — -and writes nothing. Each finding names the field, what was observed, and what was -expected, so you can fix them in one pass: - -```sh -daedalus spec capture Bad_Slug --title "" -``` - -``` -daedalus: brief "Bad_Slug" is invalid; it was not captured: - - slug: observed "Bad_Slug"; expected kebab-case: lowercase letters/digits in dash-separated segments (e.g. my-feature) - - title: observed empty; expected a non-empty title -``` - -## Listing briefs - -Use `daedalus spec list` to see every captured brief with its slug, whether a -spec has been materialized for it, and its title: - -```sh -daedalus spec list -``` - -The briefs are listed in slug order; the middle column shows `spec` when a spec -exists alongside the brief and `no-spec` when it does not: - -``` -Briefs (2): - my-feature spec My Feature - other-idea no-spec Other Idea -``` - -When there are no briefs yet, the count is zero: - -``` -Briefs (0): -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/specs/` is listed. Defaults to the current directory. | - -## Showing a brief or spec - -Use `daedalus spec show ` to print the **spec's** file content -**verbatim** — frontmatter and body, exactly as it is stored: - -```sh -daedalus spec show my-feature -``` - -Add `--brief` to print the **brief** instead: - -```sh -daedalus spec show my-feature --brief -``` - -### Options - -| Option | Description | -|---|---| -| `--brief` | Show the brief (`.brief.md`) instead of the spec (`.md`). | -| `--path ` | Target repository directory whose `.daedalus/specs/` holds the artifact. Defaults to the current directory. | - -If the artifact does not exist, Daedalus tells you so and writes nothing: - -``` -daedalus: spec for "ghost" not found -``` - -``` -daedalus: brief for "ghost" not found -``` - -## Editing the spec - -Once a spec exists, refine it with `daedalus spec edit `. This is how you -replace the seeded placeholder with the real spec/PRD content — for example, -after running the analyst on your backend — or tweak it later. At least one edit -flag is required; the slug may appear before or after the flags. - -```sh -daedalus spec edit my-feature --body-file ./generated/my-feature-spec.md -``` - -On success, Daedalus confirms the change: - -``` -Edited spec "my-feature" at .daedalus/specs/my-feature.md. -``` - -You can set the spec's title and body in the same run; `--body-file` reads the -body from a file, and `--body` sets it inline: - -```sh -daedalus spec edit my-feature --title "My Feature (revised)" --body "..." -``` - -See all options with: - -```sh -daedalus spec edit --help -``` - -### Options - -At least one edit flag is required. - -| Option | Description | -|---|---| -| `--title ` | Set the spec's title. | -| `--body ` | Set the spec's body inline. | -| `--body-file ` | Set the spec's body from a file. Takes precedence over `--body` if both are given. | -| `--path ` | Target repository directory whose `.daedalus/specs/` holds the spec. Defaults to the current directory. | -| `--help` | Show all available options. | - -`edit` changes **only the spec**. The brief is your authored input — refined -outside Daedalus — and is not editable through this command; edit the brief file -by hand if you need to. The spec's `brief` reference and the rest of its -provenance are preserved across an edit. - -### Edits are validated before anything is written - -An edit is checked **before** it touches disk, and the write is **atomic**. If -the result would be invalid — for example, an empty title — Daedalus rejects the -edit, reports the problem, and leaves your existing file completely intact (never -half-written): - -```sh -daedalus spec edit my-feature --title "" -``` - -``` -daedalus: spec "my-feature" is invalid; the edit was not applied: - - title: observed empty; expected a non-empty title -``` - -### Editing requires at least one change - -Running `edit` with no edit flag is treated as a usage error, not a silent no-op: - -```sh -daedalus spec edit my-feature -``` - -``` -daedalus: spec edit requires at least one edit flag (--title, --body, --body-file) -``` - -### Editing a spec that does not exist - -`edit` only works on a spec that already lives in your workspace. If it is not -there, Daedalus rejects the run and points you to capture the brief first: - -```sh -daedalus spec edit ghost --title "anything" -``` - -``` -daedalus: spec "ghost" not found -the spec must already exist; capture its brief first -``` - -## Removing a brief or spec - -Use `daedalus spec remove ` to delete the **spec** file, or -`--brief` to delete the **brief** file. **Only** the one file you name is -removed; the other half of the pair is left intact, so you can drop and re-seed -one half deliberately. - -```sh -daedalus spec remove my-feature -``` - -``` -Removed spec "my-feature" from .daedalus/specs/my-feature.md. -``` - -```sh -daedalus spec remove my-feature --brief -``` - -``` -Removed brief "my-feature" from .daedalus/specs/my-feature.brief.md. -``` - -### Options - -| Option | Description | -|---|---| -| `--brief` | Remove the brief (`.brief.md`) instead of the spec (`.md`). | -| `--path ` | Target repository directory whose `.daedalus/specs/` holds the artifact. Defaults to the current directory. | - -Removing an artifact that does not exist is reported as an explicit error, not a -silent success: - -``` -daedalus: spec for "my-feature" not found -``` - -## Phase 1: Daedalus does not run the agent - -Daedalus **configures** the `brief → spec/PRD` step; it does not **execute** it. -When you capture a brief, Daedalus: - -- persists the brief, -- records its link to the *analyst* agent (the `spec` phase of the `sdd-default` - workflow), and -- seeds the spec file at its canonical path, with a placeholder body. - -It does **not** call a model or launch the *analyst*. Generating the spec's real -content from the brief is done **by you**, running the *analyst* agent in your -own backend (for example, Claude Code). The seeded spec says so in its body, and -its frontmatter carries `generated: false` to make that explicit. Once you have -the generated spec/PRD, drop it into the spec file — with `daedalus spec edit` or -by hand — and refine it. - -## Notes and limitations - -- A brief and its spec are persisted as Markdown files under `.daedalus/specs/`, - paired by a shared `kebab-case` slug (`.brief.md` and `.md`), in a - deterministic, git-friendly format. The same brief always renders the same - bytes: fixed key order, every key present, and a single trailing newline. -- Capturing is **non-destructive**: it never overwrites an existing brief or a - spec you have refined. When only one half of the pair is missing, Daedalus - re-creates just that file and preserves the other. -- The brief is **input you author**; `daedalus spec` does not edit it. `edit` - changes only the spec, preserving its `brief` reference and provenance. -- Bodies are stored **verbatim** as arbitrary Markdown — Daedalus does not - interpret or rewrite them. -- Every write is validated **before** anything is written: an invalid capture or - edit is rejected with actionable findings and leaves your files intact. -- Phase 1 **configures** the `brief → spec/PRD` step; it does not **run** the - *analyst* agent — generating the spec stays with your runtime (for example, - Claude Code). - - diff --git a/docs/guide/managing-workflows.md b/docs/guide/managing-workflows.md deleted file mode 100644 index 3d601d1..0000000 --- a/docs/guide/managing-workflows.md +++ /dev/null @@ -1,766 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Managing workflows - -[← Back to the manual index](../README.md) - -A **workflow** is a declarative **DAG** (directed acyclic graph) that describes -your project's pipeline: an ordered list of **phases**, where each phase names -an **agent**, the artifacts it consumes and produces, a validation **gate**, and -the predecessor phases it **depends on**. Those `depends_on` references are the -**edges** of the graph. Instead of keeping the pipeline in your head, you author -it as a workflow in your workspace, version it with Git, and edit it with the -`daedalus workflow` command. - -Each workflow is a single YAML file, identified by a unique name. A workflow's -phases capture *what* runs and *in what order* — Daedalus models, edits, and -structurally validates that definition for you. - -## The phase schema - -Every phase is a mapping with the same six fields, always in the same order: - -| Field | Required | What it is | -|---|---|---| -| `id` | yes | The phase's identifier, unique within the workflow, in `kebab-case`. It is the handle other phases reference in their `depends_on`, so it is also the node key of the DAG. | -| `agent` | yes | The agent that runs the phase (for example `analyst`, `architect`). An opaque reference — it is not resolved against the agent catalog here. | -| `inputs` | no | The artifacts the phase consumes. A list; order is preserved. | -| `outputs` | no | The artifacts the phase produces. A list; order is preserved. | -| `gate` | yes | The validation criterion an artifact must satisfy to advance past the phase. An opaque reference. | -| `depends_on` | no | The predecessor phases this phase depends on — the incoming edges of this node. A list; order is preserved. | - -The phase order in the file is **significant** and is preserved verbatim: it is -the authored reading order of the pipeline, and Daedalus never reorders it. - -## Where workflows live - -Every workflow is persisted as one YAML file under your workspace's -`.daedalus/workflows/` directory, named after the workflow: - -``` -.daedalus/ - workflows/ - release-pipeline.yaml -``` - -The workflow's name is **not** stored inside the document — it is the file's -base name (`.yaml`), exactly as a prompt's id is its file name. The file -has a single top-level `phases:` key holding the ordered list of phase mappings: - -```yaml -phases: - - id: spec - agent: analyst - inputs: [brief] - outputs: [spec] - gate: spec-gate - depends_on: [] - - id: build - agent: architect - inputs: [spec] - outputs: [design] - gate: design-gate - depends_on: [spec] -``` - -Within each phase the keys are always written in the same order — `id`, `agent`, -`inputs`, `outputs`, `gate`, `depends_on` — and every key is always present, so -the shape is stable and a reader never has to tell "absent" from "empty". The -list-valued keys are rendered in compact **flow style** on a single line -(`inputs: [brief]`), and an empty list as `[]`. The file always ends with a -single trailing newline. - -This makes the output **deterministic**: the same workflow always produces the -same file, byte for byte, which keeps your Git diffs clean. These files are your -**editable source of truth** — you can edit them by hand, but the commands below -are the scriptable alternative. - -## The name - -Every workflow is identified by a **name**: a stable, unique, `kebab-case` slug -(lowercase letters and digits in dash-separated segments, e.g. -`release-pipeline`). The name is the file name, so it must be unique within the -workspace. A name that is not valid `kebab-case` is rejected with an explicit -error and nothing is written. Phase ids follow the same `kebab-case` rule. - -## The default SDD workflow - -You do not start from an empty directory. When you run `daedalus init`, Daedalus -seeds one ready-to-use workflow into `.daedalus/workflows/`: **`sdd-default`**, -the default **SDD** (spec-driven development) pipeline. It is a valid, complete -workflow you can use as-is, adapt to your project, or simply read as a worked -example of the schema. - -The pipeline is a straight, linear chain of six phases — each run by one of the -built-in agents, each producing the artifact the next phase consumes: - -| Phase | Agent | Consumes | Produces | Gate | -|---|---|---|---|---| -| `spec` | `analyst` | `brief` | `spec` | `spec-gate` | -| `architecture` | `architect` | `spec` | `architecture` | `architecture-gate` | -| `epics` | `planner` | `architecture` | `epics` | `epics-gate` | -| `tickets` | `planner` | `epics` | `tickets` | `tickets-gate` | -| `validation` | `validator` | `tickets` | `validation` | `validation-gate` | -| `docs` | `documenter` | `validation` | `docs` | `docs-gate` | - -The first phase, `spec`, is the root: it consumes the external `brief` (the -pipeline's initial artifact) through its `inputs`, so its `depends_on` is empty. -Every other phase depends on the one before it, giving a clean chain with no -cycles. You can see the exact seeded file at any time with -`daedalus workflow show sdd-default`: - -```yaml -phases: - - id: spec - agent: analyst - inputs: [brief] - outputs: [spec] - gate: spec-gate - depends_on: [] - - id: architecture - agent: architect - inputs: [spec] - outputs: [architecture] - gate: architecture-gate - depends_on: [spec] - - id: epics - agent: planner - inputs: [architecture] - outputs: [epics] - gate: epics-gate - depends_on: [architecture] - - id: tickets - agent: planner - inputs: [epics] - outputs: [tickets] - gate: tickets-gate - depends_on: [epics] - - id: validation - agent: validator - inputs: [tickets] - outputs: [validation] - gate: validation-gate - depends_on: [tickets] - - id: docs - agent: documenter - inputs: [validation] - outputs: [docs] - gate: docs-gate - depends_on: [validation] -``` - -### Where the implementation step is - -You may notice there is no "implementation" or "developer" phase between -`tickets` and `validation`, even though something must turn the tickets into a -working implementation before it can be validated. That is intentional: Daedalus -**configures** your project's AI structure but does not **execute** the pipeline, -and the implementation step is performed **externally** — by a developer, or by an -agent on your backend — not by Daedalus. - -So the implementation is the (un-modeled) gap on the edge from `tickets` to -`validation`: Daedalus hands off the `tickets`, an external actor builds the -implementation, and `validation` resumes from those same tickets. This is why the -`validation` phase consumes `[tickets]` rather than an `implementation` artifact — -no phase in this workflow produces an `implementation`, so listing it as an input -would describe an artifact that never exists. - -### It is a valid DAG - -The seeded workflow passes semantic validation out of the box — no cycles, no -missing artifacts, and every agent is a known built-in: - -```sh -daedalus workflow validate sdd-default -``` - -``` -Workflow "sdd-default" is semantically valid. -``` - -The seeding is **non-destructive**: if you have already created or edited an -`sdd-default.yaml`, re-running `daedalus init` leaves your file untouched and -reports it as already present. It is yours to change — rename the gates, add or -remove phases, or rework the chain entirely with the editing commands below. - -## Listing workflows - -Use `daedalus workflow list` to see every persisted workflow with its name and -phase count: - -```sh -daedalus workflow list -``` - -The workflows are listed in name order: - -``` -Workflows (1): - release-pipeline 2 phases -``` - -When there are no workflows yet, the count is zero: - -``` -Workflows (0): -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/workflows/` is listed. Defaults to the current directory. | - -## Creating a workflow - -Use `daedalus workflow create ` to add a new, **empty** workflow. Add its -phases afterwards with `daedalus workflow add-phase`. - -```sh -daedalus workflow create release-pipeline -``` - -On success, Daedalus reports the file it created: - -``` -Created workflow "release-pipeline" at .daedalus/workflows/release-pipeline.yaml. -``` - -A brand-new workflow has no phases yet, so its file is just the stable empty -shape: - -```yaml -phases: [] -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/workflows/` the workflow is added to. Defaults to the current directory. | -| `--preview` | Dry run: show the file that would be created without writing anything. | - -### Previewing without writing - -Use `--preview` to perform a **dry run**. Daedalus validates the name and prints -the exact file it would write, but **writes nothing** to disk: - -```sh -daedalus workflow create release-pipeline --preview -``` - -``` -Preview of creating workflow "release-pipeline" at .daedalus/workflows/release-pipeline.yaml: -phases: [] -``` - -Run the command again without `--preview` to apply it. - -### It will not overwrite your work - -Creating a workflow is **non-destructive**. If a workflow with the same name -already exists, Daedalus leaves the existing file — including any manual edits — -untouched and reports the conflict instead of overwriting it: - -```sh -daedalus workflow create release-pipeline -``` - -``` -daedalus: workflow already exists: "release-pipeline" — not overwritten -``` - -An invalid name is rejected before anything is written: - -```sh -daedalus workflow create Bad_Name -``` - -``` -daedalus: workflow name "Bad_Name" is not valid kebab-case -``` - -## Showing a workflow - -Use `daedalus workflow show ` to print a workflow's file content -**verbatim** — exactly the canonical YAML as it is stored: - -```sh -daedalus workflow show release-pipeline -``` - -```yaml -phases: - - id: spec - agent: analyst - inputs: [brief] - outputs: [spec] - gate: spec-gate - depends_on: [] - - id: build - agent: architect - inputs: [spec] - outputs: [design] - gate: design-gate - depends_on: [spec] -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/workflows/` holds the workflow. Defaults to the current directory. | - -If the name does not exist, Daedalus tells you so and writes nothing: - -``` -daedalus: workflow "ghost" not found -``` - -## Adding a phase - -Use `daedalus workflow add-phase ` to **append** a phase to an existing -workflow. The `--id`, `--agent`, and `--gate` flags are required; the list flags -take comma-separated values. - -```sh -daedalus workflow add-phase release-pipeline \ - --id spec \ - --agent analyst \ - --gate spec-gate \ - --inputs brief \ - --outputs spec -``` - -On success, Daedalus confirms the edit and the resulting phase count: - -``` -Applied add-phase to workflow "release-pipeline" at .daedalus/workflows/release-pipeline.yaml (1 phase). -``` - -To wire a phase to its predecessor, pass `--depends-on` — this is how you draw -an edge of the DAG: - -```sh -daedalus workflow add-phase release-pipeline \ - --id build \ - --agent architect \ - --gate design-gate \ - --inputs spec \ - --outputs design \ - --depends-on spec -``` - -``` -Applied add-phase to workflow "release-pipeline" at .daedalus/workflows/release-pipeline.yaml (2 phases). -``` - -The new phase is appended at the end, preserving the order of the existing -phases. - -### Options - -| Option | Description | -|---|---| -| `--id ` | The phase id, `kebab-case`. **Required.** | -| `--agent ` | The agent that runs the phase. **Required.** | -| `--gate ` | The phase's validation gate. **Required.** | -| `--inputs ` | Comma-separated input artifacts. Optional. | -| `--outputs ` | Comma-separated output artifacts. Optional. | -| `--depends-on ` | Comma-separated predecessor references — the DAG edges. Optional. | -| `--path ` | Target repository directory whose `.daedalus/workflows/` holds the workflow. Defaults to the current directory. | - -## Editing a phase - -Use `daedalus workflow edit-phase --id ` to change an existing -phase's fields **in place**, keeping its position in the list. Only the flags -you pass are changed; everything else stays as it was. - -```sh -daedalus workflow edit-phase release-pipeline --id build --agent planner -``` - -``` -Applied edit-phase to workflow "release-pipeline" at .daedalus/workflows/release-pipeline.yaml (2 phases). -``` - -To rename a phase, pass `--new-id`. The list flags (`--inputs`, `--outputs`, -`--depends-on`) **replace** the phase's current list; passing an empty value -clears it. - -### Options - -| Option | Description | -|---|---| -| `--id ` | The id of the phase to edit. **Required.** | -| `--new-id ` | Rename the phase to this id. Optional. | -| `--agent ` | Set the phase's agent. | -| `--gate ` | Set the phase's gate. | -| `--inputs ` | Set the phase's inputs (comma-separated; empty clears). | -| `--outputs ` | Set the phase's outputs (comma-separated; empty clears). | -| `--depends-on ` | Set the phase's `depends_on` (comma-separated; empty clears). | -| `--path ` | Target repository directory whose `.daedalus/workflows/` holds the workflow. Defaults to the current directory. | - -`edit-phase` requires `--id` so it knows which phase to change: - -```sh -daedalus workflow edit-phase release-pipeline -``` - -``` -daedalus: workflow edit-phase requires --id -``` - -## Removing a phase - -Use `daedalus workflow remove-phase --id ` to delete a phase, -preserving the order of the rest: - -```sh -daedalus workflow remove-phase release-pipeline --id build -``` - -``` -Applied remove-phase to workflow "release-pipeline" at .daedalus/workflows/release-pipeline.yaml (1 phase). -``` - -Removing a phase touches only that phase; it does **not** rewrite other phases' -`depends_on` lists, so any reference to the removed phase is left exactly as you -wrote it. - -### Options - -| Option | Description | -|---|---| -| `--id ` | The id of the phase to remove. **Required.** | -| `--path ` | Target repository directory whose `.daedalus/workflows/` holds the workflow. Defaults to the current directory. | - -## Removing a workflow - -Use `daedalus workflow remove ` to delete a workflow. **Only** that -workflow's file is removed; no other file in the workspace is touched. - -```sh -daedalus workflow remove release-pipeline -``` - -``` -Removed workflow "release-pipeline" from .daedalus/workflows/release-pipeline.yaml. -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/workflows/` holds the workflow. Defaults to the current directory. | - -Removing a workflow that does not exist is reported as an explicit error, not a -silent success: - -``` -daedalus: workflow not found: "ghost" -``` - -## Edits are validated before anything is written - -Every phase edit (`add-phase`, `edit-phase`, `remove-phase`) is checked against -the schema **before** it touches disk, and the write is **atomic**. If the -result would be invalid, Daedalus rejects the edit, lists **every** problem it -found — not just the first — and leaves your existing file completely intact -(never half-written). Each finding names the offending phase, the field, what -was observed, and what was expected, so you can fix them all in one pass: - -```sh -daedalus workflow add-phase release-pipeline --id Bad-ID -``` - -``` -daedalus: workflow "release-pipeline" is invalid; the edit was not applied: - - phase Bad-ID: id: observed "Bad-ID"; expected kebab-case: lowercase letters/digits in dash-separated segments (e.g. write-spec) - - phase Bad-ID: agent: observed empty; expected a non-empty agent reference (e.g. analyst) - - phase Bad-ID: gate: observed empty; expected a non-empty gate reference (e.g. spec-gate) -``` - -A duplicate phase id is rejected the same way, since the id is the DAG node key -and must be unique within the workflow: - -```sh -daedalus workflow add-phase release-pipeline --id spec --agent x --gate y -``` - -``` -daedalus: phase already exists: "spec" -``` - -Editing a phase that is not there names the missing id: - -```sh -daedalus workflow edit-phase release-pipeline --id ghost --agent x -``` - -``` -daedalus: phase not found: "ghost" -``` - -And a phase edit only works on a workflow that already exists: - -```sh -daedalus workflow edit-phase ghost --id spec --agent x -``` - -``` -daedalus: workflow not found: "ghost" -the workflow must already exist; create it first -``` - -## Validating a workflow - -The edit checks above are **structural** — they keep each phase well-formed. To -check that the workflow as a whole describes a coherent, runnable graph, use -`daedalus workflow validate `. This is **semantic** validation of the DAG: -it reads a workflow you have already defined and reports problems with the graph -itself. - -It checks for: - -- **Cycles** — a loop in the `depends_on` dependencies, so the graph is not a DAG. -- **Missing artifacts** — a phase consumes an `input` that is neither the initial - `brief` artifact nor an `output` of any of its predecessors (any phase reachable - by following `depends_on` back toward the roots). -- **Unknown agents** — a phase references an `agent` that does not exist in the - workspace. -- **Unknown dependencies** — a `depends_on` entry that names no existing phase - (and is not the initial `brief`); this is usually a typo. - -```sh -daedalus workflow validate release-pipeline -``` - -A workflow with no problems reports that it is valid: - -``` -Workflow "release-pipeline" is semantically valid. -``` - -When there are problems, each is reported on its own line, naming the affected -phase, the kind of problem, the observed value, and what would make it valid: - -``` -Workflow "release-pipeline" is semantically invalid (2 findings): - - phase "build": missing-artifact: observed "blueprint"; no predecessor phase produces this input artifact and it is not the initial artifact "brief"; add a predecessor that outputs it, or correct the input - - phase "build": unknown-agent: observed "wizard"; no agent with this id exists in the workspace catalog; create or import the agent, or correct the reference -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/workflows/` holds the workflow. Defaults to the current directory. | - -### What each problem looks like - -A **cycle** names the phases that form the loop, rendered as a chain so it is -self-evident: - -``` -Workflow "cycle-pipe" is semantically invalid (1 finding): - - phase "alpha": cycle: observed "alpha -> beta -> alpha"; these phases form a dependency cycle, so the workflow is not a DAG; break the loop by removing one of the depends_on edges -``` - -A **missing artifact** names the phase and the input that no predecessor produces: - -``` -Workflow "missing-art" is semantically invalid (1 finding): - - phase "build": missing-artifact: observed "spec"; no predecessor phase produces this input artifact and it is not the initial artifact "brief"; add a predecessor that outputs it, or correct the input -``` - -An **unknown agent** names the phase and the agent that could not be found: - -``` -Workflow "unknown-agent" is semantically invalid (1 finding): - - phase "spec": unknown-agent: observed "wizard"; no agent with this id exists in the workspace catalog; create or import the agent, or correct the reference -``` - -An **unknown dependency** names the phase and the dangling reference (here a typo -of `brief`): - -``` -Workflow "unknown-dep" is semantically invalid (1 finding): - - phase "spec": unknown-dependency: observed "breif"; depends_on references no existing phase (and is not the initial artifact "brief"); fix the reference or add the missing phase -``` - -### Built-in agents are always known - -The unknown-agent check resolves an agent against the workspace's agent catalog, -which includes **both** the agents you have materialized under `.daedalus/agents/` -**and** the built-in agents (`analyst`, `architect`, `planner`, `validator`, -`documenter`). A phase that references a built-in agent you have **not** added to -the workspace yet is therefore **valid** — the built-in still exists as far as the -project is concerned, so it is not flagged. Only an agent id that is neither -materialized nor a known built-in is reported as unknown. - -### Exit codes - -`validate` sets its exit code so you can gate on it from a script or CI: - -| Exit code | Meaning | -|---|---| -| `0` | The workflow is semantically valid. | -| `1` | The workflow is semantically invalid (one or more findings). | -| `2` | A usage or load error — for example, the workflow does not exist:
`daedalus: workflow not found: "ghost"` | - -## Visualizing a workflow in the TUI - -Besides the commands above, Daedalus has an interactive terminal interface that -can draw a workflow as a **graph (DAG)**, so you can see the pipeline's shape — -its phases and how they depend on each other — without reading the YAML. The view -is **read-only**: it never edits or runs anything. - -### Opening the Workflows area - -Run `daedalus` with no subcommand in an interactive terminal: - -```sh -daedalus -``` - -The interface opens on the **root menu**, which lists the six areas of your -workspace. Move the selection to **Workflows** and press `enter` to open it. The -breadcrumb reads `Daedalus › Workflows` and the list shows every workflow in the -current directory's `.daedalus/workflows/`, each with its name and phase count: - -``` -Daedalus › Workflows - - release-pipeline [2 phases] -``` - -> The interface reads the `.daedalus/workflows/` of the directory you launch it -> from, so run it from inside your project. - -Press `esc` to step back to the root menu, or `h` to jump there from anywhere. -See [Navigating the interface](navigating-the-tui.md) for the full set of areas -and keys. - -### Browsing the list - -| Key | Action | -|---|---| -| `↑` / `k` | Move the selection up. | -| `↓` / `j` | Move the selection down. | -| `enter` / `l` | Open the DAG view for the selected workflow. | -| `/` | Filter the list. | -| `esc` / `backspace` | Go back to the root menu. | -| `h` | Jump to the root menu. | -| `?` | Toggle the help footer (short ↔ full). | -| `q` / `Ctrl+C` | Quit. | - -### Reading the DAG - -Press `enter` (or `l`) on a workflow to open its DAG view. A header names the -workflow, and the graph is laid out **top to bottom in dependency order** — -roots (the phases nothing depends on) at the top, their dependents below — so the -pipeline reads from start to finish. - -Each phase is drawn as a bordered **node**. Its headline is the phase id followed -by the agent that runs it, written `@`; below it, when present, a compact -line each for the phase's inputs, outputs, and gate. A phase with no inputs, -outputs, or gate simply omits those lines. A node looks like this: - -``` -╭─────────────────────╮ -│ spec @analyst │ -│ in: brief │ -│ out: spec │ -│ gate: spec-gate │ -╰─────────────────────╯ -``` - -Between nodes, a vertical **connector** shows the dependency edge. When a phase -depends on earlier phases, the connector is labelled `after ` (the -ids from its `depends_on`); the arrow points down to the phase the edge leads -into: - -``` - │ after spec - ↓ -╭─────────────────────╮ -│ build @architect │ -│ in: spec │ -│ out: design │ -│ gate: design-gate │ -╰─────────────────────╯ -``` - -### Moving around and leaving the view - -The DAG scrolls within the view, and a hint at the bottom shows your position -through a long graph: - -| Key | Action | -|---|---| -| `↑` / `↓` | Scroll one line. | -| `pgup` / `pgdn` | Scroll one page (also `b` / `f` / `space`). | -| `g` / `G` | Jump to the top / bottom. | -| `esc` | Return to the list. | -| `?` | Toggle the help footer. | -| `Ctrl+C` | Quit. | - -`esc` is the way back to the list; inside the DAG view, `q` is reserved so you do -not leave the app by accident while reading. The view never changes the workflow -— to edit it, use the `daedalus workflow` commands above. - -### Empty, unreadable, and cyclic workflows - -The view degrades gracefully when there is nothing — or nothing valid — to draw: - -- **Empty workflow.** A workflow with no phases is a valid document; the view says - so and points you to the next step instead of showing a blank graph: - - ``` - This workflow is empty. - - Add phases with `daedalus workflow add-phase`. - ``` - -- **Unreadable workflow.** If the file cannot be loaded, the view shows a readable - error message instead of broken content, and the app keeps running. Return to - the list with `esc`. - -- **Dependency cycle.** If the phases depend on each other in a loop, the view does - not hang. It draws the phases in their declared order and shows a warning at the - top: - - ``` - ! dependency cycle detected — phases shown in declared order - ``` - -If the Workflows list itself is empty, it tells you so and points you at the CLI: - -``` -No workflows found. - -Create one with `daedalus workflow create`, or run `daedalus init` -if this directory is not a Daedalus workspace yet. -``` - -## Notes and limitations - -- Workflows are persisted as YAML files under `.daedalus/workflows/`, one file - per workflow, in a deterministic, git-friendly format. The same workflow - always renders the same bytes: fixed key order, phases never reordered, list - values in flow style, and a single trailing newline. -- Every write operation is **non-destructive**: creating a workflow never - overwrites an existing one, and an invalid `add-phase`, `edit-phase`, or - `remove-phase` is rejected before anything is written, leaving your file - intact. -- Validation in this phase is **structural** only: it checks each phase against - the schema (required `id`/`agent`/`gate`, `kebab-case` ids, ids unique within - the workflow). It does **not** yet check the graph's *meaning* — there is no - cycle detection and no check that a `depends_on`, `inputs`, or `agent` - reference resolves to something that exists. -- The interactive DAG view is strictly **read-only**: it draws the pipeline but - has no binding that edits a phase or runs the workflow. -- Phase 1 **models, edits, and validates** a workflow's definition; it does not - **execute** workflows — running the pipeline stays with your runtime (for - example, Claude Code). diff --git a/docs/guide/navigating-the-tui.md b/docs/guide/navigating-the-tui.md deleted file mode 100644 index 4bad543..0000000 --- a/docs/guide/navigating-the-tui.md +++ /dev/null @@ -1,302 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Navigating the interface - -[← Back to the manual index](../README.md) - -Daedalus is a terminal application. Launched with no arguments, it opens an -interactive interface organized into **areas** — one for each part of your -project's AI structure. This chapter explains how to move around: how to reach -each area, how to step back, and how to read where you are. The keys are the -same everywhere, so once you learn them in one area you know them in all of them. - -> This chapter covers how you move around the interface, read documents in it, -> filter lists, and get help on the available shortcuts. In-interface editing of -> artifacts arrives in a later chapter as that feature ships. - -## Launching the interface - -In an interactive terminal: - -```sh -./daedalus -``` - -The interface opens on the **root screen** — a menu listing the six areas. It -reads your workspace lazily: nothing is loaded until you enter an area, so -startup is instant. - -If you run Daedalus without an interactive terminal (piped input, a script, CI, -or a container with no TTY), it does not start the interface; see -[Command line](command-line.md) for that behavior. - -## The six areas - -The root screen lists six areas, each one mapping to a part of your project's -AI structure. They always appear in the same order, top to bottom: - -| Area | What it shows | -|---|---| -| **Init** | Your workspace status: whether a `.daedalus/` workspace exists, the project name, the configured backends, and what an init would create. | -| **Agents** | The built-in agent catalog, each agent listed by id and role. | -| **Prompts** | The global and shared prompts in your workspace. | -| **Workflows** | Your declarative DAG workflows, each tagged with its phase count. | -| **Backlog** | Your specs, architecture documents, epics, and tickets, in one list. | -| **Build** | A preview of what compiling to your configured backend would change. | - -Each row on the menu carries a one-line summary so you can tell the areas apart -at a glance. The areas are **read-only views** in the interface — they show you -what is there. Creating and editing artifacts is done with the matching -`daedalus` commands (for example `daedalus init`, `daedalus prompt`, -`daedalus build`), which the empty-state messages point you to. - -## Moving around - -Navigation uses one small, consistent set of keys. They behave the same on every -area and every detail screen: the same action always uses the same key, so once -you learn a key it works everywhere it applies. - -| Key | Action | -|---|---| -| `↑` / `k` | Move the selection up | -| `↓` / `j` | Move the selection down | -| `enter` / `l` | Enter the selected area, or open the selected item | -| `esc` / `backspace` | Go back one level | -| `h` | Jump straight to the root menu (home) | -| `/` | Filter the current list (shown when an area has items) | -| `r` | Retry loading an area that failed (shown only in the error state) | -| `?` | Toggle the help line between short and expanded | -| `q` / `Ctrl+C` | Quit Daedalus | - -A help line at the bottom of every screen always shows the keys available where -you are, so you never have to memorize them. See [Getting help](#getting-help) -below for how to expand it. - -### Entering an area - -From the root menu, move the selection with `↑`/`↓` (or `k`/`j`) to the area you -want, then press `enter` (or `l`) to go in. The area loads its contents and shows -them as a list. - -### Going back, and reaching the root - -There are two ways back, and you are never trapped: - -- Press `esc` (or `backspace`) to step back **one level** — from a detail screen - to its area's list, or from an area back to the root menu. -- Press `h` at any time to jump **straight to the root menu**, however deep you - are. - -Every screen is reached by going in, and every screen can be left by stepping -back, so there are no dead ends: a way back always exists. - -When you re-enter an area, it is shown exactly as you left it — your place in the -list is remembered. - -> Quitting from a detail screen: while you are reading a scrollable detail view, -> `q` is reserved so you do not exit by accident — use `esc` to step back, or -> `Ctrl+C` if you really want to quit. On the root menu and in any area list, -> `q` quits as usual. - -## Knowing where you are: the breadcrumb - -The top of every screen shows a **breadcrumb** — a trail that names your current -location, starting from the root: - -``` -Daedalus › Prompts › project-style -``` - -- `Daedalus` is the root menu. -- The next segment is the area you are in (here, **Prompts**), highlighted so the - active area is always identifiable. -- A third segment appears when you have opened an item into a detail screen (here, - the prompt `project-style`). - -Read the breadcrumb as the path back: each `›` is one `esc` away, or press `h` to -return to `Daedalus` in a single step. - -## Opening an item - -Some areas list items you can open into a **detail screen** — a read-only view of -that item: - -- **Prompts** opens a prompt's composed text, formatted for reading. -- **Workflows** opens a workflow's DAG. -- **Backlog** opens a spec, architecture document, or epic, formatted for reading. - -Select the row and press `enter` (or `l`) to open it. Inside a detail screen the -content scrolls: use `↑`/`↓` to scroll line by line, `pgup`/`pgdn` (or `b`/`f`) -by page, and `g`/`G` to jump to the top or bottom. A hint shows how far through -the content you are. Press `esc` to return to the list. - -Some rows are purely informational (for example the **Init** and **Build** -summaries) and do not open a detail screen; pressing `enter` on them does -nothing. - -## Reading documents - -Most of what Daedalus manages is written as Markdown — prompts, specs, -architecture documents, and epics. When you open one of these in a detail -screen, Daedalus shows it **rendered**, not as raw Markdown source. You see: - -- **Headings** set apart from body text. -- **Lists** laid out as bullets and numbers. -- **Tables** drawn with proper rows and columns. -- **Code blocks** in a monospaced block, with syntax highlighting. -- **Emphasis** — bold and italic — shown as styled text. - -The document is wrapped to the width of the screen, so lines never run off the -edge — make your terminal wider and the text reflows to use the space. Exact -colors depend on your terminal's color support, but the layout stays readable -everywhere. - -(Workflows are the exception: a workflow opens as a diagram of its DAG rather -than as a Markdown document.) - -## Filtering a list - -When an area lists more rows than you want to scan, you can filter it down to the -ones you care about. Press `/` from any area that has items to open the filter: - -1. Type a term to match. The filter is **case-insensitive** and matches anywhere - in a row's label or its badge (the small tag next to it), so you can filter by - name, kind, or status. -2. Press `enter` to apply it. The list shrinks to the matching rows. -3. Press `esc` at any time to cancel and leave the list unchanged. - -While a filter is active, a banner at the top of the list shows it — for example -`Filter: "spec" · press / to change` — so a short list is never mysterious. To -**change** the filter, press `/` again (it opens pre-filled with your current -term so you can refine it). To **clear** it, press `/`, empty the field, and -press `enter` — an empty term shows everything again. - -If a term matches nothing, the list does not go blank or trap you: it tells you -*"No matches"* and reminds you that `/` changes the filter and `esc` goes back. - -A blank filter (only spaces) is rejected with a clear message, since it could -never match anything on purpose — clear the field instead to show all rows. - -## A consistent look - -Across every area and screen, Daedalus uses one visual language: the same accent -color marks the selected row and headings, the same border frames detail panels -and forms, the same badges tag items, and the loading, empty, and error states -all share that styling. Once you recognize how one area looks, every other area -reads the same way. - -## Loading, empty, and error states - -An area is always in exactly one of these states, and **all of them keep the way -back available** — you can step back or jump home no matter what an area shows: - -- **Loading** — while an area fetches its contents you briefly see `Loading…`. - This is usually instant. -- **Empty** — when an area has nothing to list, it shows a short message that - tells you why and which command would populate it (for example, *"No - `.daedalus` workspace here yet. Run `daedalus init` to create one."*). An empty - area is a hint, not a wall. -- **Error** — if an area cannot load (for example a malformed file), it shows the - error and a prompt to recover. Press `r` to **retry** the load in place, or - `esc` to go back. An error never strands you. - -## Getting help - -You never have to remember the keys. Every screen shows a **help line** at the -bottom listing the shortcuts you can use right now. Two views, one key: - -- The **short help line** is always visible — a compact row of the handful of - shortcuts most worth knowing on the current screen. -- Press `?` to **expand** it into the full list of every shortcut available in - the current context, grouped for easy scanning. Press `?` again to collapse it. - -The help is **contextual** — it shows what applies where you are, and nothing -that does not: - -- On an **area list**, it shows move, open, filter, back, and home. -- In a **detail screen**, it shows the scrolling keys (line, page, and - jump-to-top/bottom) and back. -- In a **form** (such as the list filter), it shows submit, cancel, and how to - move between fields. -- Even in the **loading**, **empty**, and **error** states the help line stays - available, so help — and the way out — is always one `?` away. - -`?` works in **every** context, including while a form is open. What the help -line announces is exactly what works: the shortcuts you see are the shortcuts the -screen accepts. - -## Keyboard shortcuts reference - -The same action always uses the same key. Which keys are *available* depends on -the screen, but their meaning never changes. - -**Everywhere:** - -| Key | Action | -|---|---| -| `?` | Toggle the help line (short ↔ expanded) | -| `q` / `Ctrl+C` | Quit Daedalus (`q` is held back while reading or typing — see below) | - -**Root menu and area lists:** - -| Key | Action | -|---|---| -| `↑` / `k`, `↓` / `j` | Move the selection | -| `enter` / `l` | Enter an area, or open the selected item | -| `/` | Filter the list (when the area has items) | -| `esc` / `backspace` | Go back one level | -| `h` | Jump to the root menu | -| `r` | Retry a failed load (error state only) | - -**Detail screens (reading a document or DAG):** - -| Key | Action | -|---|---| -| `↑` / `k`, `↓` / `j` | Scroll line by line | -| `pgup` / `b`, `pgdn` / `f` / `space` | Scroll by page | -| `g`, `G` | Jump to top / bottom | -| `esc` / `backspace` | Back to the list | -| `h` | Jump to the root menu | - -**Forms (such as the filter):** - -| Key | Action | -|---|---| -| `enter` | Submit | -| `esc` | Cancel | -| `tab`, `shift+tab` | Move to the next / previous field | - -While you are reading a detail screen or typing in a form, `q` is *not* a quit — -it scrolls or types normally — so you never exit by accident. Use `esc` to back -out, or `Ctrl+C` if you really want to quit. (The one shortcut that still works -inside a form is `?`, which opens the help rather than typing a literal `?`.) - -Shortcuts are fixed in this version of Daedalus; they cannot be remapped. - -## Responsiveness - -The interface is built to stay out of your way: - -- **It responds instantly.** Moving between areas, opening and scrolling - documents, and using forms react the moment you press a key — the interface - never freezes while you work. -- **Slow work happens in the background.** When something takes a moment — loading - an area's contents, or rendering a large document — Daedalus shows `Loading…` - instead of locking up, and you can always press `esc` to go back or cancel - while it works. -- **It starts fast.** The interface opens effectively instantly. -- **It is quiet when idle.** While you are not interacting, Daedalus uses no - noticeable CPU — there are no constant animations or redraws burning cycles in - the background. -- **It stays stable over a long session.** Navigating in and out of areas - repeatedly does not slow the interface down or let its memory creep up. - -> Known limitation: if you resize your terminal window while a Markdown document -> is open, the document keeps its previous width until you close and reopen it. -> Reopening the document re-wraps it to the new size. This affects only the open -> document view, not navigation. - ---- - -> Phase 1 note: Daedalus configures your project's AI structure; it does not -> execute agents — that stays with your runtime (for example, Claude Code). diff --git a/docs/guide/tracing-the-backlog.md b/docs/guide/tracing-the-backlog.md deleted file mode 100644 index 48da9a2..0000000 --- a/docs/guide/tracing-the-backlog.md +++ /dev/null @@ -1,237 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Tracing the backlog - -[← Back to the manual index](../README.md) - -Once you have [specs](managing-specs.md), -[architecture documents](managing-architecture.md), and a backlog of -[epics and tickets](managing-epics-and-tickets.md), the **traceability** chain -ties them together: every ticket belongs to an epic, and every epic and ticket -can record the spec or architecture document it derives from. The -`daedalus trace` command lets you **verify** that this chain is consistent and -**navigate** it in both directions — from a spec down to its tickets, and from a -ticket back up to its origin. - -`daedalus trace` is **read-only**. It never runs an agent and never writes -anything; it simply reads the links already recorded in your artifacts' -frontmatter. There is no separate index to keep in sync — the artifacts -themselves are the single source of truth, so if you edit a link by hand, `trace` -reflects it on the next run. - -## The task, end to end - -- **Check the backlog is consistent.** Run `daedalus trace verify` to confirm - every recorded link resolves and every ticket has a parent epic. It reports any - inconsistency, worst-first. -- **Navigate the chain.** Run `daedalus trace show ` to walk the - chain from any artifact — a spec, an epic, or a ticket — in the natural - direction for that artifact. - -## What the chain looks like - -The chain has three levels, linked by the frontmatter your artifacts already -carry: - -``` -spec ─▶ epic ─▶ ticket - │ │ - └── origin links (spec / architecture) recorded in the frontmatter -``` - -- A **ticket** always names its parent **epic** (mandatory). -- An **epic** and a **ticket** may each record an **origin** spec and/or - architecture document (optional — see - [Managing epics and tickets](managing-epics-and-tickets.md)). When a ticket - records no origin of its own, it **inherits** its epic's origin. - -`trace` reasons over exactly these links; it does not invent or store new ones. - -## Verifying the chain - -Use `daedalus trace verify` to check the whole workspace: - -```sh -daedalus trace verify -``` - -When every link resolves and no ticket is orphaned, the chain is consistent and -the command exits with status `0`: - -``` -Traceability chain is consistent (no inconsistencies). -``` - -### What it checks - -`verify` reports three kinds of inconsistency. Two are **hard errors** that mean -the chain is genuinely broken; one is a **soft warning** for a traceability gap -that the backlog model allows. - -| Kind | Severity | What it means | Affects exit code? | -|---|---|---|---| -| `broken-link` | error | An epic, ticket, or architecture document records an origin (spec or architecture) that **does not exist** — the reference is present but dangles. | **Yes** | -| `orphan-ticket` | error | A ticket's parent **epic no longer exists** (for example, the epic folder was removed). | **Yes** | -| `missing-origin` | warning | An epic (or architecture document) records **no origin link at all**. This is a traceability gap, but it is **legal** — linking a spec/architecture is optional. A ticket with no origin of its own is **not** reported: it inherits its epic's origin. | No | - -### Exit codes - -`verify` sets its exit code so you can gate on it from a script or CI: - -| Exit code | Meaning | -|---|---| -| `0` | The chain is consistent, **or** has only warnings (a soft gap never fails the check). | -| `1` | The chain has at least one **hard error** (`broken-link` or `orphan-ticket`). | -| `2` | A usage or load error. | - -### When there are inconsistencies - -Findings are reported worst-first (errors before warnings) in a deterministic -order, each on its own line, naming the affected artifact, the kind of problem, -the value at fault, and how to fix it. When there are hard errors, the command -exits `1`: - -``` -Traceability chain has 2 errors and 1 warning: - - [error] ticket-05-03-epics-tickets-management: orphan-ticket: observed "epic-05-sdd-backlog"; ticket references a parent epic that does not exist; the epic was removed or the reference is wrong — restore the epic or correct the reference - - [error] epic-06-compile: broken-link: observed "compile-spec.md"; epic references a spec that does not exist; create the spec or correct the reference - - [warning] epic-07-telemetry: missing-origin: observed ""; epic records no origin spec or architecture; link one to complete the trace (optional per the backlog model, but recommended) -``` - -When the only findings are warnings, the chain is still **consistent** and the -command exits `0` — the gaps are reported for visibility, not as failures: - -``` -Traceability chain is consistent with 1 warning (no hard errors): - - [warning] epic-07-telemetry: missing-origin: observed ""; epic records no origin spec or architecture; link one to complete the trace (optional per the backlog model, but recommended) -``` - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/` chain is verified. Defaults to the current directory. | - -## Navigating the chain - -Use `daedalus trace show ` to walk the chain from any artifact. -Daedalus infers the **direction** from the shape of the id: - -- a **spec slug** descends — spec → its epics → their tickets; -- a **ticket id** (`ticket-NN-MM-`) ascends — ticket → its epic → its origin - spec/architecture; -- an **epic id** (`epic-NN-`) shows **both** — the epic's origin and its - tickets. - -### From a spec (descending) - -Pass a spec slug to see every epic linked to it and their tickets: - -```sh -daedalus trace show sdd-backlog -``` - -``` -spec sdd-backlog — SDD Backlog - └─ epic epic-05-sdd-backlog — SDD Backlog - └─ ticket ticket-05-03-epics-tickets-management — Epics & Tickets Management - └─ ticket ticket-05-04-traceability — Traceability -``` - -If no epic links to the spec, Daedalus says so instead of showing an empty tree: - -``` -spec sdd-backlog — SDD Backlog - (no epics link to this spec) -``` - -### From a ticket (ascending) - -Pass a ticket id to climb back to its epic and its origin spec/architecture. When -the ticket records no origin of its own, the origin shown is the one it inherits -from its epic: - -```sh -daedalus trace show ticket-05-04-traceability -``` - -``` -ticket ticket-05-04-traceability — Traceability - └─ epic epic-05-sdd-backlog — SDD Backlog - └─ origin spec sdd-backlog — SDD Backlog - └─ origin architecture sdd-backlog-arch — SDD Backlog Architecture -``` - -An **orphan** ticket — one whose parent epic no longer exists — is flagged -explicitly: - -``` -ticket ticket-05-04-traceability — Traceability - └─ epic epic-05-sdd-backlog — MISSING (orphan ticket) - └─ origin spec: (none resolved) - └─ origin architecture: (none resolved) -``` - -### From an epic (both directions) - -Pass an epic id to see its origin links and its tickets at once: - -```sh -daedalus trace show epic-05-sdd-backlog -``` - -``` -epic epic-05-sdd-backlog — SDD Backlog - origin spec: sdd-backlog.md - origin architecture: sdd-backlog-arch.md - tickets: - └─ ticket ticket-05-03-epics-tickets-management — Epics & Tickets Management - └─ ticket ticket-05-04-traceability — Traceability -``` - -An epic with no recorded origin shows `(none)` for that link, and an epic with no -tickets shows `tickets: (none)`. - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/` chain is navigated. Defaults to the current directory. | - -If the id is not in the chain, Daedalus tells you so and points you at the -relevant listing command — for example, for an unknown spec slug: - -``` -daedalus: no spec "ghost" in the traceability chain (a spec must be materialized; check 'daedalus spec list') -``` - -## Phase 1: read-only, no agents - -`daedalus trace` does not run any agent and does not write to your workspace. It -**reads** the links already recorded in your specs, architecture documents, -epics, and tickets, and reports or navigates the chain they form. It keeps **no -index of its own**: the artifacts' frontmatter is the single source of truth, so -the result always reflects the current state of your files. Edit a link by hand -and the next `trace` run sees the change immediately. - -## Notes and limitations - -- `trace` is **read-only and deterministic**: the same workspace state always - produces the same report, with findings in a stable, worst-first order. It - never executes agents and never modifies your files. -- It holds **no separate index** — it reads the origin and parent links directly - from each artifact's frontmatter. Fixing an inconsistency therefore means - editing the source artifact (for example, with `daedalus epic edit` or - `daedalus ticket edit`, or by hand). -- The **severity split is intentional.** Because recording a spec/architecture - origin is optional in the backlog, a *missing* origin is a warning (never fails - `verify`), while a *dangling* origin or a missing parent epic is a hard error - (fails `verify`). -- **Fixing links by hand:** to clear an origin link, use the single-token form - `--spec=` or `--architecture=` with `daedalus epic edit` / `daedalus ticket - edit` (on PowerShell, `--spec ""` as two tokens is misread by the shell). When - editing artifact files directly on Windows, save **without a BOM** — a leading - byte-order mark breaks frontmatter parsing, which `trace` then cannot read. -- Phase 1 **verifies and navigates** the chain; it does not **run** the pipeline - — generating the artifacts stays with your runtime (for example, Claude Code). - diff --git a/docs/guide/troubleshooting.md b/docs/guide/troubleshooting.md deleted file mode 100644 index 4c2c68e..0000000 --- a/docs/guide/troubleshooting.md +++ /dev/null @@ -1,132 +0,0 @@ -# Troubleshooting - -[← Back to the manual index](../README.md) - -Most problems you hit with Daedalus are reported with an **actionable** message -that tells you the file, the spot, the rule, and what was expected. This chapter -shows the common ones and how to read them. For where output goes, remember the -[output convention](command-reference.md): the human summary is on **stdout** and -the structured JSON logs are on **stderr**. - -## An invalid definition - -When a definition does not satisfy its schema, Daedalus does not just say -"invalid" — it names the **file**, the exact **spot**, the **rule**, and what was -**observed** versus what was **expected**. For example, `daedalus validate` on a -manifest whose `backends` lists an unsupported value: - -``` -Conventions: workspace conforms (no violations). -Definitions: 1 error and 0 warnings: - - [error] .daedalus/daedalus.yaml: backends[nonexistent-backend]: schema: observed unsupported backend "nonexistent-backend"; expected one of the supported backends: claude-code -``` - -Exit `1`. Read the finding left to right — severity, file, spot, rule, then -observed-vs-expected. Here the fix is to set `backends` to a supported value -(`claude-code`) in `.daedalus/daedalus.yaml`, then re-run `daedalus validate` to -confirm the workspace conforms. - -The same actionable shape appears wherever a definition is checked — for example -when [`daedalus agent edit`](managing-agents.md#editing-an-agent) rejects an edit -that would produce an empty role, listing every problem at once so you can fix -them in a single pass. - -## Validation that fails - -[`daedalus validate`](validating-conventions.md) checks two axes — **conventions** -and **definitions** — and a single error in either one exits `1`. It is -**read-only**: it reports violations, it never auto-fixes them. The fix is yours -(rename the file, move it into place, correct the manifest), and the next run -confirms it. - -- **Errors** are genuine breaches (a bad name, a missing required directory, a - misplaced artifact, a broken backlog link, an unsupported backend, a DAG - cycle). They fail the check (exit `1`). -- **Warnings** flag an optional gap — for example an epic with no recorded - origin. They are reported for visibility but do **not** fail the check; a - workspace whose only findings are warnings still exits `0`. - -Gate CI on `daedalus validate`: a non-zero exit means the workspace drifted from -the conventions or carries an invalid definition. - -## A build that aborts - -[`daedalus build`](compiling-to-a-backend.md) **validates first** and writes -nothing if anything is wrong, so a failed build always leaves your repository -exactly as it was: - -- **No workspace** in the target directory — `build` aborts and points you at - `daedalus init`. -- **Invalid canonical definition** — `build` reports the problems and stops - (exit `3`); fix them and re-run. -- **No adapter for the configured backend** — `build` fails with a clear message - (exit `4`) and writes nothing. - -## Building without a terminal - -`build` never writes silently. When it runs **without an interactive terminal** -— a script, CI, or a container with no TTY — there is no one to confirm at the -gate, so a plain `build` **prints the diff and writes nothing**, then tells you -how to proceed. To write from automation, pass `--yes`: - -```sh -daedalus build --yes -``` - -`--yes` skips the interactive gate and compiles directly; it works with or -without a terminal. `--preview` always wins over `--yes` — an explicit dry run -never writes. See -[Writing from a script or CI](compiling-to-a-backend.md#writing-from-a-script-or-ci). - -## The interface will not open - -`daedalus` with no subcommand launches the interface, which **requires an -interactive terminal**. With piped input, in a script, in CI, or in a container -with no TTY, Daedalus does not start the interface — it prints a short notice and -exits `0`. That is expected; run it in a real terminal to use the interface, or -use the subcommands (`init`, `build`, `validate`, `trace`) from automation. See -[Command line](command-line.md#non-interactive-use). - -## Reading the logs - -When the summary on stdout is not enough, the structured JSON logs on **stderr** -show what Daedalus decided and why. Lower the threshold for more detail, or raise -it to silence routine logs: - -```sh -# More detail -DAEDALUS_LOG_LEVEL=debug daedalus build --yes - -# Only warnings and errors (silences INFO logs) -DAEDALUS_LOG_LEVEL=error daedalus validate -``` - -With `DAEDALUS_LOG_LEVEL=error`, the routine INFO logs are suppressed entirely, -leaving only the human-readable summary on stdout. Because logs go to stderr, you -can capture them independently: - -```sh -daedalus build --yes 2> daedalus.log -``` - -Then look for the event you need — for example a `definition rejected` event -(logged at `WARN`, naming the `reason` and the `definition` path) when a build -aborts on an invalid definition, or a `convention violated` event when -`validate` reports a problem. See -[Configuration → Logging](configuration.md#logging) for the full details. - -## A note on Windows and BOM - -When you edit workspace files by hand on Windows, save them **without a -byte-order mark (BOM)**. A leading BOM breaks YAML frontmatter parsing, which -[`daedalus trace`](tracing-the-backlog.md#notes-and-limitations) and the validators -then cannot read. Most editors offer "UTF-8 without BOM" — use it for files under -`.daedalus/`. - -## Still stuck? - -- Re-run the command with `DAEDALUS_LOG_LEVEL=debug` and read the stderr log. -- Confirm you are pointing at the right workspace with `--path`. -- Check the relevant chapter: [Command reference](command-reference.md), - [Validating conventions](validating-conventions.md), or - [Compiling to a backend](compiling-to-a-backend.md). diff --git a/docs/guide/validating-conventions.md b/docs/guide/validating-conventions.md deleted file mode 100644 index 586fa26..0000000 --- a/docs/guide/validating-conventions.md +++ /dev/null @@ -1,231 +0,0 @@ -> **Outdated — describes Daedalus v1.** The commands and workspace model on this page were replaced in v2. See the [Overview](../getting-started/overview.md) and [`kit/METHOD.md`](../../kit/METHOD.md). - -# Validating conventions - -[← Back to the manual index](../README.md) - -Daedalus is built for **teams**: several people share and version the same -`.daedalus/` workspace. For that to stay consistent, the **conventions** — how -files and ids are named, how the workspace is laid out, how artifacts are -formatted, and how the backlog is linked together — cannot be tribal or -implicit. They are written down once and, just as importantly, they are -**machine-checkable**. The `daedalus validate` command reads your workspace and -reports every place it drifts from those conventions, so a stray name or a -mislaid file is caught early instead of leaking into the shared repository. - -`daedalus validate` is **read-only**. It never runs an agent and never writes -anything — it **reports** violations, it does **not** auto-fix them. Fixing a -violation is up to you (rename the file, move it into place, reorder the -frontmatter), and the next run confirms the fix. - -The command checks your workspace along **two axes** and prints both in one -report: - -- **Conventions** — how files and ids are named, how the workspace is laid out, - how artifacts are formatted, and how the backlog is linked. Described next. -- **Definitions** — whether your agents, workflows, and manifest are themselves - well-formed. See [Validating definitions](#validating-definitions) below. - -A fresh [`daedalus init`](initializing-a-workspace.md) workspace passes both axes -clean. - -## The conventions - -The conventions fall into four families. Each one exists so that a workspace -shared across a team reads and diffs the same way no matter who touched it last. - -### Naming - -Every file and id uses **`kebab-case`** — lowercase words joined by hyphens, no -spaces, underscores, or camelCase. On top of that, epics and tickets follow a -fixed id shape so their place in the backlog is obvious from the name alone: - -| Artifact | Pattern | Example | -|---|---|---| -| Epic directory / id | `epic-NN-` | `epic-08-state-collab` | -| Ticket directory / id | `ticket-NN-MM-` | `ticket-08-03-team-conventions` | -| Agent (file name without `.md`) | `kebab-case` | `analyst.md` | -| Workflow (file name without `.yaml`) | `kebab-case` | `sdd-default.yaml` | -| Prompt (file name without `.md`) | `kebab-case` | `glossary.md` | - -In the patterns, `NN` is the epic number and `MM` is the ticket's sequence -within that epic (both numeric), and `` is a kebab-case description. **A -ticket's directory name is its id** — there is no separate id to keep in sync. - -### Structure - -The workspace follows the canonical `.daedalus/` layout that -[`daedalus init`](initializing-a-workspace.md) creates: the expected directories -are present, and the backlog is **nested** — tickets live inside their epic's -`tickets/` folder, not in a flat list. The tracked `.state/` directory is part -of the layout too: it carries a versioned placeholder so the folder exists in -git from the start, ready to hold progress state. The validation flags a -required directory that is missing as well as an artifact that sits where it does -not belong. - -### Format - -Artifacts are formatted for clean, deterministic diffs: - -- **YAML frontmatter** uses a **canonical key order** — the same keys always - appear in the same sequence, so two people editing the same artifact produce - the same ordering and the diff shows only what actually changed. -- **Markdown** is **structured**: hierarchical headings, tables for metadata, - fenced code blocks for schemas and DAGs. - -### Traceability - -The backlog is linked end to end: **every ticket references its parent epic**, -and **every epic references its origin** (the spec or architecture it derives -from). This is the same chain that [`daedalus trace`](tracing-the-backlog.md) -navigates; `validate` checks that the links the conventions require are in place. - -> The canonical sources for these conventions are **`init.md` §7** (the project -> guideline `daedalus init` writes into your workspace) and **`CLAUDE.md` §6**. -> `daedalus validate` is the **machine-checkable expression** of those written -> conventions — when the prose and the command ever seem to disagree, the prose -> is the source of truth and the command is how you enforce it. - -## Running the validation - -From the root of your repository: - -```sh -daedalus validate -``` - -To target a different directory, use `--path`: - -```sh -daedalus validate --path ./my-repo -``` - -The command inspects the `.daedalus/` workspace in that directory, checks it -against all four convention families **and** lints the definitions (agents, -workflows, manifest), and prints a single report. It writes nothing. - -### Options - -| Option | Description | -|---|---| -| `--path ` | Target repository directory whose `.daedalus/` workspace is validated. Defaults to the current directory. | -| `--help` | Show all available options. | - -## Reading the report - -The report has one line per axis. When the workspace follows every convention -and every definition is well-formed, `validate` says so on both axes and exits -with status `0`: - -``` -Conventions: workspace conforms (no violations). -Definitions: all agents, workflows and manifest are valid. -``` - -When an axis finds something, it prints a count followed by one line per -finding. Each finding line has the same shape: - -``` -[severity] location: spot: rule: reason -``` - -- **`[severity]`** is `error` or `warning` (see below). -- **`location`** is the file or directory at fault. -- **`spot`** is the exact place inside it (a field, a key, a phase). -- **`rule`** is the short name of the convention or schema rule that was broken. -- **`reason`** explains what was observed and what was expected. - -See [Validating definitions](#validating-definitions) below for a worked -`Definitions:` example. Because a single error in either axis exits `1`, fix -every reported finding and run `daedalus validate` again to confirm the -workspace conforms. - -### Errors vs. warnings - -Not every finding fails the check: - -- **Errors** are genuine convention breaches — a bad name, a missing required - directory, a misplaced artifact, a broken traceability link. They **fail** the - validation (exit code `1`). -- **Warnings** flag an **optional origin link that is absent**. Recording the - spec or architecture an epic derives from is recommended but optional, so a - missing one is reported for visibility without **failing** the build. This is - the same severity split that [`daedalus trace`](tracing-the-backlog.md#what-it-checks) - applies to the traceability chain. - -A workspace whose only findings are warnings still conforms (the `Conventions:` -axis reports no errors) and still exits `0`. - -## Validating definitions - -Beyond the conventions, the same `daedalus validate` run **lints the definitions -themselves** — your agents, your workflows, and your manifest — and prints them -under a `Definitions:` section of the report. Conventions check that an artifact -is named and placed correctly; the definition linters check that its **content** -is well-formed and coherent. The linters read the **canonical model** in -`.daedalus/`, not any backend's native format, so the result is the same whatever -backend you compile to. - -Three families are linted: - -- **Agents** — each agent definition is schema-valid: the required fields are - present, the id is `kebab-case`, the role and prompt are filled in, and any - parameter types are valid. -- **Workflows (DAG)** — each workflow is a coherent DAG: no **cycles**, no phase - that consumes an artifact **no phase produces**, no reference to an **unknown - agent**, no **duplicate phase ids**, and no malformed dependencies. -- **Manifest (`daedalus.yaml`)** — the manifest's required fields are well-formed - (`name`, `version`, `backends`, `conventions`), every listed backend is a - **supported** one, and the conventions block is coherent. - -Each definition finding is **actionable**: it names the definition at fault, the -exact spot inside it (a field, a phase, or a key), and what was expected versus -what was found. Like the conventions report, the findings are deterministic and -printed in a stable order, so the same workspace always produces the same output. - -For example, a manifest that lists a backend Daedalus does not support produces a -`Definitions:` section with a count and one finding per problem. The finding -names the file, the spot (`backends[...]`), the rule (`schema`), and what was -observed versus expected: - -``` -Conventions: workspace conforms (no violations). -Definitions: 1 error and 0 warnings: - - [error] .daedalus/daedalus.yaml: backends[nonexistent-backend]: schema: observed unsupported backend "nonexistent-backend"; expected one of the supported backends: claude-code -``` - -Because there is at least one definition error, the command exits `1`. To fix it -you would set `backends` to a supported value (`claude-code`) and run `daedalus -validate` again to confirm both axes are clean. - -The same `Definitions:` section reports the other definition families too — for -example a workflow whose DAG loops back on itself is reported as a `dag` finding -naming the cycle (`cycle detected through phase ...`). Fix the reported spot and -run `daedalus validate` again to confirm both axes are clean. - -> A pristine `daedalus init` workspace lints clean: the built-in agents that the -> seeded default workflow references count as **known**, so a freshly initialized -> project reports no definition errors. - -## Exit codes - -`validate` sets its exit code so you can gate on it from a script or CI: - -| Exit code | Meaning | -|---|---| -| `0` | The workspace **conforms** — no violations, or only warnings (an optional gap never fails the check). | -| `1` | The workspace has at least one **error** in **either** axis — a convention violation or a definition lint error. | -| `2` | A usage or I/O error (for example, a path that has no `.daedalus/` workspace). | - -A single error in either the conventions or the definitions report is enough to -exit `1`, so gating CI on `daedalus validate` covers both at once. - -## Phase 1: read-only, no agents - -Like the rest of Daedalus in Phase 1, `validate` configures and checks your AI -structure but does not **execute** any agent. It **reads** your workspace and -**reports** how well it follows the team conventions; it never modifies your -files and never auto-fixes a violation. Bringing a workspace into conformance is -a manual edit on your side — and a deterministic one to verify: the same -workspace state always produces the same report, so a clean run today stays clean -until something actually drifts. diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 0000000..3b76e69 --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1,206 @@ +# Quickstart + +This is the whole loop end to end: an empty repo, `daedalus init`, then your first +`/brief` and `/ticket` inside Claude Code. Follow it top to bottom and you will +have shipped one small change the Daedalus way. + +**Prerequisites:** the `daedalus` binary on your `PATH` (see +[Installation](getting-started/installation.md)) and +[Claude Code](https://claude.com/claude-code) installed. Daedalus does not run +agents — it installs the kit Claude Code runs. + +## 1. Start from an empty repo + +```console +$ mkdir printquote && cd printquote +$ git init +Initialized empty Git repository in /home/you/printquote/.git/ +``` + +## 2. Install the kit — flags mode + +If you know your project's basics, pass them as flags and init runs without +prompting: + +```console +$ daedalus init --yes \ + --name printquote \ + --description "Instant 3D-print quotes from an uploaded STL" \ + --stack "Go 1.23 + Charm" \ + --build-cmd "make build" \ + --test-cmd "make test" \ + --lint-cmd "make lint" \ + --chat-language English \ + --attribution none +Initialized Daedalus kit 0.1.0-dev into /home/you/printquote + 31 written, 0 skipped (already present) +``` + +### …or interactive mode + +Prefer to be prompted? Run `daedalus init` with the required values missing and a +form collects them — same result, no flags to remember: + +```console +$ daedalus init +``` + +``` + Project name printquote + One-line description Instant 3D-print quotes from an uploaded STL + Stack Go 1.23 + Charm + + Build command make build + Test command make test + Lint command make lint + + Chat language English + Commit attribution ▸ Keep the tooling's default attribution + No AI attribution (only the git account owner) +``` + +Either way, init writes the constitution, the method, the empty backlog, and the +`.claude/` kit. Confirm it landed cleanly: + +```console +$ daedalus doctor --plain +Daedalus doctor /home/you/printquote + +ok marker present and parses (kit 0.1.0-dev) +ok kit version matches binary (0.1.0-dev) +ok CLAUDE.md present +… +ok ticket specs valid (no ticket specs found) + +Summary: 11 ok, 0 warning(s), 0 failure(s) +``` + +And the map is empty, as expected for a fresh repo: + +```console +$ daedalus status --plain +EPIC PROGRESS STATE + (no epics yet) + +WAITING ON YOU + none +… +NEXT STEP (from STATE.md) + none set +``` + +## 3. Open Claude Code in the repo + +```console +$ claude +``` + +Claude Code loads `CLAUDE.md` (your constitution) and discovers the skills under +`.claude/skills/` — `/brief`, `/spec`, `/council`, `/plan`, `/ticket`, `/epic`, +`/status`. From here the workflow lives inside Claude Code; the shell commands +(`status`, `doctor`, `update`) are for checking in from outside. + +## 4. Your first `/brief` + +`/brief` turns a raw idea or bug report into a structured artifact. It picks a +mode automatically: **quick** for a small, self-evident task (which emits a +ready-to-run ticket straight into `epic-00-inbox`), or **full** for a feature +(which produces a brief you then take through `/spec` and `/plan`). For a first +run, a small task keeps the loop short: + +```text +you › /brief the STL upload endpoint should reject files over 50 MB with a clear + error instead of a 500 + +brief › This is a small, well-scoped change to existing behavior, so I'll run + quick mode. A few questions before I write the ticket: + + 1. How do you reproduce the current 500 today? + 2. What exact response should an over-limit upload get — status code and + message? + 3. Is 50 MB a hard limit, or should it be configurable? + 4. Anything out of scope — e.g. should other endpoints get the same guard? + +you › 1. POST a 60 MB .stl to /upload. 2. 413 with {"error":"file exceeds 50 MB + limit"}. 3. Hard-coded 50 MB is fine for now. 4. Only /upload. + +brief › Ticket ready at + development/epics/epic-00-inbox/tickets/ticket-00-01-upload-size-limit/ + + type: bug · risk: low + AC-1: a test reproducing the 500 on a >50 MB upload exists and passes + AC-2: an over-limit upload returns 413 with {"error":"file exceeds 50 MB limit"} + Out of scope: other endpoints; making the limit configurable + + Next: /ticket ticket-00-01-upload-size-limit to execute it. +``` + +Notice what happened: `/brief` interviewed you until the ambiguity was gone, +wrote a **bug** ticket (so acceptance criterion 1 is automatically "a test +reproducing the defect exists and passes"), and stopped — it does not start the +next phase on its own. The ticket is now real files on disk: + +```console +$ daedalus status --plain +EPIC PROGRESS STATE +epic-00-inbox 0/1 ● active + ○ 00-01 upload-size-limit pending + +WAITING ON YOU + none +… +``` + +## 5. Your first `/ticket` + +`/ticket` runs the execution loop: implement → verify with fresh eyes → fix until +approved → close. You are the orchestrator; the actual code is written by a +sub-agent in a fresh context, and (for a bug) the reproduction test comes first. + +```text +you › /ticket ticket-00-01-upload-size-limit + +ticket › Loaded the ticket (type: bug, risk: low). Marked it in-progress. + + Because risk is low, this runs the lite implementer with hooks + a + mandatory self-check — no separate verifier pass. + + → implementer: wrote a failing test posting a 60 MB payload (reproduces + the 500), then added the size guard returning 413. Tests + lint green. + + Done. Acceptance criteria: + AC-1 ✓ TestUpload_RejectsOverLimit reproduces the old 500, now passes + AC-2 ✓ over-limit upload returns 413 {"error":"file exceeds 50 MB limit"} + + verified: self · one commit staged referencing the ticket. Review the + diff, then confirm and I'll commit. +``` + +The constitution's commit rule holds the workflow at the gate: Claude Code waits +for your explicit go-ahead before `git commit`, and — because you chose +`--attribution none` at init — the commit carries no AI trailers. Confirm, and +the ticket closes: its frontmatter flips to `status: done` with the commit hash, +and `STATE.md` records the completion. + +```console +$ daedalus status --plain +EPIC PROGRESS STATE +epic-00-inbox 1/1 ✔ done + +NEXT STEP (from STATE.md) + none set +``` + +## Where to go from here + +You just ran the method's short path — a bug that skipped spec and planning. The +full path is for features and new products: + +- **[Workflow](workflow.md)** — `/brief` (full mode) → `/spec` → `/council` → + `/plan` → `/ticket` / `/epic`, day to day inside Claude Code. +- **[Backlog](backlog.md)** — the `development/` layout, the ticket folder + contract, and every frontmatter field. +- **[Commands](commands/init.md)** — the full reference for `init`, `status`, + `doctor`, and `update`. +- **[Customization](customization.md)** — template variables, per-repo overrides, + and the attribution option. diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md new file mode 100644 index 0000000..829d3ef --- /dev/null +++ b/docs/troubleshooting.md @@ -0,0 +1,199 @@ +# Troubleshooting + +Most problems surface through [`daedalus doctor`](commands/doctor.md), so start +there. This chapter maps its exit codes and the common failures to fixes, and +explains how re-`init` and `update` behave when you need to recover. + +## Doctor exit codes + +`doctor` maps the **worst** check to its exit code — the contract for scripting it +in CI: + +| Exit | Meaning | What to do | +| --- | --- | --- | +| `0` | Every check passed. | Nothing. | +| `1` | Worst result is a **warning** (kit-version drift). | Run `daedalus update`. | +| `2` | At least one check **failed**, or a usage error. | Read the failing line(s) below. | + +A gate for CI: + +```sh +daedalus doctor --plain || echo "kit needs attention (exit $?)" +``` + +## "No kit installed" / not a Daedalus kit + +**Symptom.** Commands complain the directory isn't a kit: + +```console +$ daedalus status +status: no Daedalus kit found in /home/you/project + expected development/STATE.md — run `daedalus init` first. + +$ daedalus update +update: /home/you/project is not a Daedalus kit (no .claude/daedalus-kit.yaml). Run `daedalus init` first. +``` + +`doctor` shows the same story as a cascade of `fail` lines starting with `marker +present and parses (.claude/daedalus-kit.yaml not found …)`. + +**Cause.** You're in the wrong directory, or the repo was never initialized. + +**Fix.** `cd` to the repo root (the one that should hold `.claude/` and +`development/`), or run `daedalus init` to create the kit. Both `status` (exit 1) +and `update`/`doctor` (exit 2) are telling you the marker is missing — the marker, +`.claude/daedalus-kit.yaml`, is what makes a directory a Daedalus kit. + +## Corrupted or invalid ticket frontmatter + +**Symptom.** `doctor`'s last check fails: + +```console +fail ticket specs valid (7 checked, 1 issue(s): ticket-02-03-pricing: invalid status "in progress") +``` + +Other forms of the same failure: + +- `ticket-…: no YAML frontmatter` — the spec lost its leading `---` block. +- `ticket-…: missing status` (or `type`/`risk`/`gate`) — a required enum field is + blank or absent. +- `ticket-…: invalid gate "manual pending"` — a value outside the allowed set + (usually a space where a hyphen belongs). + +**Cause.** A hand-edit that broke the frontmatter — a typo in an enum, a deleted +`---`, or a value with the wrong separator. + +**Fix.** Open the named `spec.md` and restore valid frontmatter. The allowed +values (see [Backlog](backlog.md)): + +```yaml +--- +id: ticket-02-03-pricing +status: pending # pending | in-progress | done | blocked +type: feature # feature | bug | chore +risk: normal # low | normal | high +commit: null +verified: null +gate: none # none | manual-pending | manual-approved +--- +``` + +Re-run `daedalus doctor` — the check should turn green. `status` tolerates +malformed frontmatter more quietly (it defaults an unreadable `status` to +`pending`), so `doctor` is the tool that actually pins the problem down. + +## `STATE.md` out of sync with the backlog + +**Symptom.** `status` prints an `INCONSISTENCIES` section: + +``` +INCONSISTENCIES + ⚠ ticket-02-02-parsing is done but has no commit + ⚠ STATE's active ticket ticket-02-05-quote-ui is already done +``` + +**Cause.** A manual edit moved a ticket's state without updating `STATE.md`, or +vice versa. + +**Fix.** These are **reported, never auto-fixed**. Reconcile by hand — set the +missing `commit`, or point `STATE.md`'s active ticket at the real next one — or +ask Claude Code's `/status` to correct `STATE.md` after you confirm. Nothing here +blocks work; it's a nudge to keep disk truthful. + +## Version drift + +**Symptom.** `doctor` warns (exit 1): + +```console +warn kit version matches binary (kit 0.0.9-dev, binary 0.1.0-dev — run `daedalus update`) +``` + +**Cause.** You upgraded the `daedalus` binary; the installed kit still records the +older version. + +**Fix.** Preview, then apply: + +```console +$ daedalus update --dry-run +Dry run for Daedalus kit 0.0.9-dev -> 0.1.0-dev in /home/you/printquote + 0 file(s) would change, 28 unchanged + +$ daedalus update +Updated Daedalus kit 0.0.9-dev -> 0.1.0-dev in /home/you/printquote + 0 updated, 28 unchanged +``` + +`0 would change` here means the kit content is identical between versions — only +the marker stamp is refreshed. When files do differ, update lists each `would +update:` / `updated:` and writes a backup (next section). + +## Missing kit files after an update, or wanting to undo one + +**Symptom.** After `update`, a managed file you had edited looks different, or a +file is reported `updated:`. + +**Cause.** `update` overwrites managed kit files whose content differs from the kit +— including your local edits to them. It backs up what it replaced first: + +```console +$ daedalus update +Updated Daedalus kit 0.0.9-dev -> 0.1.0-dev in /home/you/printquote + 1 updated, 27 unchanged + updated: .claude/skills/status/SKILL.md + backup: .claude/.backup-0.0.9-dev/ +``` + +**Fix / recover.** Your previous copy is under +`.claude/.backup-/`, at the same relative path: + +``` +.claude/.backup-0.0.9-dev/.claude/skills/status/SKILL.md +.claude/.backup-0.0.9-dev/.claude/daedalus-kit.yaml +``` + +Copy it back if you need it. To keep such changes permanently, move them to a +durable surface — the constitution or your own added files — as described in +[Customization](customization.md); editing kit-shipped files loses to every +`update`. + +## How re-`init` behaves (it won't clobber anything) + +Re-running `init` on an existing kit is safe by construction: it only **adds** +missing files and **skips** everything present. + +```console +$ daedalus init --yes --name printquote --description "…" --stack "…" \ + --build-cmd "make build" --test-cmd "make test" --lint-cmd "make lint" +Initialized Daedalus kit 0.1.0-dev into /home/you/printquote + 0 written, 31 skipped (already present) + skipped: .claude/agents/analyst.md + … +``` + +Use this to **restore accidentally deleted kit files** — delete a file, re-run +`init`, and only that file is rewritten. Note the flip side: because `init` never +overwrites, it will **not** refresh a stale file to a newer version. Deliberately +delete the stale file first and re-`init`, or (for a version bump across the whole +kit) use `update`. + +## The constitution changed upstream + +**Symptom.** `update` appends: + +``` + constitution template changed upstream — review manually +``` + +**Cause.** Your `CLAUDE.md` no longer matches what the current template renders — +either you edited it (expected) or the template changed in a newer kit. + +**Fix.** Update never rewrites `CLAUDE.md`. Diff yours against +`kit/constitution/CLAUDE.md.tmpl` (with your marker's variables applied) and merge +by hand whatever upstream change you want. Your edits are safe; this is only a +heads-up. + +## See also + +- [`daedalus doctor`](commands/doctor.md) — the full check list and outputs. +- [Backlog](backlog.md) — valid frontmatter values. +- [Customization](customization.md) — durable overrides vs. what update reverts. diff --git a/docs/workflow.md b/docs/workflow.md new file mode 100644 index 0000000..feb5891 --- /dev/null +++ b/docs/workflow.md @@ -0,0 +1,224 @@ +# Workflow + +This is the day-to-day loop inside Claude Code. The `daedalus` binary set up the +repo; from here you drive everything with the seven skills the kit installed. The +lifecycle is: + +``` +IDEA ──► SPEC ──► DESIGN ──► PLAN ──► EXECUTE (per ticket) ──► SHIP +/brief /spec /council /plan /ticket · /epic +``` + +**The method scales down.** A bug or a small task skips SPEC, DESIGN, and PLAN +entirely: `/brief` in quick mode emits a ticket straight into `epic-00-inbox`, and +`/ticket` runs it. The full chain below is for new features and products — never a +tax on small work. `/status` works at any point. + +Two rules hold throughout: **artifacts on disk are the only source of truth** +(any session can be killed and the next resumes from `development/`), and **humans +decide, agents inform** — design choices, manual gates, and commits are yours. + +## `/brief` — idea to structured artifact + +`/brief` interviews you until the ambiguity is gone, then writes an artifact. It +never proposes solutions during the interview and never invents facts you didn't +state. It picks a mode: + +- **Full mode** (new feature/product) → a brief at `development/briefs/NN-.md`. + It asks in batches of ≤4 questions covering intent, desired behavior, + constraints, non-goals, and success — and explicitly probes for non-goals, + which users rarely volunteer. Anything still open after ~3 rounds lands in the + brief's *Open questions* rather than a guess. +- **Quick mode** (bug / small task) → a ready-to-run ticket in `epic-00-inbox`. + For a bug, acceptance criterion 1 is always "a test reproducing the defect + exists and passes." + +```text +you › /brief we need per-customer volume discounts on quotes + +brief › New feature — running full mode. First batch: + 1. Who sets the discount tiers — an admin UI, config, or hard-coded? + 2. Is a discount a % off, a fixed amount, or a price-per-unit override? + 3. Does it stack with any existing promo, or is it exclusive? + 4. What is explicitly NOT in scope for this first cut? + … + Brief ready at development/briefs/01-volume-discounts.md. + Next: /spec to derive verifiable requirements. +``` + +`/brief` stops there — it does not start `/spec` for you. + +## `/spec` — brief to verifiable requirements + +`/spec` turns an approved brief into a spec where **every requirement carries at +least one verifiable acceptance criterion** — a runnable command, an observable +behavior, or a measurable value. Drafting is delegated to the analyst agent; you +only see its summary and any new open questions, which you resolve before the spec +is final. + +The spec is the contract for everything downstream: what is not in the spec does +not get built. `/spec` also surfaces a *Decisions needed* list — every +expensive-to-reverse choice (architecture, stack, public API shape, data model) +it refuses to silently resolve inside a requirement. + +```text +you › /spec + +spec › Drafted from 01-volume-discounts.md via the analyst. 6 requirements, all + with acceptance criteria. Two open questions came back — answer these and + I'll finalize: + · Do discounts apply before or after tax? + · Is the tier table per-customer or shared across a customer group? + +you › Before tax. Per-customer for now. + +spec › Spec written to development/specs/01-volume-discounts.md. + Decisions needed: [pricing-engine placement]. + Run /council on that before /plan — planning against an unmade decision + produces rework. +``` + +## `/council` — de-bias an expensive decision + +A council runs 3–5 perspectives **in parallel and blind to each other** +(pragmatist, maintainer, adversary, user — plus a domain lens when warranted), +then a synthesizer merges them into an ADR-style `DECISION-NN.md` that +**preserves the disagreements**. You decide; the council only prepares the +decision. + +### When NOT to use it + +This is the part people get wrong. A council is the method's only sanctioned +parallel burst, and it is expensive. Use it **only** for choices that would cost +days of rework or a migration to reverse: architecture, stack selection, +API/schema design, data models, security posture. + +Do **not** convene a council for: + +- **implementation-level questions** — that quality is owned by the `/ticket` + verifier loop, not a council; +- naming, internal structure, or any choice a single ticket can absorb and change + later; +- a question already constrained by a recorded `DECISION` — surface the conflict + instead. + +A typical project runs a council **2–3 times in its whole lifetime**. If you are +reaching for it weekly, ceremony has leaked into routine work. `/council` itself +gates the invocation and will tell you when it is overkill: + +```text +you › /council should the discount field be a float or a decimal type? + +council › That's an implementation choice a single ticket can make and revise — + a council is overkill here. Use a decimal for money to avoid float + rounding, note it in the ticket, and move on. Save councils for + decisions that are expensive to reverse. +``` + +## `/plan` — spec to executable backlog + +`/plan` decomposes an approved spec into epics and tickets via the planner agent. +It is **strictly additive** over the existing backlog — it never renumbers or +rewrites existing epics, and never touches `done` tickets. If the spec still lists +unresolved *Decisions needed* (or references a `DECISION` still `proposed`), +`/plan` stops and points you at `/council` first. + +You review the plan as markdown on disk and can edit, reorder, or delete tickets +by hand before executing. + +```text +you › /plan + +plan › Planned via the planner. 1 epic, 5 tickets: + + epic-03-volume-discounts — apply per-customer volume discounts to quotes + 03-01 discount-tier-model R-1, R-2 + 03-02 discount-engine R-3 + 03-03 apply-to-quote R-3, R-4 + 03-04 admin-tier-editor R-5 · manual gate + 03-05 e2e-discount-flow R-6 · manual gate + + Dependency order is 01→05. Manual gates on 04 and 05. + This is markdown under development/epics/ — edit or reorder before running. + Next: /epic epic-03-volume-discounts (or /ticket ticket-03-01-…). +``` + +## `/ticket` — the execution loop + +`/ticket` runs one ticket end to end. You are the **orchestrator**: you sequence +the loop and keep state true, but you do not write product code — the implementer +does, in a fresh context. The loop is verification-proportional to the ticket's +`risk` frontmatter: + +1. **Load** the ticket; refuse to start if it is already `done`, gated, or has + malformed frontmatter. Mark it `in-progress`. +2. **Research** (only if it touches unfamiliar code or an external library). +3. **Implement** — `implementer-lite` for `risk: low`, the full `implementer` + otherwise. For a **bug**, a failing reproduction test comes first: no + reproduction, no fix. +4. **Verify** — `risk: low` skips the verifier (hooks + the implementer's + self-check suffice, recorded as `verified: self`); `normal`/`high` spawn a + **verifier** in fresh context that tries to *refute* completion. +5. **Fix loop** — on REJECTED, findings go to `observations.md` and the + implementer fixes from that document only. If the same finding fails twice, it + escalates to you rather than looping. +6. **Close** — commit (after your confirmation), flip frontmatter to `done` with + the commit hash, update `STATE.md`, record any durable lesson. +7. **Gate** — if the ticket has a `manual-validation.md`, set `gate: + manual-pending` and **stop** until you approve. + +```text +you › /ticket ticket-03-02-discount-engine + +ticket › Loaded (feature, risk: normal). in-progress. + → implementer: added the discount engine per R-3. Tests + lint green. + → verifier (fresh context): executed validation.md, all checks pass. + APPROVED in 1 round. + AC-1 ✓ … AC-2 ✓ … AC-3 ✓ + Commit staged referencing the ticket — confirm to commit. +``` + +## `/epic` — run an epic in order + +`/epic` runs an epic's tickets in `MM` order through the same `/ticket` loop, +re-reading `STATE.md` between tickets as its re-anchor. It skips `done` tickets +silently (so it is resumable), and **hard-stops** at a manual gate, a blocked +ticket, an escalation, or your interrupt. One ticket = one commit; documentation +batches into a single documenter pass at epic close. + +```text +you › /epic epic-03-volume-discounts + +epic › 5 tickets, 03-01 pending first, manual gates on 03-04 and 03-05. + 03-01 discount-tier-model … done (a1b2c3d) + 03-02 discount-engine … done (d4e5f6a) + 03-03 apply-to-quote … done (b7c8d9e) + 03-04 admin-tier-editor … done — MANUAL GATE reached. + + Stopping. Test the tier editor per its manual-validation.md, then say + "approved" and I'll continue with 03-05. +``` + +## `/status` — the map, any time + +`/status` renders the work map from disk — epics, ticket states, pending gates, +blockers, next step — with zero sub-agents and zero writes. It is the same view +as the shell's [`daedalus status`](commands/status.md); use whichever is at hand. +Its one permitted write is correcting a drifted `STATE.md`, and only after you +confirm. + +## The shape of a session + +- **Start every session by reading `STATE.md`** (the constitution makes Claude + Code do this) — disk is the truth, not conversation memory. +- **Manual gates block the whole chain** until you approve — no exceptions. +- **Commits wait for your explicit confirmation** and never carry AI attribution + when you chose `--attribution none`. +- A degraded, over-long session is worse than a clean handoff: `STATE.md` + + frontmatter make resuming in a fresh session lossless. + +## See also + +- [Backlog](backlog.md) — the artifacts these skills read and write. +- [`kit/METHOD.md`](https://github.com/Codigo-de-Altura/Daedalus/blob/main/kit/METHOD.md) — the full normative standard behind every + skill above. diff --git a/kit/METHOD.md b/kit/METHOD.md index 3a2865f..3630c50 100644 --- a/kit/METHOD.md +++ b/kit/METHOD.md @@ -79,10 +79,12 @@ Workspace layout installed by the kit: ```yaml --- +id: ticket-NN-MM- status: pending | in-progress | done | blocked type: feature | bug | chore +risk: low | normal | high commit: -verified: +verified: gate: none | manual-pending | manual-approved --- ``` diff --git a/web/index.html b/web/index.html index c38686c..fd51a4d 100644 --- a/web/index.html +++ b/web/index.html @@ -1,27 +1,24 @@ - + - - - Daedalus — Build your AI scaffolding once. Compile it anywhere. + + + Daedalus — An AI engineering method, installed in one command - - - - +