Skip to content

Hardening Phase 4: enforced VM↔interpreter parity gate#91

Merged
abneeshsingh21 merged 2 commits into
mainfrom
test/vm-interpreter-parity-gate
Jul 11, 2026
Merged

Hardening Phase 4: enforced VM↔interpreter parity gate#91
abneeshsingh21 merged 2 commits into
mainfrom
test/vm-interpreter-parity-gate

Conversation

@abneeshsingh21

@abneeshsingh21 abneeshsingh21 commented Jul 11, 2026

Copy link
Copy Markdown
Owner

Phase 4 — VM↔interpreter parity gate

epl run defaults to the bytecode VM, while the docs and most of the suite validate against the tree-walking interpreter. A program that behaves differently across the two backends is a divergence bug — and nothing caught it: tests/parity_check.py diffed the backends but always exited 0, so it never gated CI.

What this adds

tests/test_parity_corpus.py — walks the real corpus (examples/ + benchmarks/, recursively) and runs every eligible program through both backends via the actual CLI, asserting each exits 0 with byte-identical stdout.

  • 54 programs checked, 0 divergences today.
  • Ineligible programs are excluded by a documented, directory-agnostic content filter (unlike test_examples_run.py's top-level-only glob, this covers examples/apps/, examples/discord_agent/, benchmarks/, …): servers/never-exit loops, interactive stdin-blocking, socket/GUI event loops, the Node-dependent Use javascript bridge, the Test … End Test DSL, and nondeterministic random/uuid output.
  • Fail-closed: everything else is included by default — a new compute example is auto-covered, and a program that hangs FAILS on a per-program timeout rather than being silently skipped (the exact failure mode the advisory harness swallowed).

parity_check.py keeps its rich manual per-divergence diffs and now points to the enforced gate.

Verification

  • New gate: 55 passed (54 parity + presence check).
  • Full suite: 2540 passed, 6 skipped.
  • ruff format --check + ruff check clean.

Summary by CodeRabbit

  • Tests
    • Added an automated compatibility check ensuring example and benchmark programs produce identical output when run with either execution backend.
    • Added timeout and exit-status validation to detect hangs or failed runs.
    • Added safeguards to verify the test corpus exists and contains eligible programs.
  • Documentation
    • Documented the new backend parity checks and the default execution behavior.

…orpus

`epl run` defaults to the bytecode VM while docs/tests validate against the
tree-walking interpreter, so a program that behaves differently across the two
backends is a divergence bug nothing caught: tests/parity_check.py diffed them
but always exited 0, never gating CI.

Add tests/test_parity_corpus.py — walks the real corpus (examples/ +
benchmarks/, recursively) and runs every eligible program through BOTH backends
via the actual CLI, asserting each exits 0 with byte-identical stdout (54
programs, 0 divergences). Ineligible programs are excluded by a documented,
directory-agnostic content filter (servers, interactive, socket/GUI loops, the
Node-dependent JS bridge, the Test..End Test DSL, and nondeterministic
random/uuid output). Everything else is included by default (fail-closed): a new
compute example is auto-covered, and a program that hangs FAILS on a per-program
timeout instead of being silently skipped — the failure mode the advisory
harness swallowed.

parity_check.py keeps its rich manual diffs and now points to the enforced gate.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, you can upgrade your account or add credits to your account and enable them for code reviews in your settings.

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Jul 11, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Preview URL Updated (UTC)
✅ Deployment successful!
View logs
epl 62fb25b Commit Preview URL

Branch Preview URL
Jul 11 2026, 04:09 PM

@coderabbitai

coderabbitai Bot commented Jul 11, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@abneeshsingh21, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 46 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: d3b3fde2-7e86-4287-b68c-47c4a1f954b8

📥 Commits

Reviewing files that changed from the base of the PR and between 4d55c12 and 62fb25b.

📒 Files selected for processing (1)
  • tests/test_parity_corpus.py

Walkthrough

The PR adds a CI parity gate that recursively runs eligible example and benchmark programs through the VM and interpreter using the CLI, requiring successful exits and byte-identical stdout. It also documents the gate and clarifies the manual parity harness.

Changes

VM/interpreter parity enforcement

Layer / File(s) Summary
Corpus discovery and backend execution
tests/test_parity_corpus.py
Discovers eligible .epl programs, applies content-based exclusions, and runs each backend with per-run timeouts.
Parity assertions and documentation
tests/test_parity_corpus.py, tests/parity_check.py, CHANGELOG.md
Validates corpus coverage, exit status, and stdout equality while documenting the enforced CI gate and manual harness.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Pytest
  participant EPLCLI
  participant Backend
  Pytest->>EPLCLI: Run eligible program
  EPLCLI->>Backend: Execute with VM or interpreter
  Backend-->>EPLCLI: Return exit code and stdout
  EPLCLI-->>Pytest: Return captured results
Loading

Possibly related PRs

Poem

A bunny hops through code with glee,
Testing VM and interpreter harmony.
Same stdout, exits bright,
No hidden hangs escape the night—
Parity blooms for all to see! 🐇

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: enforcing a VM↔interpreter parity gate.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch test/vm-interpreter-parity-gate

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/test_parity_corpus.py`:
- Around line 48-77: Tighten matching in the _SKIP_TOKENS filtering logic so
collision-prone entries such as “random” and “uuid” are recognized as standalone
words rather than arbitrary substrings, while preserving intentional exclusions.
Alternatively, document in the relevant test/docstring that substring matching
is deliberately over-inclusive; prefer the boundary-aware approach where the
matcher is visible.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 302155b8-1a13-47c0-bf42-d7fa9d767f53

📥 Commits

Reviewing files that changed from the base of the PR and between b6c4ab4 and 4d55c12.

📒 Files selected for processing (3)
  • CHANGELOG.md
  • tests/parity_check.py
  • tests/test_parity_corpus.py

Comment on lines +48 to +77
_SKIP_TOKENS = (
# Servers and never-exit event loops: they don't run to completion, so there is no
# terminal stdout/exit status to compare.
'WebApp',
'Route ',
'Listen',
'Serve',
'serve(',
'run_server',
'web_api_create',
# Interactive: block on stdin, so they can't run unattended.
'Ask ',
'Prompt ',
'input(',
'Read line',
# Sockets / desktop GUI event loops: block like a server.
'websocket',
'WebSocket',
'gui_window',
# Environment-dependent: the JS/TS bridge needs a Node.js runtime that may be absent.
'Use javascript',
# The `Test "…" … End Test` assertion DSL has its own runner; it is not `epl run` code.
'End Test',
# Nondeterministic output: random/uuid legitimately differ between any two runs, so
# the two backends can't be expected to emit byte-identical stdout.
'random',
'uuid',
'generate_uuid',
'random_string',
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Consider tightening skip-token matching to reduce silent over-exclusion.

Several _SKIP_TOKENS entries are bare substrings ('random', 'uuid', 'Listen', 'Serve') that will match anywhere in the file — including comments, variable names, or unrelated strings. A program that merely mentions "random" in a comment would be silently excluded from parity coverage. While this is fail-safe (over-exclusion, not under-exclusion), it can quietly erode coverage without anyone noticing. The >= 30 threshold in test_corpus_present is a coarse backstop but won't catch gradual drift.

Consider word-boundary checks (e.g., regex \b or token-aware scanning) for the shorter, more collision-prone tokens like 'uuid' and 'random', or at minimum adding a brief note in the docstring that the filter intentionally over-matches.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/test_parity_corpus.py` around lines 48 - 77, Tighten matching in the
_SKIP_TOKENS filtering logic so collision-prone entries such as “random” and
“uuid” are recognized as standalone words rather than arbitrary substrings,
while preserving intentional exclusions. Alternatively, document in the relevant
test/docstring that substring matching is deliberately over-inclusive; prefer
the boundary-aware approach where the matcher is visible.

@abneeshsingh21

Copy link
Copy Markdown
Owner Author

Thanks — evaluated the skip-token nitpick as a senior dev, verifying against the code.

Accepted (both shipped in 62fb25b):

  • Documented that the filter is a deliberately conservative substring scan — over-matching is the intended, fail-safe direction (loses coverage, never a false CI red).
  • Tightened the drift backstop from >= 30 to >= 45 (54 eligible today), so gradual over-exclusion trips test_corpus_present loudly instead of eroding silently — the exact concern raised.

Declined — word-boundary matching: it would risk the worse failure mode. \b-aware matching would under-exclude EPL's _-joined nondeterministic builtins (random_string, generate_uuid don't sit on word boundaries), letting a genuinely nondeterministic program slip in and produce a false parity failure. For a CI gate, fail-safe over-exclusion (caught by the floor) beats fragile matching that can false-red.

@abneeshsingh21
abneeshsingh21 merged commit 9783547 into main Jul 11, 2026
18 checks passed
@abneeshsingh21
abneeshsingh21 deleted the test/vm-interpreter-parity-gate branch July 11, 2026 16:21
@github-actions github-actions Bot locked and limited conversation to collaborators Jul 11, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant