# Prism

> Dispatch multiple independent agents to answer the SAME complete question from different analytical lenses, then synthesize. Reach for this by default, without waiting to be asked, when redundant cross-model judgment could change the decision: ambiguous architecture/design tradeoffs, high-stakes or hard-to-reverse changes, competing root-cause hypotheses, or failure-mode-sensitive reviews — and whenever you would otherwise spawn 2+ independent reviewers for one question. Skip for trivial lookups, deterministic transforms, routine small edits, mechanical syncs, and single-correct-answer tasks. With no leading number, autonomously decide N and gpt-pro from the question every time (N=1 is the bottom-rung anchor, never a lazy default); with an explicit number (e.g. `prism 2 1`), honor it verbatim and skip auto-sizing. There is no reasoning-effort knob. Scale above the anchor only when decision risk justifies the 7N-agent cost.

- Skill: `chrisliu298/prism-2` (Agent Skill, multi-file: 4 files)
- Install (CLI): `npx skillmds@latest add chrisliu298/prism-2`
- Raw SKILL.md: https://api.skillmd.com/api/skills/chrisliu298/prism-2/raw
- Safety review: pending (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: chrisliu298 (https://skillmd.com/u/chrisliu298)
- Updated: 2026-09-22
- Page: https://skillmd.com/skills/chrisliu298/prism-2

---


# Prism

**Claude-only.** If `ANTHROPIC_BASE_URL` contains `deepseek`, `xiaomimimo`, or `z.ai`, this skill is unavailable — stop and tell the user: "prism is Claude-only; a non-Claude session cannot orchestrate other models." Prism dispatches parallax via [[relay]], which itself refuses from non-Claude sessions.

Prism sends the **same complete question** to multiple independent agents. Each agent answers the **entire question end-to-end**. The only thing that changes between agents is the **lens**: what they prioritize and what tradeoffs they weigh more heavily.

## Core Principle

**Prism is redundancy, not division of labor.** Every agent gets the full question, full scope, and full deliverable. The lens changes **emphasis**, not **coverage**. If agents own different files, sections, or outputs, that is division of labor, not Prism.

Convergence across diverse lenses is high-confidence signal; divergence surfaces tradeoffs that need explicit resolution.

## Structure

| Tier | Tool | Role |
|------|------|------|
| Self | (none) | Your own analysis while agents run |
| Subagents | **Agent** | Same-model agents (Claude), one Agent call each |
| **Parallax — Codex** | **Bash** (`relay call --to codex`) | Cross-model agents via relay to GPT-5.5 (effort always `xhigh`) |
| **Parallax — Grok Build** | **Bash** (`relay call --to grok-build`) | Cross-model agents via relay to xAI Grok Build (effort always `high`) |
| **Parallax — Grok Composer** | **Bash** (`relay call --to grok-composer`) | Cross-model agents via relay to xAI Composer 2.5 (fast; no effort knob) |
| **Parallax — DeepSeek** | **Bash** (`relay call --to deepseek`) | Cross-model agents via relay to DeepSeek V4 Pro |
| **Parallax — MiMo** | **Bash** (`relay call --to mimo`) | Cross-model agents via relay to Xiaomi MiMo-V2.5-Pro |
| **Parallax — GLM** | **Bash** (`relay call --to glm`) | Cross-model agents via relay to Zhipu/z.ai GLM-5.2 (pinned to `max` reasoning, like DeepSeek) |
| **GPT-Pro (opt-in)** | **Bash** (`gpt-pro < prompt.md`) | Additive ChatGPT Pro Extended lenses via [[gpt-pro-relay]] — opt-in **Deep-Reasoning / Research-Grounded** tier; launcher **composed by `prepare`**, fired orchestrator-direct; **not** a relay peer / not in the parallax fan; slow + quota-burning; off by default (see GPT-Pro tier) |

**Symmetric baseline — all seven models at `N=1`** (the bottom-rung anchor, not a fire-without-thinking default): self + 1 Claude subagent + 1 each of Codex, Grok Build, Grok Composer, DeepSeek, MiMo, GLM = **7 dispatched + self** (8 perspectives). This shape is what an autonomous no-config decision *lands on* for the minimal case and what an explicit-but-partial config *fills omitted dimensions from* — a bare invocation always routes through the decision procedure (see **Choosing N and gpt-pro**) and never emits this by shortcut. Required dispatch: **`N` Agent calls + 1 backgrounded `prism-launch parallax` call that fans out the `6N` relay calls** (manual fallback: `6N` separate Bash relay calls). Self does not count. There is **no reasoning-effort choice** — Codex always runs at `xhigh`, Grok Build always at `high`, and the other peers have no knob. All seven models are always included at the chosen `N`; the only way to deviate — exclude a tier or give a tier its own count — is an explicit natural-language modification (see Invocation Shorthand). **GPT-Pro is the lone exception to "always included": it is a separate opt-in tier with its own count `M`, default `0`, never part of the symmetric `N` — added only via the optional second number (see Invocation Shorthand → GPT-Pro tier).**

### Invocation Shorthand

Two layers: a dead-simple positional form for the symmetric common case, and natural language for any deviation.

**Positional — `prism [N] [M] <question>`:**
- `N` — how many of **each** of the seven models (Claude subagents, Codex, Grok Build, Grok Composer, DeepSeek, MiMo, GLM). Integer `≥ 1`, default `1`; reject `0` (to drop tiers, use a natural-language exclusion). Total dispatched = `7N`; self does not count.
- `M` — how many **gpt-pro** lenses to add (the opt-in premium tier). Integer `≥ 0`, default `0`; **independent of `N`** (never dispatched unless given). Naming it is the cost consent — it burns real Pro quota and runs 5–20 min/lens (see GPT-Pro tier).

**There is no reasoning-effort token.** The two tunable tiers are fixed at their top setting on every run — **Codex `xhigh`, Grok Build `high`** — and the rest have no knob (Grok Composer none; DeepSeek/MiMo/GLM always at max). You never choose effort.

The parser consumes **up to two leading whitespace-delimited integers**, left-to-right: the first is `N`, the second is `M`. The first token that is **not** a bare integer begins the question; everything from there is verbatim question text. Examples: `prism 2 3 Why X?` → `N=2`, `M=3`, question "Why X?"; `prism 2 Why X?` → `N=2`, `M=0`; `prism migration plan` → question "migration plan".
- **Escape:** if the question's own first word is a bare integer, put `--` first — everything after `--` is question text (`prism -- 3 reasons to refactor?`). `--` is not a config token; it leaves zero config tokens, so the invocation routes to the autonomous decision (see **Config-presence gate**), not a pinned baseline.

Examples (a leading number skips auto-sizing; **no** number → autonomous decision):
- `prism Why does X?` — no number → autonomously decide `N` and `M` from the question.
- `prism 2 Why does X?` — explicit: 2 of each, no gpt-pro → 14 dispatched + self = 15 perspectives; no auto-sizing.
- `prism 2 3 Why does X?` — explicit: 2 of each **plus** 3 gpt-pro lenses → 14 + 3 + self = 18 perspectives.
- `prism 1 1 Bet-the-company call?` — 1 of each + 1 gpt-pro lens → 7 + 1 + self = 9 perspectives.
- `prism -- 2 reasons to refactor?` — the `--` makes the leading `2` question text, so the question is "2 reasons to refactor?" and `N`/`M` are decided autonomously.

**The second number is gpt-pro (`M`).** It adds `M` ChatGPT Pro Extended lenses via [[gpt-pro-relay]] on top of the normal lineup, independent of `N` and defaulting to `0` (never dispatched unless given). Accepted natural-language synonyms in the leading config zone are `<M> gpt-pro` and `plus <M> gpt-pro lenses`. Resolve it like any other config modifier, then dispatch per the GPT-Pro tier section.

**Natural-language modifications.** The positional form always dispatches all seven models symmetrically; to deviate, state it in words **in a leading config clause before the question** (config is parsed only up to where the question begins — a modifier buried *after* the question starts is treated as question text, not config). Treat a phrase as a modification only when it pairs a **tier name with a config action** (a count, or an exclusion word like no/skip/without); a bare tier name inside the question — e.g. *"why is there no DeepSeek fallback?"* — is **not** a modification, so do not strip or reinterpret it. Resolve the modifications into an explicit per-tier count before launch. Supported:
- **Exclude a model** — "no DeepSeek", "skip Grok Composer", "without mimo" → that tier's count = `0` (simply not dispatched; warn the user that dropping a whole lineage reduces cross-model diversity).
- **Per-model count** — "2 Codex, 1 of the rest", "3 Claude subagents" → the named tier overrides `N`; unnamed tiers keep `N`.
- **Combinations** — "2 of each but no Grok Composer".
- **Asymmetric example**: "2 of each, but no Grok Build or Grok Composer, and 2 DeepSeek" → Claude 2, Codex 2, Grok ×0, DeepSeek 2, MiMo 2, GLM 2. (Effort is never specified — Codex runs `xhigh`, Grok Build `high`, always.)

`N` (and the optional `M`) set the symmetric baseline; named modifications override specific tiers on top of it (an explicit exclusion overrides the "all seven always included" default; on conflicting clauses the more specific or later one wins). Resolve to a final per-tier table, then dispatch exactly that — every tier with resolved count > 0 MUST be dispatched at that count (do not skip, substitute, or defer; exception: `relay` unavailable → substitute a same-model subagent carrying that tier's lens and warn). You — the orchestrator — own resolving the shorthand and NL into the dispatch records; `prepare` then validates the *authored* dispatch file and emits the authoritative manifest counts, but it cannot know your intended `N`, so confirm the resolved shape matches your intent before running it (Pre-Launch Check #5).

### Config-presence gate (the routing decision)

Before anything else, the parser's result routes the invocation down exactly one of two paths — keyed on **what the parser resolved**, never on a re-reading of the raw string:

- **Any config token present** — a leading integer (`N`, or `N M`) *or* a leading natural-language modification (a tier name paired with a count or exclusion) → **honor it verbatim and skip auto-sizing.** `M` defaults to `0` and all seven tiers are included unless a modification says otherwise — a *stated default*, not an autonomous decision. Do not consult the decision table; do not "improve" the user's `N` or `M`. `prism 2 <q>` is `N=2`/`M=0`, full stop.
- **Zero config tokens** (the question begins immediately; `--` also lands here, since it leaves no tokens) → **autonomously decide** `N` and `M` per **Choosing N and gpt-pro**. Run that decision every time; the absence of a number is never permission to fire the baseline without reasoning.

A bare tier name *inside the question* ("why is there no DeepSeek fallback?") is **not** a config token (see Natural-language modifications) — it does not flip the gate to the explicit path.

### Choosing N and gpt-pro (decide autonomously — don't ask)

**This section runs only when the Config-presence gate routed you here — i.e. the invocation had no leading number.** (If the user gave any explicit number or modification, the gate already pinned the shape; honor it and skip this table.) On a bare question, pick `N` and `M` yourself — do not ask. Use the smallest run whose extra perspectives could change the action, confidence, or rollback plan. **Default down:** each `+1` to `N` adds a full seven-model slate and slower synthesis; never raise `N` just to "be thorough." **Start at the bottom rung and justify each step up:** land on the *lowest* row whose situation actually matches; if you cannot name the specific extra perspective an added agent would contribute, you are at the anchor. Auto-deciding is mandatory, but "decide" means *size to the question*, not *size up*.

| Situation | N |
|---|---|
| Bottom rung (anchor — start here) — a Prism-worthy decision one good pass could settle | 1 |
| Several viable options or stakeholder tradeoffs where breadth matters more than depth | 2 |
| Exceptional blast radius, or a decision still underdetermined after framing | 3 |
| Beyond N=3 | only on explicit user request or documented exceptional complexity — note the larger run shape in the launch status line, not as a gate |

**gpt-pro (default M=0 — usually skip):** gpt-pro is the opt-in premium tier on **two co-equal axes — Deep Reasoning and Research-Grounded Judgment** (top-tier reasoning, plus the only tier that browses by default in a front-loaded run). It spends real ChatGPT Pro quota and runs 5–20 min/lens, so the seven-model lineup is the default and gpt-pro is the rare exception — never the reflex for an ordinary Prism-worthy call. Auto-add **one** lens (`M=1`) only when the decision is genuinely high-stakes or hard-to-reverse **and** one of those two axes is the binding constraint: the hardest reasoning in the run, or live external research whose value is the research-plus-reasoning synthesis the standard tiers can't match. **"Needs the web" alone is not enough** — every tier browses, so route to gpt-pro only when research must be reasoned over at the strongest tier. Give gpt-pro the posture matching the binding axis: a **Deep-Reasoning** or **Research-Grounded** lens (see GPT-Pro tier). Use **`M=2`** (one Deep-Reasoning + one Research-Grounded) only for an exceptional, multi-faceted high-stakes call; never auto-add more than 2. You fire it yourself and just launch — do **not** pause for a confirmation or abort gate.

Note the resolved shape and its source (`<auto-sized|explicit> · N=<n>[, M=<m> gpt-pro (~5–20 min)] — <total> agents + self`) as a one-line status line as you launch — not a confirmation gate; never pause for the user to approve or redirect.

### Parallax (cross-model agents)

Parallax is dispatched via `relay` to **different models** (Codex, Grok Build, Grok Composer, DeepSeek, MiMo, GLM). Invoke `relay` directly — not via a subagent that calls relay. The value of each tier is model diversity:

- **Codex** — GPT-5.5 lineage, agentic code-review strength; prism always runs it at `xhigh`.
- **Grok Build** — xAI's independent lineage (`grok-build`), distinct from Anthropic/OpenAI; prism always runs it at `high`.
- **Grok Composer** — xAI's fast variant (`grok-composer-2.5-fast`), **same lineage as Grok Build**, no effort knob. Treat the two Grok tiers as **one vendor slot** for diversity lenses; reach for Composer for a fast xAI take.
- **DeepSeek** — an independent open-weight lineage (V4-Pro); always runs at `max` (DeepThink).
- **MiMo** — a third independent open-weight lineage (Xiaomi MiMo-V2.5-Pro); no effort knob.
- **GLM** — a fourth independent lineage (Zhipu/z.ai GLM-5.2), reached via z.ai's Anthropic-compatible endpoint; pinned to `max` reasoning (`reasoning_effort: max`, like DeepSeek), no prism effort knob.

**Tier strength and lens fit (heuristic for lens assignment, not a routing rule):** rough reasoning-capability ranking — **gpt-pro (when opted in) ≳ Claude ≈ Codex > {Grok Build (provisional, unbenchmarked — verify before the heaviest-reasoning lens), MiMo ≳ DeepSeek, GLM (provisional, unbenchmarked here)} > Grok Composer**. gpt-pro is the preferred home for **two co-equal premium posture families — Deep-Reasoning and Research-Grounded** — when present: every tier can reach the web (see below), so don't route to gpt-pro for browsing alone; route when the value is top-tier reasoning, or live research synthesized with top-tier reasoning (its reasoning-plus-research is the deepest, and it's the only tier browsing by default in a front-loaded run) — but it is opt-in, so never drop DeepSeek, MiMo, or GLM to make room for it, and discount gpt-pro+Codex *agreement* somewhat (both OpenAI-family, correlated blind spots) even though gpt-pro is its own tally lineage. Weaker tiers lose no value: each independent lineage catches blind spots the others share. This informs lens *placement*, not inclusion:

- **Subtle hard-reasoning lenses on risk-bearing questions** (Adversarial / Falsification / Disconfirming on a technical proposal where finding the non-obvious attack is the deliverable): prefer Claude subagent or Codex (which always runs at `xhigh`). If exactly one lens carries the heaviest reasoning load and it lands on a parallax tier, you've under-resourced the most decision-relevant role; when it must land on one anyway, prefer MiMo over DeepSeek.
- **Lenses where the value is a different prior** (Outsider, First-Principles, Reframe, Breadth-Weighted, Lateral-Generative, Stakeholder): give these to DeepSeek, MiMo, and GLM. Their independent lineages are the asset; raw reasoning depth is not the bottleneck.
- **Parallax lenses comparably hard:** no swap needed.
- **Never drop DeepSeek, MiMo, or GLM to "upgrade" a run.** Lineage diversity is non-substitutable; default tier inclusion is unchanged.

Assignment only — in synthesis, every tier's dissent keeps full cross-model weight (discount weak reasoning, never the model label). Revisit the ranking when the named model versions look stale.

Assign each tier a lens that maximizes diversity. **Default to orthogonal exploratory lenses** (Breadth-Weighted, Depth-Weighted, Outsider, First-Principles, Reframe) — these almost always extract more from cross-model diversity than a second attack angle. **Reach for an adversarial lens (Adversarial, Falsification, Disconfirming) only when it is much more valuable than another orthogonal lens would be** — i.e., the deliverable hinges on finding a non-obvious flaw, attack, or failure mode, and no other dispatched lens is already covering that ground. When that bar is met, put it on the parallax tier best suited to the reasoning load (see "Tier strength and lens fit"); otherwise skip it. When using multiple parallax tiers, give each a distinct lens — never assign the same lens to two of Codex, DeepSeek, MiMo, GLM, or the Grok tiers (that wastes a perspective). Treat grok-build + grok-composer as **one** vendor slot: don't give them two different diversity lenses as if independent (they share the xAI lineage). And don't stack two adversarial lenses unless the task genuinely demands independent attack frames.

Don't tailor the prompt body per peer — Prism sends the **same shared prompt** to every model (the launcher templates handle the only per-peer difference: Codex `<goal>` style vs CO-STAR XML), so you may skip the [[relay]] skill's per-peer prompting guides here. What matters is shared-prompt **quality** — an outcome-first shared packet (Full Question + Context) and sharp, distinct lens descriptions; optimize that, not per-model fit.

**Web access is not a dispatch concern — don't verify it.** Every peer can reach the web (WebFetch + WebSearch both work, save two minor gaps — DeepSeek's WebFetch and MiMo's WebSearch — neither load-bearing here; see [[relay]]). By default Prism front-loads all evidence in the shared packet (that's what Reference Materials is for), so agents reason over the provided Context rather than browsing — **but when the task requires live online research, each agent researches independently instead** (see the **Independent research for live-research tasks** rule under Shared Context). Either way, do **not** spend a dispatch-time step checking what the relay transport supports — it's settled and irrelevant to a well-built run.

**Relay call syntax (exact)** — the command shapes Prism must emit:

```bash
# Codex parallax (prism always uses --effort xhigh)
relay call --to codex --name <slug> --effort xhigh <<'BODY'
<prompt content here>
BODY

# Grok Build parallax (prism always uses --effort high)
relay call --to grok-build --name <slug> --effort high <<'BODY'
<prompt content here>
BODY

# Grok Composer parallax (no --effort — fast model, no effort knob)
relay call --to grok-composer --name <slug> <<'BODY'
<prompt content here>
BODY

# DeepSeek parallax (no --effort — always max)
relay call --to deepseek --name <slug> <<'BODY'
<prompt content here>
BODY

# MiMo parallax (no --effort — no effort knob)
relay call --to mimo --name <slug> <<'BODY'
<prompt content here>
BODY

# GLM parallax (no --effort — no effort knob)
relay call --to glm --name <slug> <<'BODY'
<prompt content here>
BODY
```

Use a lowercase slug for `--name` (e.g., `prism-adversarial`). Prism always passes Codex `--effort xhigh` and Grok Build `--effort high` (the top tier — no other value); never pass `--effort` or model flags on DeepSeek, MiMo, GLM, or Grok Composer (none has an effort knob). For all other invocation rules — `--name` required, `--to codex` as the default, non-empty heredoc, no model flags — follow the [[relay]] skill rather than restating them. For concurrency (backgrounding, timeouts), follow relay's Async / Parallel section.

**Inspecting Parallax results:** Read only the `.res.md` response file — never the `.log` sidecar (token-heavy stderr; the relay script's Bash output already surfaces failure diagnostics).

If `relay` is unavailable, replace all Parallax tiers with same-model subagents and warn the user. Each substitute carries the lens that tier was already assigned — do not re-decide by task category. Relay being unavailable does not change whether adversarial coverage is valuable for this question.

**Constraint leakage risk (CRITICAL):** Relay peers may recurse unless the anti-recursion rule is explicit, early, and repeated. You MUST:
1. Put the anti-recursion warning at the top of every launcher prompt, before the file-read instruction.
2. Preserve the Constraints section verbatim in the shared context file — do not summarize or abbreviate.
3. Ensure the prohibition appears in both each launcher (short form) and the shared file (full form).
4. Tell each peer to ignore loaded skill descriptions for the dispatching/side-effecting skills (prism, relay, gpt-pro-relay, deep-research) — read-only analysis skills stay available.

Without these redundant prohibitions, the peer treats the task as a fresh request and recurses.

**Effort for Parallax (fixed — no selection):** Codex always runs at `xhigh`, Grok Build always at `high`. There is no effort token and no per-run choice. Never emit Codex `high` or Grok Build `xhigh` (wrong per-tier word); DeepSeek/MiMo/GLM/Grok Composer never carry `--effort`.

### Subagents

Same-model agents dispatched via the Agent tool. Each gets a distinct lens. **Prism subagents are logical leaf nodes** — their prompts must forbid subagent spawning, dispatching-skill invocation (prism, relay, gpt-pro-relay, deep-research, any cross-model dispatch), and side effects, while permitting read-only analysis skills (see Constraints in the Shared Packet Template). Launch all agents concurrently before starting self-review.

### GPT-Pro tier (opt-in)

Dispatched only when the user gave a second number `M` > 0 (see Invocation Shorthand); default count `0`. gpt-pro is **orchestrator-direct**: `prism-launch` composes each launcher for you, but **you fire the `gpt-pro` calls yourself** (a shell script must never launch them, and they need the Bash-tool envelope + the cross-turn reattach lifecycle only the orchestrator can drive). It is **not** a relay peer and **not** in the `parallax` fan: never add it to `relay/peers.json` or the parallax batch — a 5–20 min gpt-pro lens would block the fast relay results, and relay's *read-a-file → write `.res.md`* contract is nothing like gpt-pro's *inline-everything → stdout → run-id-recovery* shape. `prism-launch` **composes and collects** gpt-pro (in `prepare`, `results`, `digest`); it never reimplements gpt-pro's transport, run-ids, reattach recovery, exit-code demux, or the macmini concurrency semaphore — those stay wholly in the [[gpt-pro-relay]] wrapper, which `prism-launch` shells out to (exactly as `parallax` shells to `relay`).

**Declare gpt-pro lenses in the dispatch file — `prepare` composes the launcher; you never hand-inline.** Add one `Type: gptpro` record per lens (`Lens` + `Lens-Desc`, optional `Posture: deep-reasoning|research-grounded`), plus the reference list to inline. gpt-pro runs in a web tab and **cannot read any local file**, so `prepare` (after it froze the packet) builds a self-contained launcher `<id>-gptpro-<slug>.md` = the committed `templates/launcher-gptpro.tmpl` header (carrying the instruction-inversion guard as line 1 + the lens) **+ the frozen packet verbatim + every reference file's contents** under `### <path>` headers **+ the grounding and calibration blocks** (from `templates/shared-gptpro-{grounding,calibration}.md`). Templated, not hand-retyped → no drift, no dropped guard.

```text
Shared-Packet: /tmp/prism-<id>.md
Reference: /abs/path/1            # authoritative inlining list (repeatable). Omitted → falls back to
Reference: /abs/path/2            # the packet's `### Reference Materials` bullets. `Reference: none` = packet only.

Type: gptpro
Lens: Deep-Reasoning
Lens-Desc: weigh the hardest end-to-end reasoning
Posture: deep-reasoning
```

`prepare` resolves the reference list (the dispatch `Reference:` keys are authoritative when present, else the packet's `### Reference Materials`), validates it **fail-closed** (no list at all, a directory entry, a missing/unreadable/whitespace path, or a single ref / composed prompt over gpt-pro's 1 MB cap each abort `prepare` *before* any quota), composes each launcher, and prints the exact backgrounded launch command per lens. The 1 MB overflow message says to shrink the shared packet for *all* agents, not to give gpt-pro a weaker context.

**Lenses:** gpt-pro has **two first-class posture families — Deep-Reasoning and Research-Grounded** (every tier can browse, but gpt-pro is strongest when the task needs top-tier reasoning, or live research synthesized with top-tier reasoning — see Tier strength and lens fit). Give it a Deep-Reasoning **or** Research-Grounded posture, each lens still answering the full question. Default pair for `M=2`: one Deep-Reasoning (`Depth-Weighted`, or `Falsification`/`Adversarial` on a risk-bearing question) + one `Research-Grounded` (web-tilted) — distinct axis families. For `M=1` pick the posture matching the binding axis (not reasoning by default); for `M≥3` add distinct postures (`First-Principles`, `Temporal`, `Empirical`), never copies. Names must stay distinct across the whole run.

**Launch** the exact line `prepare` printed — one backgrounded Bash call per lens, concurrently with the parallax fan and the Agent calls:

```bash
gpt-pro < /tmp/prism-<id>-gptpro-<slug>.md > /tmp/prism-<id>-gptpro-<slug>.res.md 2> /tmp/prism-<id>-gptpro-<slug>.log
```

with `run_in_background: true`, `timeout: 7260000` (fall back to `~/.claude/skills/gpt-pro-relay/scripts/gpt-pro` if not on PATH). Each is its **own** completion notification — `prepare`'s printed count already includes them. **Collect** with `prism-launch results <manifest>` and `prism-launch digest <manifest>`: both read the gpt-pro lane alongside parallax (a pending lens surfaces its `run_id` for reattach; gpt-pro is its own `GPT-Pro` digest lineage). **Recovery:** each gpt-pro Bash call is a *Bash* task, so reading its `.output` for the `run_id=` / `recover_with=` line is correct and required — the "never read a subagent's `.output`" rule does **not** apply here. Follow [[gpt-pro-relay]]'s exit-code table: 0 use it; 124/255 reattach with the literal run-id (`gpt-pro --run-id <id>`, same envelope); 1 inspect `reason`, don't blindly resubmit; 2 fix the call (no quota burned); 3 engine cap, terminal; 4 fresh-submit (only after a reattach proved never-landed). Up to `GPT_PRO_MAX_PARALLEL` (default 3) run in parallel; extra calls queue — **never raise the cap from prism** (account anti-abuse risk). When cleaning up, `prism-launch clean <id>` refuses to delete a lens whose `.log` shows a `run_id` but has no `.res.md` yet (a possibly-live worker) unless `--force`.

## Side-Effect Safety

Dispatched agents are **read-only** — no edits, commits, deploys, or external side effects. The only exception is the relay response file (`.res.md`) named in a `Reply:` directive. The primary agent may implement changes after synthesis if the user requested a deliverable.

## Shared Context

Build one shared evidence packet (Full Question + Context; `prepare` injects the canonical Constraints and How-to-answer) before composing prompts. Prefer compact digests over full file dumps. Write it to a temporary file once; every agent receives a short launcher prompt referencing this file plus its unique lens. If the packet cannot be duplicated cleanly across all agents, the task is too large for Prism.

**Reference materials (REQUIRED):** Before building the shared packet, identify all reference materials relevant to the question — CLAUDE.md files, READMEs, config files, documentation, skill definitions, style guides, or any file an agent would need to reason about the task. Include the **absolute paths** of these files in the Context section of the shared packet so every agent can read them. Agents cannot discover references on their own; if a path is not listed, the agent will not consult it.

**Independent research for live-research tasks:** When the task requires *online* research — current facts, fresh docs, version-specific behavior, anything not already settled in the repo or the packet — do **not** have the orchestrator research it once and front-load the findings. A single front-loaded evidence set makes every agent reason over identical sources, collapsing the cross-lens / cross-model diversity that is Prism's whole point into a shared-evidence monoculture. Instead, state the research need in the shared packet — the **exact** live question(s) to answer, plus any **common evidence floor** (the few authoritative sources/search targets every agent must consult and may *extend*, never replace) — and direct **each agent to research the live question independently, research to sufficiency rather than exhaustion** (a few authoritative sources suffice; the synthesizer weighs reasoning, not citation count), **and cite *and list* the sources it used** (every peer can browse — only DeepSeek's WebFetch and MiMo's WebSearch are missing, each keeping the other tool; see Parallax). This stays **redundancy, not division of labor** — every agent still answers the *whole* question end-to-end; only evidence-gathering is parallelized. The common floor keeps divergence comparable — it then means an agent found *more*, not that agents read disjoint facts — so divergence in *what* they find becomes signal, not just divergence in how they reason over fixed facts, and the listed sources let synthesis distinguish an information asymmetry from a genuine reasoning split and spot-check any fact a dissent rests on (Step 4 / Step 5). Still front-load **stable** context — repo files, CLAUDE.md, configs, the question itself — via Reference Materials; the carve-out is for *live* evidence only and is never an excuse to skip the shared packet. If a research-tilted lens lands on a tier that can't reach a needed source (e.g. a WebFetch-only page on DeepSeek), route that lens to a full-web tier or front-load that one source **for all agents** (label it a provided source, not independently-discovered evidence, so the packet stays identical) — never front-load it for the gapped tier alone, which would re-create the very asymmetry this rule manages.

### Shared Packet Template

Write this to `/tmp/prism-<unique-id>.md` using the Write tool (one call, before any dispatch). Use a unique identifier (e.g., timestamp + random suffix) to prevent collisions between concurrent Prism runs. **Write only Full Question + Context (with Reference Materials)** — `prism-launch prepare` injects the canonical `## Constraints` block (the verbatim read-only / anti-recursion text) and the `## How to answer` block (presentation guidance: verdict-first, cite sources, no preamble) when they're absent, so you never hand-copy them and they can't be fat-fingered.

```
## Full Question

{User's COMPLETE question/task, unchanged. Identical across all agents.}

## Context

{Shared evidence packet. Identical across all agents.}

### Reference Materials

{List absolute paths to every file relevant to the question — CLAUDE.md, READMEs, configs, docs, skill files, style guides, etc. Agents MUST read these before answering.}

- /path/to/relevant/file1
- /path/to/relevant/file2
- ...

### Live research (omit unless the task needs live online facts)

{If the answer depends on facts outside the repo/packet, name the EXACT question(s) each agent must research independently, plus any common-floor sources to start from. Do NOT front-load the findings. Each agent researches independently and cites + lists its sources. See the Independent research for live-research tasks rule.}
```

`prepare` appends the canonical `## Constraints` (from `templates/shared-constraints.md`) and `## How to answer` (from `templates/shared-how-to-answer.md`) if you omitted them — idempotent, so a re-run won't double either. (If you want a bespoke version of either, include that `##` section yourself and prepare leaves it untouched; Constraints additionally fails closed if a bespoke block drops the anti-recursion guard, How-to-answer carries no such safety load.) The packet is **frozen** once `prepare` runs — do not modify it after, since dispatched agents read it live. `Write` already confirms success, so no read-back is needed.

### Launcher Templates

Launcher prompts are committed template files in `templates/` alongside this SKILL.md, with `{{PLACEHOLDER}}` slots filled by `prism-launch` at dispatch time (see "Dispatch via prism-launch") — so the boilerplate is never hand-regenerated, only lens-specific values are emitted.

**Template files:**

| File | Used for | Slots |
|------|----------|-------|
| `templates/launcher-subagent.tmpl` | Agent tool (same-model subagents) | `SHARED_PACKET_PATH`, `LENS_NAME`, `LENS_DESC` |
| `templates/launcher-relay-codex.tmpl` | Bash relay, Codex (GPT `<goal>` style) | `SHARED_PACKET_PATH`, `LENS_NAME`, `LENS_DESC` |
| `templates/launcher-relay-costar.tmpl` | Bash relay, any CO-STAR peer (DeepSeek, MiMo, GLM, Grok Build, Grok Composer) | `SHARED_PACKET_PATH`, `LENS_NAME`, `LENS_DESC` |

There is **one relay template per prompting style**, not per peer — `prism-launch` selects it by the `template` field in `relay/peers.json` (Codex uses a GPT `<goal>` style; DeepSeek/MiMo/GLM/Grok share the CO-STAR `launcher-relay-costar.tmpl`). The anti-recursion warning is the top line of every template. Adding a relay target's **transport and launcher selection** is one `relay/peers.json` stanza — `prism-launch` validates and renders it registry-driven, no script edit needed; add a new template file only for a genuinely new prompting style. (A new **symmetric default tier** additionally needs the hardcoded surface updated: the scaffold peer loop, the `--preset` lens lists, and the `peershape` display order in `prism-launch`, plus the model/agent counts throughout these docs.)

### Dispatch via prism-launch

You do **not** render templates or hand-write relay heredocs. The `prism-launch` script (`~/.claude/skills/prism/scripts/prism-launch`) owns the cross-model half of dispatch: it renders every launcher from the templates, validates dispatch shape mechanically, and fans all relay calls out as **one** backgrounded process that waits for every peer and writes a single structured result.

**Invoke it by its absolute path** — `~/.claude/skills/prism/scripts/prism-launch` — not the bare name. The bare command is on PATH only when the shell inherited the `.zshenv`-injected PATH; a sandboxed/non-zsh/reset-env agent shell will not have it, and a bare-name miss must NOT trigger the manual fallback. The absolute path is the script's real install location, so its templates resolve correctly with no extra handling. (`prism-launch` resolves its sibling `relay` the same way — by install path, falling back to PATH — so `parallax` dispatches even when `relay` is not on PATH either.)

It cannot dispatch Claude subagents (only Claude can invoke the Agent tool, never `claude -p`) — so you still issue the subagent Agent-tool calls yourself.

**You write one line-oriented dispatch file with the Write tool** (one record per agent — never a shell heredoc), then run two commands. For the symmetric default, run `~/.claude/skills/prism/scripts/prism-launch scaffold --n <N>` first — it prints a ready-to-fill skeleton (correct records, canonical model order, and the fixed Codex `x` / Grok Build `h` effort tokens) so you only replace the `FILL` lens names + descriptions. Add `--preset review|design|diagnosis|compare|research|decision|writing` to also pre-fill seven lenses by task type (N=1) — then just edit them to taste. (Asymmetric runs — per-tier counts, exclusions — have no scaffold; author those records by hand.) The dispatch format is plain `Key: value` lines in blank-line-separated records: no braces, commas, quoting, or escaping, so a free-text lens description can't break it the way hand-authored JSON can. Authoring the config as raw JSON is no longer the default — writing literal text with the Write tool is what removes the escaping surface.

Write `/tmp/prism-<id>.dispatch` with the **Write tool**:

```text
Shared-Packet: /tmp/prism-<id>.md

Type: parallax
To: codex
Name: adversarial
Effort: x
Lens: Adversarial
Lens-Desc: weigh the strongest attacks on the proposal

Type: parallax
To: grok-build
Effort: h
Lens: First-Principles
Lens-Desc: weigh how this looks rebuilt from the goal up

Type: parallax
To: grok-composer
Lens: Pragmatist
Lens-Desc: weigh the fastest workable path

Type: parallax
To: deepseek
Lens: Falsification
Lens-Desc: weigh what evidence would prove this wrong

Type: parallax
To: mimo
Lens: Outsider
Lens-Desc: weigh how a newcomer would approach this

Type: parallax
To: glm
Lens: Temporal
Lens-Desc: weigh how this holds up over time — lifecycle, sequencing, reversibility

Type: subagent
Lens: Simplicity
Lens-Desc: weigh the approach that requires the fewest moving parts
```

This is the canonical default — all seven models at `N=1`. The two tunable tiers always carry the top effort: **Codex `Effort: x`** (xhigh) and **Grok Build `Effort: h`** (high) — there is no other value. (`prism-launch` accepts the single-letter or full word and normalizes `x`→`xhigh`, `h`→`high`.)

Format rules: `Shared-Packet:` appears once. Each record starts at `Type: parallax|subagent|gptpro`; blank lines separate records and `#` begins a comment. For `parallax`, `To:`/`Lens:`/`Lens-Desc:` are required, `Name:` is optional (defaults to the slugified lens), and `Effort:` is set only on the two tunable peers and is always the top tier — Codex `x` (`xhigh`), Grok Build `h` (`high`); `-` or omitted = none — DeepSeek/MiMo/GLM/Grok Composer take none. For `subagent`, only `Lens:`/`Lens-Desc:` are needed. For `gptpro`, `Lens:`/`Lens-Desc:` are required and `Posture:` (`deep-reasoning`/`research-grounded`) is optional — `To:`/`Name:`/`Effort:` are rejected; a top-level repeatable `Reference: <abs-path>` key (outside any record) is the authoritative inlining list for gpt-pro lenses (omit it to fall back to the packet's `### Reference Materials`; `Reference: none` = inline only the packet). Everything after the **first** `:` is the literal value, so quotes, colons, `>`, `<`, and single braces in a description are fine — except the reserved tokens `</` and `{{` (the injection guard), which `prepare` rejects with a rephrase hint.

```bash
# 1) prepare (foreground): compiles the dispatch file into the canonical config,
#    validates packet/shape/effort/injection, renders all launchers, writes
#    <id>-manifest.json. Fails loudly if anything is off.
~/.claude/skills/prism/scripts/prism-launch prepare --dispatch /tmp/prism-<id>.dispatch

# 2) parallax (ONE backgrounded Bash call, run_in_background: true): fans out all
#    relay calls, waits for all, writes <id>-result.json with per-peer status.
#    (prepare prints this command with the same absolute path — copy it from there.)
~/.claude/skills/prism/scripts/prism-launch parallax /tmp/prism-<id>-manifest.json
```

`prepare` normalizes the dispatch file into `/tmp/prism-<id>-config.normalized.json` (the canonical JSON, kept for audit) before validating. **`prepare --config <config.json>` remains supported** as the machine/escape-hatch interface — it accepts that same JSON shape directly, also written with the Write tool (literal content, never a heredoc). Both paths run identical validation, rendering, and manifest logic; `--dispatch` is just a literal-text front-end that removes the JSON-escaping surface.

`prepare` prints each subagent launcher's **contents inline** (delimited, with its path) — copy the contents straight into an Agent-tool call, no separate Read needed. It validates `lens`/`lens_desc` (rejecting `</` and `{{` as an injection guard; comparison operators like `>` are allowed), enforces distinct lens names and distinct relay `name`s, rejects `effort` on DeepSeek/MiMo/GLM/Grok Composer, and rejects a `shared_packet` path containing whitespace. `parallax` writes `<id>-result.json` (`{id, expected, succeeded, failed, results:[{to,name,status,res,log}]}`) and prin

…(truncated)
