# 0.6.0 — Discovery + milestones: the full lifecycle

The release that turns Wonderland from a tool you bring your own
context to into one that **carries the project across sessions.**
Two new pre-design phases ship together:

- **Discovery** — three operator interviews (Alice on personas,
  Cheshire Cat on constraints, White Rabbit on scope) capture
  intent once as structured `requirement` artifacts on disk.
  Wall-clock unbounded; ~12 minutes of operator attention. Every
  later workflow seeds from this corpus rather than re-asking what
  the project is for.
- **Planning** — the `milestone-plan` workflow organizes captured
  requirements into a 3–7 milestone trajectory. Coverage closes
  at the end of each rotation: any decomposable requirement not
  consumed by a milestone fires a synthetic Dodo observation
  nudging the team to revise.

Per-milestone design uses `tdd-design --milestone <slug>`, with
its own coverage check on M2 verifying every milestone requirement
is realized by a feature. The dashboard derives the current phase
from disk and surfaces the next workflow as a one-line CTA, so an
operator returning after a week sees what's next without
re-orienting.

Plus a substrate-level **retract primitive** that lets agents walk
back off-scope artifacts, a workflow-level kill-list that blocks
speech_act leakage between phases, and update-by-slug semantics
across every registry so re-emitted artifacts converge on one disk
file instead of N.

### Discovery (P14)

- New `Interview` abstraction sibling to `Meeting` in `Workflow`. YAML can declare `interviews:` alongside `meetings:` and the runtime executes interviews first, in declaration order.
- `RequirementRegistry` lives at `.wonderland/requirements/requirement-NNN-slug.md`. Eight requirement kinds: `persona` / `situation` / `constraint` / `integration` / `scope` / `success_criterion` / `out_of_scope` / `deal_breaker`. Each carries a `confidence` flag (`operator_stated` vs `interviewer_inferred`) for downstream provenance dispatch.
- Disk-mediated operator bridge: `pending_interview.json` → operator fills the modal → `pending_interview_answers.json`. Wall-clock unbounded (1-hour timeout), no rotation-budget burn while the operator's away. `batch_id` per round disambiguates follow-up answers from stale prior rounds.
- Alice / Cheshire Cat / White Rabbit each pick up an additive `interview_review` decision mode + `requirements` + `followup_questions` fields. The substrate writes the YAML's questions directly to the bridge (no agent turn needed for the question batch); the agent only runs to synthesize answers into requirements + optionally ship one follow-up batch. Cap of 3 rounds per interview.
- `InterviewModal` TUI screen renders one widget per question kind (TextArea / RadioSet / Checkbox group / numeric Input) with a free-response escape on every field. Submit / Skip-section / Cancel exits; required-field validation surfaces a notification instead of dismissing. App-side `_poll_interviews_for_background_run` poller mirrors the existing question-bridge shape, runs in parallel with it.
- `closet/workflows/discovery.yaml`: three-interview flow (I1 Alice on personas, I2 Cat on constraints, I3 Rabbit on scope), ~12 questions, ~12 min of operator attention. Category: `discovery`, budget $1.50. Added an `access_model` question to I3 after the discovery3 pilot shipped a milestone plan that skipped registration / login / onboarding entirely — "we'll add auth later" is the common omission the new required question catches.

### Milestones (P15)

