Skip to content

Simplify flow syntax and verify the grammar against the parser - #61

Merged
brynary merged 6 commits into
recover/04-ai-stepsfrom
recover/05-language-and-grammar
Oct 5, 2026
Merged

brynary merged 6 commits into
recover/04-ai-stepsfrom
recover/05-language-and-grammar

Conversation

@brynary

@brynary brynary commented Oct 5, 2026 •

Copy link
Copy Markdown
Contributor

Add the executable PEG grammar and parser comparison tests. Adopt role prefixes, WINDOW, and simpler tokens/comments; migrate the authored flows. Include the preceding screenshot-retry and CI-flake fixes.

Recovers the intended changes from #44, #45, #46, which were merged into the old development stack but did not reach main. Preserves the newer lithos-llm pin from #54.

Stage 5 of 10. Based on #60. Full recovery inventory and merge order: #57.

Merge the recovery PRs in order with merge commits. Once the preceding PR lands, retarget this PR to main.

Validation: CARGO_NET_OFFLINE=true mise run check passed on this branch. This runs formatting, Clippy, local Rust/browser tests, shim checks, eval tooling, and workflow checks. Paid model evals, the external BrowserSim round trip, and live Kernel checks were not rerun.

brynary and others added 6 commits September 28, 2026 21:25
…akes

Two snapshot tests failed once in CI with "Page.captureScreenshot:
Unable to capture screenshot": Chromium refused a capture for a moment
on a busy runner, and Whirl reported a runtime error. SNAPSHOT (page,
viewport, and element captures), SCREENSHOT, and JUDGE now take such a
capture again after a short pause, until the step's time runs out. Any
other capture error fails as before.

The 60 fps video test failed once on macOS with 61 distinct frames of
128: on a busy runner, with --trace sharing the screencast, Chrome
supplies fewer distinct frames and the recorder repeats the last one to
keep the rate. The test only needs to show that the animation was
recorded, and a still page gives one or two distinct frames, so both
rate checks now require a quarter of the frames to differ instead of
half.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
SPEC section 17 now defines the whole syntax of a .whirl file as a
parsing expression grammar in pest notation. Section 17.1 lists the
value rules that the grammar leaves out. grammar_tests.rs reads the
grammar from SPEC.md and requires the grammar and the parser to accept
the same files, with the same entries and steps, on the repository's
samples, edge cases, and changed copies of the samples.

The comparison found three places where the parser differed from the
SPEC, now fixed: JSON array bodies after HTTP and MOCK were a parse
error; MOCK lines with no VISIT after them parsed; and a JSON string's
\\{{name}} lost its reference in the parsed value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every ARIA role that Playwright accepts, except generic, none, and
presentation, is its own locator prefix: `button:"Sign in"`,
`button:~Sign` for a substring match, and `dialog:*` for any name.
`role:` is gone. Prefixes are strict: a bare colon in a locator always
marks a prefix, and `>>` is never a segment.

Browser tabs are windows: `WINDOW name` and `window:name closed`. A bare
value cannot start with `@`, `name: value` lines need a space after the
colon, and a quoted string joins a token only after `:` or `:~`. The
removed `[Asserts]` and `[Captures]` sections are gone.

With these rules the parser reads each line left to right, so the
grammar in SPEC section 17 drops its per-context locator rules and
lookaheads. Sample flows, SPEC examples, eval caches, and tests use the
new syntax.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A `#` in the middle of a bare token started a comment, so
`VISIT /docs#install` visited `/docs`, and
`ASSERT url == https://shop.example.com/#/cart` compared against the
URL without its fragment. `whirl check` passed both files.

A `#` now starts a comment only at the start of a line or after white
space, as in the shell. Inside a token it is text, so URL fragments
and `css:#submit` work without quotes. A value that starts with `#`
still needs quotes, and `whirl fmt` keeps them there.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A json: or xpath: argument had its own rule: one bare run or one quoted
string. So json:a:"b" was an error while css:a:"b" worked. The argument
now follows the token rule for every prefix value, and the grammar drops
its `single` rule.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@brynary
brynary added this pull request to stack #67 October 5, 2026 18:18
@brynary
brynary merged commit 4b1e20a into main Oct 5, 2026
3 checks passed
@brynary
brynary deleted the recover/05-language-and-grammar branch October 5, 2026 18:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant