wish — Plan Before You Build
Runtime syntax: invoke the plugin copy through the active runtime's owner-qualified skill selector; use a bare selector only when intentionally selecting a user-tier copy (a separately installed personal copy; Genie no longer seeds this tier). Cross-skill prose below uses bare names as portable semantic routes; the orchestrator resolves the selector for the active runtime.
Convert a validated idea into an executable wish document at .genie/wishes/<slug>/WISH.md.
When to Use
- Non-trivial work needs planning before implementation.
- User wants to scope, decompose, or formalize a feature/change.
- Prior
brainstorm output exists and needs to become actionable.
Wish artifacts live in .genie/wishes/ in the shared worktree. Execution-group definitions go in WISH.md (git) so other agents and skills can read them; per-group execution state lives in the state DB via genie task (see the work skill for how groups are claimed and completed). When spawned as a native subagent, use the curated context from your dispatch prompt directly.
Design link pre-flight
Before writing the wish, check the design exists and, when present, verify the
review evidence with the helper shipped in this skill:
test -f .genie/brainstorms/<slug>/DESIGN.md
node "<wish-skill-dir>/references/design-review-evidence.mjs" verify ".genie/brainstorms/<slug>/DESIGN.md"
- Present and verification exits 0: consume the reviewer-bound evidence and emit
| **Design** | [DESIGN.md](../../brainstorms/<slug>/DESIGN.md) |.
- Present but verification fails: stop and return to design review. Missing evidence, a non-SHIP verdict, or a content-digest mismatch cannot be waived; editing DESIGN.md invalidates its prior review. Never repair the failure with a locally recomputed digest — only a new design review may return the
reviewed-sha256 passed to stamping.
- Absent: emit
| **Design** | _No brainstorm — direct wish_ | (no link) — valid for hotfixes, trivial changes, or plans obvious enough that a brainstorm adds no value. The linter (scripts/wishes-lint.ts) accepts the literal stub text; a bracket-link to a non-existent brainstorm file fails lint.
Flow
Gate check: if the request is fuzzy (no prior design, unclear scope, vague requirements), run brainstorm first and say so. If a design exists, do not scaffold until its digest-bound design-review evidence verifies as SHIP.
Align intent: clarify until success criteria are testable.
Pass the simplicity gate: state the simplest complete design, justify every mechanism beyond it with a present requirement or measurement, and defer plausible future complexity behind a concrete trigger. A wish cannot outsource this decision to implementation.
Define scope: explicit IN and OUT lists. OUT cannot be empty.
Decompose: small, loosely coupled execution groups.
Scaffold — always copy the template, never hand-write WISH.md. Resolve
the absolute directory containing this loaded SKILL.md, replace only the
two placeholder assignments below, and run the complete command from the
repository root:
WISH_SKILL_DIR='<absolute directory containing this SKILL.md>'
WISH_SLUG='<slug>'
case "$WISH_SLUG" in
''|*[!a-z0-9-]*|-*|*-) printf 'invalid wish slug: %s\n' "$WISH_SLUG" >&2; exit 2 ;;
esac
WISH_DEST=".genie/wishes/$WISH_SLUG/WISH.md"
test -f "$WISH_SKILL_DIR/templates/wish-template.md"
test ! -e "$WISH_DEST"
mkdir -p "$(dirname "$WISH_DEST")"
cp "$WISH_SKILL_DIR/templates/wish-template.md" "$WISH_DEST"
The template ships inside this skill as the single source of truth for wish structure — a plain document, no runtime scaffolder. Copying guarantees the skeleton the parser and linter expect; ad-hoc wishes regularly fail structural lint.
Fill: replace the {{slug}}/{{date}} tokens and every <TODO: …> marker with real content. Every group gets
acceptance criteria plus a non-zero validation command proportional to the planned diff's risk and reach. Start with
the narrowest checks that can disprove the changed behavior or contract: documentation-only groups, including
deterministic generated documentation or plugin skill mirrors, use relevant format, link, example, generator, parity,
or content-contract checks; runtime groups use focused behavior tests and add type, lint, or build checks only for
boundaries they reach. Escalate shared runtime/core behavior, dependency or lockfile, generated executable or runtime
artifact, configuration or schema, CI or release, broad-refactor, or uncertain-impact groups to the repository full
gate plus affected build or end-to-end checks. State why the command scope fits; a repository-documented
gate is by itself sufficient justification for its scope. Preserve any repository-defined aggregate integration or
release gate separately from per-group validation.
Declare dependencies: use the wish-level ## Dependencies keys
**depends-on:** <comma-separated slugs or none> and
**blocks:** <comma-separated slugs or none> for cross-wish edges. Keep
per-group **depends-on:** fields under each execution group. The spelling
is always hyphenated; the DAG is a machine-readable planning artifact in git.
Create tasks — one per execution group, so work can claim and complete each group and the board reflects progress:
genie task create --title "<group title>" --wish <slug> --group <group-name>
genie task list --wish <slug> # inspect what was created
Tasks carry the --wish/--group linkage; the dependency DAG stays in the WISH.md document, not in task rows. If creation fails (no .genie/genie.db yet, CLI unavailable), warn and continue — WISH.md in git is the source of truth and must remain usable by work without task rows.
Handoff: run the wish linter — inside the genie repo, grep -q '"wishes:lint"' package.json 2>/dev/null && bun run wishes:lint. If it reports any error, surface it and stop — never hand a structurally broken wish onward. Only after lint passes, auto-invoke review (plan review) on the WISH.md. Never suggest work directly — the review gate comes first.
Persist the verdict: the reviewer only returns evidence. The invoking orchestrator appends that evidence under ## Review Results and sets the WISH status to APPROVED on SHIP, FIX-FIRST on FIX-FIRST, or BLOCKED on BLOCKED. Do not route to work until the APPROVED status is on disk.
Record the wave base (APPROVED only): once the status on disk is APPROVED, run genie context --wish <slug> from the repository root. This non---plan resolution pins the integration base SHA as the wish's wave base — every group spawn cuts its worktree from that one SHA. A later run returns the recorded SHA; genie context --wish <slug> --re-resolve refreshes it. Never use --plan for this step: the preview writes nothing, so it cannot record the base. If the command fails (genie CLI or state DB unavailable — an empty ready-task set is NOT a failure; the base is still recorded and returned), warn and continue — the first non-plan resolution or the first spawn --wish records the base instead.
Wish Document Sections
| Section |
Required |
Notes |
| Status / Slug / Date |
Yes |
Status: DRAFT on creation |
| Summary |
Yes |
2-3 sentences: what and why |
| Scope IN / OUT |
Yes |
OUT cannot be empty |
| Decisions |
Yes |
Key choices with rationale |
| Simplicity Case |
Yes |
Simplest complete design, justified additions, and measurable deferrals |
| Success Criteria |
Yes |
Checkboxes, each testable |
| Execution Strategy |
Yes |
Wave-based plan — mandatory even if a single sequential wave; forces ordering, parallelism, and dependency thinking upfront |
| Execution Groups |
Yes |
Goal, deliverables, acceptance criteria, validation command |
| Dependencies |
Yes |
Wish-level depends-on / blocks using slug or repo/slug; use none when empty |
| QA Criteria |
No |
What to verify on dev after merge |
| Assumptions / Risks |
No |
What could invalidate the plan |
Rules
- Never write WISH.md from scratch — always copy the in-skill template, then edit.
- Lint before handoff: the genie repo's wish linter must pass before
review sees the wish.
- Never emit a bracket-link to a non-existent brainstorm — use the
_No brainstorm — direct wish_ stub.
- Never consume a linked design whose persisted review evidence is missing, non-SHIP, or stale; the wish linter independently enforces this for new wishes.
- No implementation during
wish — planning only.
- On APPROVED, record the wave base with the non-
--plan genie context --wish <slug> (warn and continue on failure; never --plan).
- No speculative optimization: caches, deltas, sharding, background coordination, and configuration surfaces require a current criterion or measurement in the Simplicity Case.
- Every group testable, bite-sized, and independently shippable; no vague tasks ("improve everything").
- Every group has non-zero, risk-proportional validation with its scope explained; aggregate integration and release
gates remain intact.
- OUT scope must contain at least one concrete exclusion.
- Declare cross-wish dependencies early.
1---2name: wish3description: Convert an idea into a structured wish plan with scope, acceptance criteria, and execution groups for work.4---56# wish — Plan Before You Build78**Runtime syntax:** invoke the plugin copy through the active runtime's owner-qualified skill selector; use a bare selector only when intentionally selecting a user-tier copy (a separately installed personal copy; Genie no longer seeds this tier). Cross-skill prose below uses bare names as portable semantic routes; the orchestrator resolves the selector for the active runtime.910Convert a validated idea into an executable wish document at `.genie/wishes/<slug>/WISH.md`.1112## When to Use13- Non-trivial work needs planning before implementation.14- User wants to scope, decompose, or formalize a feature/change.15- Prior `brainstorm` output exists and needs to become actionable.1617Wish artifacts live in `.genie/wishes/` in the shared worktree. Execution-group definitions go in WISH.md (git) so other agents and skills can read them; per-group execution state lives in the state DB via `genie task` (see the `work` skill for how groups are claimed and completed). When spawned as a native subagent, use the curated context from your dispatch prompt directly.1819## Design link pre-flight2021Before writing the wish, check the design exists and, when present, verify the22review evidence with the helper shipped in this skill:2324```bash25test -f .genie/brainstorms/<slug>/DESIGN.md26node "<wish-skill-dir>/references/design-review-evidence.mjs" verify ".genie/brainstorms/<slug>/DESIGN.md"27```2829- **Present and verification exits 0:** consume the reviewer-bound evidence and emit `| **Design** | [DESIGN.md](../../brainstorms/<slug>/DESIGN.md) |`.30- **Present but verification fails:** stop and return to design review. Missing evidence, a non-SHIP verdict, or a content-digest mismatch cannot be waived; editing DESIGN.md invalidates its prior review. Never repair the failure with a locally recomputed digest — only a new design review may return the `reviewed-sha256` passed to stamping.31- **Absent:** emit `| **Design** | _No brainstorm — direct wish_ |` (no link) — valid for hotfixes, trivial changes, or plans obvious enough that a brainstorm adds no value. The linter (`scripts/wishes-lint.ts`) accepts the literal stub text; a bracket-link to a non-existent brainstorm file fails lint.3233## Flow341. **Gate check:** if the request is fuzzy (no prior design, unclear scope, vague requirements), run `brainstorm` first and say so. If a design exists, do not scaffold until its digest-bound design-review evidence verifies as SHIP.352. **Align intent:** clarify until success criteria are testable.363. **Pass the simplicity gate:** state the simplest complete design, justify every mechanism beyond it with a present requirement or measurement, and defer plausible future complexity behind a concrete trigger. A wish cannot outsource this decision to implementation.374. **Define scope:** explicit IN and OUT lists. OUT cannot be empty.385. **Decompose:** small, loosely coupled execution groups.396. **Scaffold** — always copy the template, never hand-write WISH.md. Resolve40 the absolute directory containing this loaded `SKILL.md`, replace only the41 two placeholder assignments below, and run the complete command from the42 repository root:4344 <!-- wish-scaffold-command:start -->45 ```sh46 WISH_SKILL_DIR='<absolute directory containing this SKILL.md>'47 WISH_SLUG='<slug>'48 case "$WISH_SLUG" in49 ''|*[!a-z0-9-]*|-*|*-) printf 'invalid wish slug: %s\n' "$WISH_SLUG" >&2; exit 2 ;;50 esac51 WISH_DEST=".genie/wishes/$WISH_SLUG/WISH.md"52 test -f "$WISH_SKILL_DIR/templates/wish-template.md"53 test ! -e "$WISH_DEST"54 mkdir -p "$(dirname "$WISH_DEST")"55 cp "$WISH_SKILL_DIR/templates/wish-template.md" "$WISH_DEST"56 ```57 <!-- wish-scaffold-command:end -->5859 The template ships inside this skill as the single source of truth for wish structure — a plain document, no runtime scaffolder. Copying guarantees the skeleton the parser and linter expect; ad-hoc wishes regularly fail structural lint.607. **Fill:** replace the `{{slug}}`/`{{date}}` tokens and every `<TODO: …>` marker with real content. Every group gets61 acceptance criteria plus a non-zero validation command proportional to the planned diff's risk and reach. Start with62 the narrowest checks that can disprove the changed behavior or contract: documentation-only groups, including63 deterministic generated documentation or plugin skill mirrors, use relevant format, link, example, generator, parity,64 or content-contract checks; runtime groups use focused behavior tests and add type, lint, or build checks only for65 boundaries they reach. Escalate shared runtime/core behavior, dependency or lockfile, generated executable or runtime66 artifact, configuration or schema, CI or release, broad-refactor, or uncertain-impact groups to the repository full67 gate plus affected build or end-to-end checks. State why the command scope fits; a repository-documented68 gate is by itself sufficient justification for its scope. Preserve any repository-defined aggregate integration or69 release gate separately from per-group validation.708. **Declare dependencies:** use the wish-level `## Dependencies` keys71 `**depends-on:** <comma-separated slugs or none>` and72 `**blocks:** <comma-separated slugs or none>` for cross-wish edges. Keep73 per-group `**depends-on:**` fields under each execution group. The spelling74 is always hyphenated; the DAG is a machine-readable planning artifact in git.759. **Create tasks** — one per execution group, so `work` can claim and complete each group and the board reflects progress:76 ```bash77 genie task create --title "<group title>" --wish <slug> --group <group-name>78 genie task list --wish <slug> # inspect what was created79 ```80 Tasks carry the `--wish`/`--group` linkage; the dependency DAG stays in the WISH.md document, not in task rows. If creation fails (no `.genie/genie.db` yet, CLI unavailable), warn and continue — WISH.md in git is the source of truth and must remain usable by `work` without task rows.8110. **Handoff:** run the wish linter — inside the genie repo, `grep -q '"wishes:lint"' package.json 2>/dev/null && bun run wishes:lint`. If it reports any error, surface it and stop — never hand a structurally broken wish onward. Only after lint passes, auto-invoke `review` (plan review) on the WISH.md. Never suggest `work` directly — the review gate comes first.8211. **Persist the verdict:** the reviewer only returns evidence. The invoking orchestrator appends that evidence under `## Review Results` and sets the WISH status to `APPROVED` on SHIP, `FIX-FIRST` on FIX-FIRST, or `BLOCKED` on BLOCKED. Do not route to `work` until the `APPROVED` status is on disk.8312. **Record the wave base (APPROVED only):** once the status on disk is `APPROVED`, run `genie context --wish <slug>` from the repository root. This non-`--plan` resolution pins the integration base SHA as the wish's wave base — every group spawn cuts its worktree from that one SHA. A later run returns the recorded SHA; `genie context --wish <slug> --re-resolve` refreshes it. Never use `--plan` for this step: the preview writes nothing, so it cannot record the base. If the command fails (genie CLI or state DB unavailable — an empty ready-task set is NOT a failure; the base is still recorded and returned), warn and continue — the first non-plan resolution or the first `spawn --wish` records the base instead.8485## Wish Document Sections8687| Section | Required | Notes |88|---------|----------|-------|89| Status / Slug / Date | Yes | Status: DRAFT on creation |90| Summary | Yes | 2-3 sentences: what and why |91| Scope IN / OUT | Yes | OUT cannot be empty |92| Decisions | Yes | Key choices with rationale |93| Simplicity Case | Yes | Simplest complete design, justified additions, and measurable deferrals |94| Success Criteria | Yes | Checkboxes, each testable |95| Execution Strategy | Yes | Wave-based plan — mandatory even if a single sequential wave; forces ordering, parallelism, and dependency thinking upfront |96| Execution Groups | Yes | Goal, deliverables, acceptance criteria, validation command |97| Dependencies | Yes | Wish-level `depends-on` / `blocks` using slug or `repo/slug`; use `none` when empty |98| QA Criteria | No | What to verify on dev after merge |99| Assumptions / Risks | No | What could invalidate the plan |100101## Rules102- Never write WISH.md from scratch — always copy the in-skill template, then edit.103- Lint before handoff: the genie repo's wish linter must pass before `review` sees the wish.104- Never emit a bracket-link to a non-existent brainstorm — use the `_No brainstorm — direct wish_` stub.105- Never consume a linked design whose persisted review evidence is missing, non-SHIP, or stale; the wish linter independently enforces this for new wishes.106- No implementation during `wish` — planning only.107- On APPROVED, record the wave base with the non-`--plan` `genie context --wish <slug>` (warn and continue on failure; never `--plan`).108- No speculative optimization: caches, deltas, sharding, background coordination, and configuration surfaces require a current criterion or measurement in the Simplicity Case.109- Every group testable, bite-sized, and independently shippable; no vague tasks ("improve everything").110- Every group has non-zero, risk-proportional validation with its scope explained; aggregate integration and release111 gates remain intact.112- OUT scope must contain at least one concrete exclusion.113- Declare cross-wish dependencies early.