ADLC
Toolkit

parallax

Fans N independent readers over a request and surfaces only the divergences as questions humans must answer.

parallax

ADLC phase: P1 Interrogate · Gate: the measured ambiguity score is at or below threshold (spec/edge), or the routed answers agree (route).

The ADLC lifecycle, with P1 highlighted. Read the theory for P1

What it defends against

A single model reading an ambiguous request commits to one interpretation and states it with total confidence. The ambiguity never surfaces; it just silently becomes a decision. parallax replaces that introspection with measurement: it fans N independent cheap-tier readings, diffs them, and reports only where they disagree. The ambiguity score (divergences / (divergences + agreements)) turns "is this spec clear?" into a number you can gate on.

Usage

adlc parallax --request "text" | --file req.md | --edge T1 T2 | --route "question" [flags]

Three modes: spec (default, fans readers over a raw request), edge (--edge T1 T2, authors the contract implied between two tickets), and route (--route, answers a mid-build question and checks that the answers agree).

FlagDescription
--request <text> / --file <path>Spec mode: request text inline or from a file (stdin if neither).
--edgeEdge mode: takes two ticket IDs as positionals.
--route <text>Route mode: the question to route.
--context <file>Route mode: context file, repeatable.
--tickets <path>Tickets file for edge mode (default .adlc/tickets.json).
--n <int>Fan width: number of independent readings (default 3, minimum 2).
--allow-partial-fanAccept a verdict computed from fewer readings than --n requested. Off by default: a narrowed sample biases the score toward a pass.
--threshold <0-1>Ambiguity gate threshold (default 0.25).
--tier cheap|mid|frontierOverride the LLM tier.
--jsonMachine-readable output (score + divergences).
--prompt-onlyPrint the exact prompts and exit 0. No API key needed.
--record-verdict <file|->With --prompt-only: record the operator's answer into .adlc/manifest.jsonl via gate-manifest. Requires --prompt-only and --ticket.
--ticket <id>Ticket this run is evidence for. Required with --record-verdict — an unbound record can satisfy any ticket's P1 gate.

What a verdict requires

parallax refuses to certify a reading it did not actually take. Two guards, both operational errors (exit 1), never a score:

  • Off-schema divergence payload. The mid-tier divergence call is asked for {agreements: [...], divergences: [...]}. A refusal object, a truncated {}, a bare array or a {result: ...} wrapper used to fall through to "zero divergences, zero agreements", which scores 0 and passes the gate — an unanalysed spec reported as unambiguous. Such a payload is now refused.
  • Shrunken fan. The score is measured across --n independent readings, so a fan narrowed by rate limits, timeouts or unparseable JSON measures a smaller sample and scores systematically LOWER — it biases toward a pass. When fewer readings survive than were requested, the verdict is refused unless --allow-partial-fan is given. requested and used appear in both --json and --questions-json so a machine consumer can see the effective width instead of having to notice a warnings entry.

--n 1 is rejected at parse time: one reading can never be compared against another, so it could only ever spend an API call on the way to an error.

Exit codes

0: gate passes. Ambiguity score at or below threshold (spec/edge), or answers equivalent (route).1: operational error (bad input, missing file, network failure, too few readings).2: gate fails. Ambiguity score exceeds threshold, or route answers diverge.

Example

$ adlc parallax --request "Add a login page" --n 5
# Parallax spec analysis

## Agreement set (draft spec)
- Email + password fields, submit button

## Divergences — answer these
**Q1: Social sign-in?**
  A) email/password only
  B) also Google OAuth

**Ambiguity score:** 0.33 (threshold 0.25) — gate FAILS ✗
exit 2

Go deeper

packages/parallax · Why unexamined ambiguity is dangerous: Tests Are the Spec.

On this page