# Slides content & storytelling review loop for decks

This bounded loop reviews a deck's narrative. Visual review remains with the sibling [Designer + Vision Review Loop](./ui-designer-review-loop.md).

## Public entrypoint and dependency boundary

- `dev-loop` remains the single public entrypoint. This review loop is an internal capability behind it and adds no second public workflow name.
- It consumes the deck source (and optionally the captured slide screenshots produced by the [UI Smoke Harness](./ui-smoke-harness.md)) plus acceptance criteria and a storytelling brief. It does not redefine browser capture or artifact naming.

## Required input bundle

The loop requires all of the following inputs before it may run:

1. **Acceptance criteria**
   - the slice-level acceptance criteria the review is judging
2. **Storytelling brief**
   - one bounded note: audience, intended takeaway, and what to pay extra attention to
3. **Deck bundle**
   - `deckSourcePath` — required path to the deck source (e.g. the Slidev `.md`)
   - `slideScreenshots[]` — optional captured slides from the UI smoke harness
     - `slideId`
     - `screenshotPath`

If any required part of this bundle is missing, incomplete, or ambiguous, the loop fails closed instead of guessing. Optional slide screenshots, when present, must each carry both `slideId` and `screenshotPath`.

## Review lens (public audience)

- **Arc**: is there a hook → tension → resolution? Does slide 1 make a stranger care?
- **One message per slide**: each slide has a single takeaway; titles state the claim, not the topic.
- **Sequencing**: order builds understanding; no forward references; jargon introduced before it is used.
- **Audience calibration**: a public/non-insider reader can follow it — internal enum names, state-machine identifiers, and pills are translated or earn their keep, not dumped raw.
- **Cut / merge / reorder**: explicit recommendations — which slides to drop, combine, or move.
- **Close**: a memorable takeaway, not a feature list.

The reusable prompt template is at `skills/dev-loop/templates/slides-story-review.md`.

## Required output bundle

Every review pass must produce a bounded structured result with:
- **Findings**
  - what is wrong with the narrative and why
  - which `slideId` it affects
  - the severity (`high` | `medium` | `low`)
- **Corrective actions**
  - what should be changed next (cut / merge / reorder / reword), one per finding
- **Outcome**
  - exactly one of:
    - `story_review_satisfied`
    - `needs_iteration`

## Outcome semantics

### `needs_iteration`

Use this when narrative findings remain and a storytelling pass should continue. The handoff goes back with the findings, the corrective actions, and the same acceptance criteria and storytelling brief for the next pass. When the outcome is `needs_iteration`, the findings list must be non-empty.

### `story_review_satisfied`

Use this when the deck satisfies the storytelling brief and acceptance criteria closely enough to stop iterating on the narrative side, and any remaining issues are minor enough that they do not justify another dedicated storytelling pass. This does not replace normal engineering validation or the visual review.

## Fail-closed behavior

The loop fails closed when:
- required acceptance criteria are missing
- the storytelling brief is missing or empty
- the deck source path is missing
- an optional slide screenshot lacks `slideId` or `screenshotPath`

When the work is not a deck, the loop does not trigger; it returns a skip outcome (`skip_non_slides`) instead of pretending to review unrelated artifacts.

## Handoff sequence under `dev-loop`

1. Draft or update the deck source.
2. Optionally collect the captured slide screenshots from the UI smoke harness.
3. Run the story review against the acceptance criteria and storytelling brief using the template at `skills/dev-loop/templates/slides-story-review.md`.
4. If the outcome is `needs_iteration`, apply the corrective actions (words / order / structure, not the design system) and re-run.
5. Re-run until the outcome is `story_review_satisfied`.
