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

# Brief-to-plan acceptance run

> Run the same brief-to-draft scenario through the operator UI and an agent on a local stack, and check the properties the feature promises.

This run demonstrates one scenario twice: a brief becomes a template-backed plan, questions are answered, the plan is reviewed, and one draft gig is created. The first pass starts in the web app and finishes with an agent. The second starts with an agent and finishes in the web app. Both passes work on the **same saved plan**.

## Start the stack

```bash theme={null}
npm run dev:infra

cd api-events
npm run db:migrate
npm run db:seed:baseline
EVENT_PLANS_ENABLED=true EVENT_PLAN_EXTRACTOR=fixture npm run dev:emulator

cd ../web
NEXT_PUBLIC_FF_BRIEF_TO_PLAN=true npm run dev:emulator
```

`EVENT_PLAN_EXTRACTOR=fixture` reads the brief with a deterministic local extractor, so the run needs no AI Gateway key. To exercise the model, drop that variable and set `AI_GATEWAY_API_KEY`; the request is sent with zero data retention.

Sign in as the seeded owner. The organization needs:

* one gig template with a timed run of show, at least two staffing shifts, and a task checklist. Save any seeded gig as a template if none exists;
* two saved venues with the same name in different cities, so the brief's venue is ambiguous.

## The brief

```text theme={null}
Corporate reception, October 20 in Austin. 200 guests, doors at 6, program at 7,
finished by 10. Audio and basic lighting. Use our standard corporate setup.
Venue: The Echo
```

The brief has no year and no timezone on purpose.

## Pass one: app first, agent second

**1. Create the plan in the app**

**New gig → Plan from a brief**, paste the brief, and submit. Expect the plan page, not a gig.

**2. Choose the template**

The corporate template ranks first with its reasons listed. Select it. Schedule entries, roles, and tasks appear labelled **Template**; doors and program show **From brief** with the template's times kept beside them.

**3. Answer the blocking questions**

Expect exactly these under **Needed to create the draft**: the year for October 20 (offered as choices, none selected) and which **The Echo** is meant (nothing selected). The timezone shows as **Suggested** from the organization. Answer the year only, then close the tab.

**4. Continue with an agent**

Connect an MCP client to `http://localhost:4000/mcp` with the same user, and run the `plan_event_from_brief` prompt, or start CheckAI locally and ask it to continue the reception plan. The agent must list the existing plan rather than start a new one, present both venue candidates, and wait for your choice.

**5. Review and create**

Ask the agent to review the plan. It summarises by origin and lists what stays open. Ask it to create the draft: it must show a confirmation summary ending in "nothing is sent" and wait for your yes.

**6. Reopen in the app**

Reload the plan page: it shows **Created** and links to the gig. The gig is a **Draft**, its Overview lists the open decisions, and **Planned from a brief** links back to the plan.

## Pass two: agent first, app second

Give the agent the same brief in a new conversation. After it asks its questions, stop. Open **Gigs → Plans** in the app: the plan is there, at the questions step, with the agent's answers recorded. Finish the questions, review, and create the draft from the app.

## Properties to check

| Property | How to check |
| - | - |
| No invented values | Before you answer, the plan has no gig date. The draft cannot be created. |
| Sources are visible | Every detail has a label; hovering **From brief** shows the quoted words. |
| Anchor changes preview first | Move doors to 6:30. The preview lists what shifts and what stays pinned before anything changes. Pin the technical check, move doors again, and it stays. |
| Constraint conflicts are visible | Set the technical check to end after doors. A conflict appears and blocks creation until fixed or acknowledged. |
| Stale review is rejected | Review the plan in the app, edit it through the agent, then press **Create draft gig** in the app. The app reports the change and asks for a fresh review. |
| One gig per plan | Call create twice (repeat the agent's confirmed call, or re-send the request). Both return the same gig id. |
| Nothing outbound | See the query below. |
| Template untouched | Edit the draft's run of show. The template's is unchanged. |
| New template version does not reach back | Update the template from another gig. The draft and its plan keep their content; an open plan offers the new version with a diff. |

```sql theme={null}
SELECT
  (SELECT COUNT(*) FROM "Invitation" WHERE "eventId" = e.id)                       AS invitations,
  (SELECT COUNT(*) FROM "Notification" WHERE "eventId" = e.id)                     AS notifications,
  (SELECT COUNT(*) FROM crew_offers o
     JOIN crew_offer_recipients r ON r.offer_id = o.id WHERE o.event_id = e.id)    AS offer_recipients,
  (SELECT COUNT(*) FROM crew_offers o
    WHERE o.event_id = e.id AND (o.status <> 'DRAFT' OR o.sent_at IS NOT NULL))    AS sent_offers
FROM "Event" e
WHERE e.source_plan_id IS NOT NULL
ORDER BY e."createdAt" DESC
LIMIT 1;
```

Every column must be `0`.

## Automated coverage

The same properties are asserted without a browser in `api-events`:

* `src/db/eventPlanDraftWriter.integration.test.ts` covers one gig per plan, concurrent creates, rollback, stale review, and nothing outbound.
* `src/db/eventPlan.integration.test.ts` covers the version guard.
* `src/systems/event-plans/eventPlansOperations.integration.test.ts` covers the full pipeline with the fixture extractor.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.