"Interactively design a new Arazzo scenario from PM intent through a structured 11-step flow (intent, domain, inventory scan, actors, step walk, failure modes, UI hints, generate, validate, Mermaid sanity check, write). Use when authoring a new behavioral scenario; delegates generation and validation to the scenario-architect and scenario-validator subagents."
Install
npx skillscat add specfuse/authoring/design-scenario Install via the SkillsCat registry.
Interactively design a new Arazzo scenario from PM intent, walking through a structured 11-step flow that produces a validated scenario file.
Enforces: .specfuse/authoring/handbooks/Arazzo_Handbook.md
Before writing any files, read and internalize the authoritative rules:
- Read
.specfuse/authoring/handbooks/Arazzo_Handbook.md-- the full handbook - Read
.specfuse/authoring/samples/scenario-samples.yaml-- canonical scenario template - Read
.specfuse/authoring/samples/recipe-samples.yaml-- canonical recipe template (for understanding x-setup wiring) - Note the input/output contract of the
scenario-architectsubagent (provided by the specfuse-authoring plugin) -- you will delegate generation to it - Note the report format of the
scenario-validatorsubagent (provided by the specfuse-authoring plugin) -- you will delegate validation to it
What this command produces
A single Arazzo 1.0.1 scenario file (.arazzo.yaml) placed in:
api/specs/v1/domains/{domain}/scenarios/for domain scenariosapi/specs/v1/scenarios/cross-domain/for cross-domain scenarios
The scenario is generated by the scenario-architect sub-agent and validated by the scenario-validator sub-agent. This command handles all user interaction and delegates heavy lifting to those agents.
The 11-step interactive flow
Work through these steps in order. Each step has a clear interaction point -- present information, ask for confirmation, then move on. Do not skip steps. Do not batch multiple steps into a single response unless the user explicitly asks to accelerate.
Step 1: Gather intent
Ask the user to describe the use case in 2-3 sentences. Guide them with:
"Describe the use case you want to model. What triggers it, who is involved, and what is the expected outcome?"
From the response, identify:
- The core action (e.g., "process a refund", "finalize an order", "archive stale records")
- The trigger (user action, cron job, upstream event)
- The expected outcome (state change, notification, generated artifact)
- Whether this is a happy path, a failure test, or both
Present your understanding back to the user and confirm before proceeding.
Step 2: Map to domain
Based on the intent, propose a kebab-case domain name from the project's active domain list (defined in the project's overlay).
If the use case spans multiple domains, propose cross-domain and confirm file placement under scenarios/cross-domain/.
Present the proposed domain and confirm with the user.
Step 3: Scan OpenAPI and AsyncAPI
Read the target domain's specs to build inventories:
- Operations inventory: Glob
api/specs/v1/domains/{domain}/operations/*.yamland extract everyoperationId. For cross-domain scenarios, also scan the relevant secondary domains. - Events inventory: Glob
api/specs/v1/domains/{domain}/messages/*.yamland extract everyx-labelas{Entity}.{Action}. Also check OpenAPI operations forx-emitsto identify write-triggered events. - Existing scenarios: Glob
api/specs/v1/domains/{domain}/scenarios/*.arazzo.yamland list their workflowIds and step operationId sequences (for the granularity check later). - Existing recipes: Glob
api/specs/v1/scenarios/setup-recipes/**/*.recipe.yamland list their file stems and output keys.
Present the candidate operations and events to the user as a numbered list, organized by type:
- Read operations (GET endpoints)
- Write operations (POST/PUT/PATCH/DELETE) with their
x-emitsevents - Available events (from AsyncAPI messages)
Highlight which operations and events seem relevant to the use case described in step 1. Ask the user to confirm which ones the scenario will use, and flag any that are missing:
"I found these operations and events in the {domain} domain. Which ones apply to your scenario? If the operation you need is missing, we will need to design it in OpenAPI first."
Step 4: Confirm actors
Based on the use case, propose actors whose roles are registered in the OpenAPI info.x-roles registry.
Many projects include an Authenticated role for pre-business-role flows (signup, invitation acceptance) — check whether the project's enum declares it before using it. The other roles vary by project.
For each actor, propose:
- A camelCase key (e.g.,
requester,manager,approver,observer) - A role from the closed set
- A description of their role in this scenario
For scheduled-job scenarios (cron-triggered, no human initiator), explain that the actor serves as an observer who verifies outcomes, not an initiator. Use x-as: $observer on verification steps.
Present the actor list and confirm:
"Here are the actors I propose for this scenario. Confirm or adjust their roles and keys."
Step 5: Walk through steps
Build the step sequence one step at a time. This is the longest part of the flow -- for each step:
Propose the step based on the use case and the confirmed operations:
stepId(kebab-case)operationId(from the inventory, or omitted for standalonex-async.await/x-async.pollsteps)x-as(which actor performs this step)- Key request parameters and body fields (using
$setup.outputs.X,$steps.{id}.outputs.X, or$inputs.Xexpressions) - Expected status code (matching OpenAPI: GET->200, POST->201, PUT/PATCH->200, DELETE->204)
- Outputs to extract (e.g.,
refundId: $response.body#/id) - Async assertions if the operation emits events (
x-async.emit) or the step needs to wait for an event (x-async.await) or poll (x-async.poll)
Present the step in a readable summary (not raw YAML -- keep it conversational):
Step 3: Create refund request (as
$requester)- Calls
requestRefund(POST, expects 201) - Body: orderId, lineId from setup
- Outputs: refundRequestId
- Emits:
Refund.Requested(timeout 10s)
- Calls
Confirm with the user before moving to the next step. Accept corrections (different actor, different operation, additional outputs).
After all steps are confirmed, summarize the full step sequence and ask for a final confirmation:
"Here is the complete step sequence. Does this match the flow you have in mind? Any steps to add, remove, or reorder?"
Step 6: Elicit failure modes
Ask explicitly about failure paths:
"What should happen if any of these steps fail? Are there specific error scenarios to test (e.g., validation failures, permission errors, duplicate requests)?"
For each identified failure mode, determine whether it should be:
- A step-level
onFailureblock (single expected-error step within an existing workflow) - A separate workflow in the same file (if it produces a meaningfully different Mermaid sequence diagram)
- A workflow-level
failureActionsdefault (if all steps share the same failure behavior)
Apply the Mermaid diagram test: if the failure path has the same steps as the happy path with only one step's outcome differing, use onFailure on that step. If the failure path has a meaningfully different step sequence, create a separate workflow.
Step 7: Collect x-ui actions
For each step that has a user-facing interaction, ask:
"For the '{stepId}' step, what does the user see and do in the UI? Describe the page, the actions they take, and what they expect to see after."
Collect:
- Platform: web, mobile, or any
- Page: the route where this happens (e.g.,
/orders) - Actions: ordered natural-language descriptions of what the user does (each gets a kebab-case
id) - Expect: what the user sees after the step (visual outcomes)
- Playwright selectors: only if the user provides concrete selectors. Do NOT guess at selectors.
If the user says the scenario has no UI steps, skip this step entirely.
Step 8: Generate YAML
Delegate to the scenario-architect sub-agent. Spawn a single Agent with the following structured context gathered from steps 1-7:
Required inputs to include in the agent prompt:
domain: the confirmed domainintent: the PM's original use case description from step 1actors: the confirmed actor list with keys, roles, and descriptionssteps: the confirmed step sequence with operationIds, actors, parameters, outputs, and async assertionsoperationIdInventory: all operationIds found in step 3eventInventory: all{Entity}.{Action}event names found in step 3existingScenarios: scenario files and their step sequences from step 3existingRecipes: recipe file stems and output keys from step 3
Optional inputs (include when available):
failureModes: failure paths from step 6uiActions: UI action descriptions from step 7tags: any tags the user mentioned (e.g.,critical-path)
Tell the agent to:
- Read
.specfuse/authoring/handbooks/Arazzo_Handbook.mdand.specfuse/authoring/samples/scenario-samples.yaml - Follow the generation process the
scenario-architectsubagent (provided by the specfuse-authoring plugin) defines - Return the complete YAML content and the proposed file path
- Report any gaps found (missing operationIds, events, recipes)
Setup recipe selection: before spawning the agent, check the existing recipes from step 3. If no recipe provides the outputs the scenario needs (actor entity IDs, resource IDs):
STOP and tell the user:
"This scenario needs setup fixtures that no existing recipe provides. The following outputs are needed: [{list}]. Please run
/design-recipeto create a recipe first, then return to/design-scenario."Do not proceed until the recipe gap is resolved.
If the architect agent reports gaps (missing operationIds, events, or a granularity violation >= 80% overlap), surface them to the user and stop. These are blocking issues that must be resolved before the scenario can be written.
Step 9: Validate
After the architect produces the YAML, write it to a temporary location and delegate validation to the scenario-validator sub-agent.
Spawn the scenario-validator subagent (provided by the specfuse-authoring plugin), which:
- Applies its validation pipeline and report format
- Runs the validation pipeline against the generated file:
./scripts/specfuse/validate-arazzo-spectral.sh(Spectral lint)./scripts/specfuse/validate-arazzo.sh(structural + cross-spec checks)
- Returns a structured validation report
Process the report:
- Auto-fix mechanical issues silently: missing
x-versiondefaults, missingx-mcp: { exposed: false }, casing fixes, ISO duration format corrections. Apply these to the YAML without asking the user. - Surface judgment calls to the user: unresolved operationIds, invalid actor roles, event name mismatches, granularity alerts. Present each issue and ask how to proceed.
- Re-validate after fixes until the report shows zero errors.
If validation reveals issues that require design changes (wrong operationId, missing event), go back to the relevant earlier step (step 3 or step 5) and rework.
Step 10: Mermaid sanity check
Generate a Mermaid sequence diagram from the scenario's step sequence. For each workflow in the file, produce a diagram showing:
- Actor swimlanes (participants named by actor key and role)
- Step arrows (from actor to API, labeled with the operationId or action)
- Event annotations (async emit/await/poll shown as notes or dashed arrows)
- Failure branches (if separate failure workflows exist)
Present the Mermaid markdown in a fenced code block so the terminal renders it:
```mermaid
sequenceDiagram
participant requester as Requester (Customer)
participant api as API
participant approver as Approver (SupportAgent)
participant bus as Event Bus
requester->>api: requestRefund (POST 201)
api-->>bus: Refund.Requested
approver->>api: getRefund (GET 200)
approver->>api: approveRefund (PUT 200)
api-->>bus: Refund.Approved
bus-->>requester: Refund.Validated (await)
requester->>api: getRefund (poll until completed)
```Ask the user:
"Does this diagram match the flow you described? Any steps out of order or missing?"
If the user identifies issues, go back to step 5 and adjust the step sequence, then regenerate (steps 8-10).
Step 11: Write file
Save the validated scenario file to its final location:
- Domain scenario:
api/specs/v1/domains/{domain}/scenarios/{use-case-name}.arazzo.yaml - Cross-domain:
api/specs/v1/scenarios/cross-domain/{use-case-name}.arazzo.yaml
Report:
- The file path
- A summary of what was created (number of workflows, steps, actors, events)
- Suggested next steps:
- Run
/review-scenariofor an independent second opinion on quality and granularity - Run
/validateto verify no regressions in the broader spec suite - If the scenario has
critical-pathtag, note that it will block PR merges once test generation is in place
- Run
Post-flow checklist
Verify all of these before reporting completion:
- Scenario file written to the correct directory
- All
operationIdvalues confirmed against OpenAPI - All
{Entity}.{Action}event names confirmed against AsyncAPI - Status code assertions match OpenAPI conventions (GET->200, POST->201, PUT/PATCH->200, DELETE->204)
-
x-versionpresent withcurrent: 1andstatus: draft -
x-domainpresent and matches the confirmed domain -
x-doc.summarypresent and PM-readable -
x-mcp.exposedexplicitly set -
x-actorspresent with at least one actor, all roles from the closed set -
x-aspresent on every scenario step -
x-setuprecipe exists and provides all needed outputs (or gap flagged) - Granularity check passed (no >= 80% step overlap with existing scenarios)
- Mermaid diagram reviewed by the user
- Validation passes with zero errors
- No hardcoded dates -- date tokens (
@today+3d) used throughout - No language-specific references (no class names, namespaces, package paths)
- No top-level
x-emits(Arazzo usesx-async.emiton steps) - No channel addresses in
x-async(channels are derived)
Tips for good scenarios
- One file = one use case. If two scenarios would produce the same Mermaid diagram, merge them into one scenario with input parameters for data variation.
- Workflows for step-sequence variants, not data variants. Use separate workflows for "manager approves" vs "manager rejects" (different steps). Use input parameters for "morning order" vs "evening order" (same steps, different data).
- Assert observable outcomes for AI workers. Use
x-async.awaitfor the terminal event andx-async.pollor GET steps for the resulting REST state. Never assert prompt content, model choice, or token counts. - Use date tokens, not hardcoded dates.
@today+3d,@now-1h,@today+2w@America/Montreal. Date tokens resolve only inx-setup.inputs, workflowinputsdefaults, steprequestBody.payload, and stepparametersvalues. - Keep
x-doc.summaryPM-readable. Write for the product manager, not the developer. Avoid jargon, acronyms, and implementation details. - Tag
critical-pathsparingly. Only scenarios that must block PR merges deserve this tag. Overuse dilutes its value and slows CI. - Recipes are infrastructure. If the scenario needs fixtures that no recipe provides, create the recipe first with
/design-recipe. Do not inline fixture creation in the scenario. - Failure modes deserve explicit attention. Step 6 exists because failure paths are often where the most important behavior lives. Do not skip it.