Scenario compiler

How .molar.md scenarios are validated, compiled, and executed — P1 verbs and deterministic Playwright output.

Scenario compiler

The scenario compiler (@molar/scenario-spec) validates .molar.md files, resolves clone legs, and emits deterministic Playwright .spec.ts artifacts.

Commands

molar scenarios validate   # lint frontmatter + step grammar
molar scenarios compile      # write .molar/scenarios/*.spec.ts (gitignored)

Validation runs in CI and locally. Compilation is content-hash keyed — the same scenario always produces the same Playwright output for a given compiler version.

File format

Each scenario is a Markdown file with YAML frontmatter:

---
spec_version: '1.0'
id: '019301c0-cafe-7000-bea7-000000000001'
slug: checkout-happy-path
description: User completes checkout
priority: medium
tags: [smoke]
clones:
  - { kind: stripe, seed: stripe-base }
---

# Checkout

## Steps

1. Navigate to /checkout
2. Click "Pay now"
3. Wait for webhook stripe.checkout.session.completed {timeout: 30s}
4. Assert text "Thank you" is visible

Project-level config lives in repo-root .molar.md.

Browser-authoring pipeline

molar_generate_scenarios_from_url is the verified authoring entry point. It returns a durable task_id; poll molar_get_task until completed, failed, or cancelled. A verified run crawls the authorized project URL, checkpoints discovered flow IDs, replays selected flows in a recorded browser, and sends only value-free evidence through the canonical compiler.

Successful flow results contain three immutable artifacts:

  • molar_md — canonical source;
  • playwright — deterministic compiled .spec.ts;
  • manifest — source, compiled, evidence, compiler-version, and provenance hashes plus Trace/HAR/recording/screenshot references.

Artifact reads are project-scoped and return five-minute signed URLs. Stalled work is claimed atomically and resumes from its stored checkpoint; a run beyond the total deadline fails with authoring_deadline_exceeded. Cancellation keeps already verified sibling flows. Authoring never opens a pull request automatically.

For sign-up or authenticated flows, pass an opaque auth_context. Email, OTP, password, identity, and payment values stay in credential/Clone boundaries and are rendered as secret references rather than literals.

Locator grammar

Browser interactions accept only bounded Playwright-native targets: role "button" named "Continue", label "Email", testid "submit", exact text "Welcome", or a stable css "[data-state=ready]". URL authoring rejects unstable positional selectors such as nth-child.

Shipped verbs

These verbs compile to Playwright today:

VerbPurpose
navigateGo to a path or URL
fillFill an input
clickClick an element
assertText/visibility/state assertion
waitFixed delay or condition
snapshotDOM snapshot checkpoint
screenshotCapture screenshot
inject_errorInject fault (chaos testing)
advance_clockAdvance clone virtual clock
requestHTTP request (API-only scenarios)
debugDebugger breakpoint

Playwright-native interaction verbs hover, select, check, uncheck, focus, blur, press, scroll, drag, and upload are also shipped.

Frontmatter schema

Required keys: spec_version (must be '1.0'), id (UUIDv7), slug, description.

Optional: priority, tags, clones, schedule (Guard production), shadow_prod, mender.mode.

Unknown frontmatter keys are rejected (MOLAR_S004).

Clone integration

Clone declarations in frontmatter tell Guard and the runtime which vendor simulators to start. Setup steps can reset clone state before assertions.

See Clones scenario integration.

MCP equivalents

CLIMCP
molar scenarios validatemolar_validate_scenario
molar scenarios compilemolar_compile_scenario

Compiler and authoring failures return bounded diagnostics with stable codes, severity, message, and optional line/column. A rejected candidate is never counted as authored or verified.