- New `milestone_plan` decision mode on Alice / Cat / Rabbit. Each constitution's `_OUTPUT_PROTOCOL` now opens with a "meeting type determines your primary decision" rule, mapping `milestone-plan` → `milestone_plan`, `tdd-design` M1 → `story`, etc. Constitutional prior pinned at the protocol layer so convenor directives don't have to fight it on every turn.
- `MilestoneRegistry` lives at `.wonderland/milestones/milestone-NN-slug.md`. Each milestone carries goal, done-when criteria, order, deferred flag, and a `consumes_requirements:` slug list. Update-by-slug semantics so re-running milestone-plan against an existing corpus refines rather than duplicates.
- `closet/workflows/milestone-plan.yaml`: single-phase deliberation. Directive enforces coverage discipline — every discovery requirement must have a milestone home; personas + cross-cutting requirements can appear in multiple milestones.
- Substrate-level `Meeting.allowed_decisions` guardrail (T-m6): a meeting can declare which speech_acts it accepts; artifacts off that list get silently stripped from utterances + deleted from disk before publish. Catches cross-meeting stage-leaks like Rabbit's M2/M3 priors shipping tickets during `milestone-plan`. Emits an `ArtifactSuppressed` observer event.
- `wonderland run-bg --milestone <slug>` scopes a design or implementation run to one milestone. `run_workflow` resolves the slug via `MilestoneRegistry`, prepends the milestone's goal + done-when to the entry meeting's directive, and a module-level scope narrows `resolve_seeds` so requirement-kind seeds outside the milestone's `consumes_requirements` get filtered before they reach M1.
- `tdd-design.yaml` M1 now pulls `requirement` artifacts (the discovery output) into the story-generation pool. With a milestone scope active, only that milestone's slice shows up.

### Closed-loop coverage checks

- **Requirement coverage (T-m8a):** at the end of every milestone-plan rotation the substrate computes which decomposable requirements aren't consumed by any milestone, injects a synthetic Dodo observation listing the gaps + grants a bonus rotation so agents can revise. Bonus rotations are capped (`Meeting.coverage_max_extra_rotations`, default 2) so the phase can't loop indefinitely. Personas, situations, out-of-scope, and deal-breakers are exempt — they're background context, not buildable units.
- **Feature realization (T-m8b):** same pattern at M2's commit phase. Walks `milestone.consumes_requirements → stories whose realizes_requirements includes the slug → features sourcing those stories`. Gap → Dodo observation + bonus rotation. New `StoryPayload.realizes_requirements` field; Alice's and Caterpillar's M1 protocols updated to populate it. The coverage hook also clears `state.exit_condition_met` when a gap exists so M2's "exit on first feature shipped" doesn't short-circuit the loop.
- New `coverage` module owns the check registry + helpers. New `PhaseSpec.coverage_check` field. New `coverage_gap` artifact kind rides on the observation so the live-watch / dashboard can render the deficit.

### Retract primitive (T-m7)

- New `RETRACT` speech_act + `retraction` artifact `{target_kind, target_slug, reason}`. The substrate unlinks the targeted file via the matching registry, records (kind, slug) in a module-level run-scoped set, and `resolve_seeds` filters retracted artifacts from every downstream meeting's seed pool.
- Available on Caterpillar (primary scope-violation catcher) and Alice (self-correction). Emits an `ArtifactRetracted` observer event.
- Generic over kinds — works for stories / features / tickets / ADRs / milestones / requirements.
- Caterpillar's M2 protocol opens with an explicit trace-to-M1 procedure: list every feature, verify each persona it names appears in an M1 story, retract any feature naming a persona / problem-domain not in seeds.

### Anti-bleed guards

- **Workflow-level `disallowed_decisions`** — new `Workflow.disallowed_decisions: list[str] | None` field declares speech_acts that are NEVER valid in a workflow. `tdd-design.yaml` declares `[milestone_plan, interview_questions, interview_review]` so a stray Rabbit `milestone_plan` utterance during design can't clobber the milestone registry (discovery4 pilot caught Rabbit overwriting M1's consumes with invented slugs mid-design).
- **Source resolution check** — substrate hook strips ticket / feature artifacts whose `sources` slugs don't resolve to real story or feature files on disk. The `TicketPayload.sources` validator's known-bad-prefix block was necessary but not sufficient.
- **Seeded-personas whitelist** — `_prepend_milestone_framing` reads `persona`-kind requirements from disk + renders an exhaustive bullet list of valid persona titles into the directive prepend. Catches drift like Marcus → Alex / Priya / Maya.
- **`FeaturePayload.sources` required** — features without source stories are unmoored claims; validator catches at parse time so Rabbit's retry loop fixes it.

