Skip to main content

Parallax

Render-in-the-loop self-verification for coding agents — and the study of why it works.

A second viewpoint reveals structure invisible from the first. Parallax flips a generated text artifact (SQL, a regex, plotting code) into a rendered representation, has a critic inspect the render, and reports (or corrects) silent, "looks-right-but-wrong" bugs a quick glance misses.

  • Package (PyPI): parallax-verify · import: parallax · API: crosscheck(artifact, render_fn)
  • Status: 🟢 M1 usable. The crosscheck primitive works end-to-end with two adapters (SQL-result-shape, regex-highlight), a CLI, and an MCP server. Offline by default (no API key); upgrades to a multimodal vision critic when one is configured. The why-it-works study (M2) is separate and ongoing.

What it catches

Code that LLMs (and people) generate can fail silently — it runs, returns a plausible answer, and is wrong. Nothing throws.

  • SQL: a dropped/loose JOIN predicate inflates row counts (fan-out); a LEFT/INNER swap silently drops rows.
  • Regex: a greedy quantifier over-matches into a region it shouldn't; a pattern quietly misses spans it should catch.

Parallax extracts a small set of neutral shape facts (row-count ratio, null fractions, how many matches land in a forbidden region, …), renders them, and has a critic flag anything that looks off. It knows only what you tell it — there is no hidden oracle.

Install

pip install parallax-verify               # core: SQL + regex + CLI, offline heuristic critic
pip install "parallax-verify[anthropic]"  # + Anthropic vision critic
pip install "parallax-verify[openai]"     # + any OpenAI-compatible vision endpoint
pip install "parallax-verify[mcp]"        # + the MCP server

Walkthrough (CLI)

Offline by default — no API key required. Here's a real session; the whole idea fits in about thirty seconds.

A greedy regex over-matches into a region it was supposed to leave alone. --forbidden-spans 3:9 says the characters SECRET must not be matched:

$ parallax regex "<.*>" --target "<a>SECRET<b>" --forbidden-spans 3:9
parallax regex: "artifact" - [!] SUSPICIOUS (suspicion 0.65)
  critic: parallax-local-heuristic
  flagged: matches_in_forbidden_region
  note: local heuristic flagged extreme bins: matches_in_forbidden_region
$ echo $?
1

Make the quantifier lazy and the bug is gone — Parallax goes quiet:

$ parallax regex "<.*?>" --target "<a>SECRET<b>" --forbidden-spans 3:9
parallax regex: "artifact" - [ok] looks fine (suspicion 0.05)
  critic: parallax-local-heuristic
  note: local heuristic saw no extreme bins
$ echo $?
0

That flip — <.*> flagged, <.*?> clean — is the whole product in miniature.

SQL works the same way. A join predicate that's too loose multiplies rows (fan-out); you tell Parallax how many rows you expected and it catches the blow-up (3 expected, 12 returned):

$ parallax sql "SELECT o.id, c.region FROM orders o JOIN cust c ON o.cust = c.id" \
    --setup "CREATE TABLE orders(id INT, cust INT); INSERT INTO orders VALUES (1,10),(2,10),(3,10);
             CREATE TABLE cust(id INT, region VARCHAR); INSERT INTO cust VALUES (10,'A'),(10,'B'),(10,'C'),(10,'D');" \
    --expected-rows 3
parallax sql: "artifact" - [!] SUSPICIOUS (suspicion 0.65)
  critic: parallax-local-heuristic
  flagged: rowcount_ratio_to_expected
  note: local heuristic flagged extreme bins: rowcount_ratio_to_expected

Exit code is 0 when it looks fine, 1 when flagged, 2 on error — so it drops straight into CI. Add --json for machine-readable output:

$ parallax regex "<.*>" --target "<a>SECRET<b>" --forbidden-spans 3:9 --json
{"kind": "regex", "item_id": "artifact", "caught": true, "suspicion": 0.65, "flagged": ["matches_in_forbidden_region"], "rationale": "local heuristic flagged extreme bins: matches_in_forbidden_region", "corrected": false, "proposed_fix": null, "critic": "parallax-local-heuristic"}

Swap the offline critic for a vision model with --critic anthropic (needs ANTHROPIC_API_KEY) or --critic openai — see Critics below.

Use from Python

from parallax import Artifact, crosscheck, render_regex
from parallax.clients.heuristic_critic import HeuristicCritic

art = Artifact(kind="regex_highlight", text="<.*>",
               context={"target": "<a>SECRET<b>", "forbidden_spans": "3:9"})
result = crosscheck(art, render_regex, HeuristicCritic(), mode="expected")
print(result.critique.caught, result.critique.flagged)  # True ('matches_in_forbidden_region',)

Run the full demo (SQL + regex, offline): python examples/demo.py.

Use as an MCP tool (for Claude / agents)

parallax-mcp starts a server exposing one crosscheck tool (kind = sql | regex, text, context, optional mode/critic). Point your MCP client at it and an agent can render-verify its own generated SQL/regex before trusting the result.

The two honest modes

Parallax has no magic oracle. It works from what you give it:

  1. Supplied expectations — you provide the expected row count, the spans you meant to match, or the regions that must not match.
  2. Relative anomaly — compare against a previous / reference run.

Critics

Bring your own key — local needs none, and the vision critics accept a key from an env var or the --api-key flag:

  • local (default) — a fast, offline, rule-based sanity check over the same verdict-free features. No API key.
  • anthropic — an Anthropic multimodal model looks at the rendered image. PARALLAX_CRITIC=anthropic + ANTHROPIC_API_KEY (default model claude-opus-4-8).
  • openai — any OpenAI-compatible vision endpoint. PARALLAX_CRITIC=openai + OPENAI_API_KEY (default model gpt-4o-mini). Point --base-url (or PARALLAX_BASE_URL) at OpenAI, Google Gemini's OpenAI-compatible endpoint, OpenRouter, or a local server, and pick the model with --model.

Which critic to trust. The offline local critic is the zero-config default and is fully tested. The Anthropic vision critic is validated live on the SQL adapter — it passes clean results and catches fan-outs. (An earlier render showed only a color per bin and the model false-positived on clean results; the render now prints each bin's label as text, which fixed it.) The OpenAI-compatible endpoint and the regex render haven't had the same live check yet, so treat their vision verdicts as provisional and lean on local for CI.

# use your own OpenAI key
parallax sql "..." --setup "..." --expected-rows 3 --critic openai --api-key "$OPENAI_API_KEY"
# or a different provider via its OpenAI-compatible endpoint
parallax regex "<.*>" --target "<a>x<b>" --forbidden-spans 3:4 \
  --critic openai --base-url https://openrouter.ai/api/v1 --model "google/gemini-2.5-flash"

All settings also read from the environment (PARALLAX_CRITIC / PARALLAX_MODEL / PARALLAX_API_KEY / PARALLAX_BASE_URL) — see .env.example.

What this is (and is not)

The render-and-critique loop is not new — it exists in several verticals (maps, motion trajectories, plotting, GUI agents). Parallax's contribution is different: a general, artifact-agnostic primitive with SQL-result-shape and regex-highlight adapters, plus a controlled study the field skips.

We do not claim "rendering beats text," that images universally help, or that the idea is ours. The honest claim is a model-conditional representation effect, scoped to the cells we actually run, with nulls reported. The factorial decomposition that would justify any why-it-works statement is a separate, ongoing research program (M2) — see docs/NOVELTY.md for the full do-not-claim list and docs/RED-TEAM.md for why the design is shaped this way.

Documentation

Doc What
docs/PRD.md Product requirements, users, scope/non-goals
docs/INTERFACE.md crosscheck() + the adapter contract + worked adapter specs
docs/ARCHITECTURE.md Stack, package layout, sandboxing, model routing
docs/TASKS.md TDD-first task list (M1 library MVP + M2 study), risk register
docs/EVAL.md The M2 crux — pre-registration-grade factorial decomposition design
docs/NOVELTY.md Prior-art verdict, defensible claim, do-not-claim list
docs/RED-TEAM.md The adversarial findings that reshaped the contribution
docs/CITATIONS.md Citation-integrity pass — 6 fixes needed before publish

Metadata

Release files for parallax-verify 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for parallax-verify 0.1.1
File Size Uploaded Provenance Actions
parallax_verify-0.1.1.tar.gz 121.6 kB Without provenance Details for parallax_verify-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for parallax-verify 0.1.1
File Interpreter ABI Platform Actions
parallax_verify-0.1.1-py3-none-any.whl Python 3 none any Details for parallax_verify-0.1.1-py3-none-any.whl

Total release size: 160.4 kB

Release files / parallax_verify-0.1.1.tar.gz

Download URL parallax_verify-0.1.1.tar.gz
Size 121.6 kB
Tags Source
SHA-256 checksum
How to use checksums
1a92540d59e9b1be590ce3db09c37edf2b88e54babe723b2cc047cb66d68931a
BLAKE2b-256 checksum
How to use checksums
6e65390bc2f8f3575328c95a88899f0c47410d8adfe03d3ce04bebda41e851ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Release files / parallax_verify-0.1.1-py3-none-any.whl

Download URL parallax_verify-0.1.1-py3-none-any.whl
Size 38.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2ef5b02053a2501e0729dec302090fce6464bc7b21c4312ee687c69b47c7392a
BLAKE2b-256 checksum
How to use checksums
1eada8e2a12a83db4d0e32382b17f556ad16c6c1e9040bea7012d515cb950818
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.14

Security for parallax-verify 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page