### Update-by-slug semantics across every registry

Previously, `StoryRegistry` / `FeatureRegistry` / `TicketRegistry` / `ADRRegistry` always allocated a new number on every write, so re-emitting the same artifact across rotations produced duplicate files with identical slug components (discovery5 pilot: 8 story files for 4 conceptual stories). `MilestoneRegistry` has had update-by-slug since the milestone substrate first shipped; this aligns the design-time registries with the planning registry's dedup shape. Re-emit with the same slug now overwrites in place; new slug appends.

### Dashboard milestone surfacing (T-m5)

- **Top row is Milestones (left) + Features (right) at 50/50.** Milestones render as a tree: each milestone is a parent node carrying its title + req/feature counts, with its `consumes_requirements` as collapsible children. Selecting a milestone filters the Features pane via the realization chain. Lifecycle state chips (designed / queued / in_progress / verified / rejected) stack with the milestone filter.
- **Milestones detail pane** mirrors Features' list+detail+button shape. The "Design milestone: <slug>" CTA sits at the bottom of the detail pane, surfaced when the highlighted milestone has zero realizing features.
- **Cross-cutting requirements node** at the bottom of the tree lists persona / situation / out-of-scope reqs that don't belong to any specific milestone — full corpus accountable at a glance.
- **Requirement detail in the milestones detail pane** — highlighting a requirement leaf (under a milestone or under cross-cutting) renders its body in the right pane without disturbing the features filter.
- **Phase-aware CTAs.** DISCOVERY → "Run discovery" button replaces the empty tree. PLANNING → "Run milestone-plan". When orphan requirements exist with milestones already planned, a warning hint sits above the tree.
- **Runs row** moved below — always-visible history reference; Milestones+Features is the primary navigation surface up top.

### Project lifecycle phase + flow-ordered workflow picker

- **Phase badge** at the top of the dashboard derives the project's current state (`DISCOVERY` / `PLANNING` / `DESIGN — Milestone N` / `IMPLEMENTATION` / `COMPLETE`) from disk every refresh + names the next recommended workflow.
- **Flow-ordered workflow picker** in the new-run screen: categories now sort `discovery` → `planning` → `design` → `implementation` (instead of alphabetical, which used to put `design` ahead of `discovery`). Tail categories (`utility` / `smoke` / `legacy` / `other`) land below the flow band. Shared `category_sort_key` helper.

### NewProjectScreen overhaul

- Dropped the "Initial workflow" Select — workflow choice is per-run, putting it in the create form was a holdover.
- New **Prime directive** row mirroring NewRunScreen's directive composer, scoped to demo-category presets. Demo picker on the left + TextArea on the right. Saves to `Project.prime_directive` on submit.
- **StartDiscoveryModal** pushes after the project registers, recommending "Yes, start discovery" as the natural first move. On Yes, the discovery workflow launches directly via `launch_background_run` (skipping NewRunScreen entirely) with the prime directive + a $3.50 budget.

### Tooling + tests

- New `ToolSearch`-style smoke verification + the coverage module's check registry plug in cleanly for new checks.
- 600+ tests covering the discovery substrate, milestone registry, coverage walk, retract primitive, source-resolution filter, allowed/disallowed decisions, project phase derivation, update-by-slug semantics.

### Migration notes

- The 0.5.4 hotfix branch is rolled into this cut. No further hotfix backport needed.
- Existing projects on disk: no migration required. Discovery / milestone / planning artifacts are additive directories — the substrate falls back to legacy behavior when those directories are empty. To adopt the lifecycle on an existing project, run `discovery` first, then `milestone-plan`, then per-milestone `tdd-design`.
- `Workflow.description` is still required by Pydantic — same as 0.5.x. Custom workflow YAMLs need a description field if you're loading them via `Workflow.model_validate`.
