/cross-research
Two-phase multi-model research. Phase A fans codex+gemini in parallel (benchmarks + citations angles); Phase B synthesises via fresh Claude session. Usage: /cross-research [--with <id> | list | compare] <target>
$ npx -y skills add FerroxLabs/ijfw --agent claude-codeHow it fires
How this command gets triggered: by you, by Claude, or both.
- Fires itselfClaude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/cross-research
Context preview
What this command does when you run it.
Two-phase multi-model research. Phase A fans codex+gemini in parallel (benchmarks + citations angles); Phase B synthesises via fresh Claude session. Usage: /cross-research [--with <id> | list | compare] <target>
Command definition
cross-research.mddescription: "Two-phase multi-model research. Phase A fans codex+gemini in parallel (benchmarks + citations angles); Phase B synthesises via fresh Claude session. Usage: /cross-research [--with <id> | list | compare] <target>"
allowed-tools: ["Read", "Write", "Bash", "Grep"]
Deep-research triangulation from multiple agents. Solves "a single model's training data is a single lens." Parallel fan-out collects independent claim sets, then a synthesis pass merges them into a consensus/contested/unique matrix with open questions surfaced. All three requests, responses, and the merged output archive automatically.
Subcommands
| Form | Behavior | |------|----------| | `/cross-research` | **Zero-arg auto-pick.** Detect target from git state (staged → unstaged → last commit). Pick default roster (Codex=benchmarks, Gemini=citations). Generate Phase A requests. | | `/cross-research <target>` | Same auto-pick, named target. | | `/cross-research --with <id> [target]` | Override an auditor slot: `codex`, `gemini`, `opencode`, `aider`, `copilot`. Target optional. | | `/cross-research list` | Show roster with self marker. No requests generated. | | `/cross-research compare` | Read Phase A responses, build Phase B synthesis request, fire it, render matrix, archive. |
Smart target auto-detection (bare `/cross-research`)
When invoked without a target, run this detection cascade and use the first non-empty result:
1. **Staged changes** -- `git diff --cached --name-only` 2. **Unstaged changes** -- `git diff --name-only` 3. **Last commit** -- `git diff HEAD~1 --name-only` 4. If all empty: print the roster and ask "what topic would you like researched?"
Report which step succeeded:
Cross-research target auto-detected: 2 staged file(s)
mcp-server/src/cross-dispatcher.js
mcp-server/test-cross-dispatcher.js
(Override with /cross-research <path> or /cross-research --with <id> <path>.)
If >5 files, group in request body but list all paths. If a single file >2000 lines, use the diff hunks rather than the full file.
The natural-language phrase **"research this across models"** / **"multi-model research"** fires the intent router (`mcp-server/src/intent-router.js`), which nudges Claude to invoke `/cross-research` automatically -- same auto-detect flow runs.
Default flow -- Donahoe Trident (don't make me think)
Caller is one perspective. **Default is two independent research streams feeding one synthesis.** The Trident yields: independent evidence collection in parallel, then a single merge pass that exposes what each model knew, what they agreed on, and where they diverge.
When invoked, do this in order:
1. **Probe roster.** Call `pickAuditors({ count: 2, env: process.env })` from `audit-roster.js`. Returns `{ picks, missing, note }` -- picks are installed AND non-self.
2. **Show a TODO surface** in chat:
Cross-research plan
[ ] Step A.1: Generate Wave A requests (codex=benchmarks, gemini=citations)
[ ] Step A.2: Fire codex in background
[ ] Step A.2: Fire gemini in background
[ ] Wait for both completions
[ ] Step B.1: Generate Wave B synthesis request (claude=synthesis)
[ ] Step B.2: Fire synthesis
[ ] Step B.3: Render consensus/contested/unique matrix
[ ] Step B.4: Archive all requests + responses + merge3. **Ask the user once** which combo to run:
Auditors detected and ready: codex, gemini.
Run cross-research:
[A] codex only (benchmarks angle)
[B] gemini only (citations angle)
[C] Both -- recommended (Donahoe Trident, enables full synthesis)
[D] Cancel / pick customDefault suggestion: **C (Both)** when >=2 installed. Synthesis (Phase B) requires both Phase A responses; if only one auditor runs, Phase B renders a partial synthesis and flags the gap.
4. **If only one installed:**
> "Only `<id>` is installed locally. The full Trident shines here -- two > independent research streams remove single-model blind spots before synthesis. > Install one of the available auditors (opencode, aider, etc.) to unlock the > complete picture."
Then offer to run the single-auditor partial flow.
5. **Fire Wave A in background** (see Wave A section below).
6. **After Wave A completes**, run `/cross-research compare` (or fire it automatically when both background jobs notify).
7. **Fire Wave B synthesis** via fresh Claude session (see Wave B section below).
8. **Render matrix** from `mergeResponses('research', responses)`.
9. **Archive** all files to `.ijfw/cross-audit/archive/<ts>-research/`.
Auditor picking
node --input-type=module -e "import('./mcp-server/src/audit-roster.js').then(m => console.log(m.formatRoster()))"Default pick order (first non-self): `codex → gemini → opencode → aider → copilot → claude`.
Research role assignment is mode-aware via `assignRoles('research', roster, self)` in `cross-dispatcher.js`:
- `codex` → `benchmarks` angle
- `gemini` → `citations` angle
- Synthesis always goes to a **fresh Claude session via `claude -p`** -- never the
caller's own session, even if self=claude, to prevent circularity.
---
Wave A -- Parallel fan-out
Step A.1 -- Generate Phase A requests via the dispatcher
Run one node call per auditor:
node --input-type=module -e "
import('./mcp-server/src/cross-dispatcher.js').then(m =>
process.stdout.write(m.buildRequest('research', '<target>', 'codex', 'benchmarks'))
)" > .ijfw/cross-audit/request-research-codex.mdnode --input-type=module -e "
import('./mcp-server/src/cross-dispatcher.js').then(m =>
process.stdout.write(m.buildRequest('research', '<target>', 'gemini', 'citations'))
)" > .ijfw/cross-audit/request-research-gemini.md> **Note:** `buildRequest` is synchronous and returns a string -- do NOT `.then()` it. Wrap it in `process.stdout.write(...)` directly.
Replace `<target>` with
Read more
description: "Two-phase multi-model research. Phase A fans codex+gemini in parallel (benchmarks + citations angles); Phase B synthesises via fresh Claude session. Usage: /cross-research [--with <id> | list | compare] <target>" allowed-tools: ["Read", "Write", "Bash", "Grep"]
Deep-research triangulation from multiple agents. Solves "a single model's training data is a single lens." Parallel fan-out collects independent claim sets, then a synthesis pass merges them into a consensus/contested/unique matrix with open questions surfaced. All three requests, responses, and the merged output archive automatically.
Subcommands
| Form | Behavior | |------|----------| | `/cross-research` | **Zero-arg auto-pick.** Detect target from git state (staged → unstaged → last commit). Pick default roster (Codex=benchmarks, Gemini=citations). Generate Phase A requests. | | `/cross-research <target>` | Same auto-pick, named target. | | `/cross-research --with <id> [target]` | Override an auditor slot: `codex`, `gemini`, `opencode`, `aider`, `copilot`. Target optional. | | `/cross-research list` | Show roster with self marker. No requests generated. | | `/cross-research compare` | Read Phase A responses, build Phase B synthesis request, fire it, render matrix, archive. |
Smart target auto-detection (bare `/cross-research`)
When invoked without a target, run this detection cascade and use the first non-empty result:
1. **Staged changes** -- `git diff --cached --name-only` 2. **Unstaged changes** -- `git diff --name-only` 3. **Last commit** -- `git diff HEAD~1 --name-only` 4. If all empty: print the roster and ask "what topic would you like researched?"
Report which step succeeded:
Cross-research target auto-detected: 2 staged file(s) mcp-server/src/cross-dispatcher.js mcp-server/test-cross-dispatcher.js (Override with /cross-research <path> or /cross-research --with <id> <path>.)
If >5 files, group in request body but list all paths. If a single file >2000 lines, use the diff hunks rather than the full file.
The natural-language phrase **"research this across models"** / **"multi-model research"** fires the intent router (`mcp-server/src/intent-router.js`), which nudges Claude to invoke `/cross-research` automatically -- same auto-detect flow runs.
Default flow -- Donahoe Trident (don't make me think)
Caller is one perspective. **Default is two independent research streams feeding one synthesis.** The Trident yields: independent evidence collection in parallel, then a single merge pass that exposes what each model knew, what they agreed on, and where they diverge.
When invoked, do this in order:
1. **Probe roster.** Call `pickAuditors({ count: 2, env: process.env })` from `audit-roster.js`. Returns `{ picks, missing, note }` -- picks are installed AND non-self.
2. **Show a TODO surface** in chat:
Cross-research plan
[ ] Step A.1: Generate Wave A requests (codex=benchmarks, gemini=citations)
[ ] Step A.2: Fire codex in background
[ ] Step A.2: Fire gemini in background
[ ] Wait for both completions
[ ] Step B.1: Generate Wave B synthesis request (claude=synthesis)
[ ] Step B.2: Fire synthesis
[ ] Step B.3: Render consensus/contested/unique matrix
[ ] Step B.4: Archive all requests + responses + merge3. **Ask the user once** which combo to run:
Auditors detected and ready: codex, gemini.
Run cross-research:
[A] codex only (benchmarks angle)
[B] gemini only (citations angle)
[C] Both -- recommended (Donahoe Trident, enables full synthesis)
[D] Cancel / pick customDefault suggestion: **C (Both)** when >=2 installed. Synthesis (Phase B) requires both Phase A responses; if only one auditor runs, Phase B renders a partial synthesis and flags the gap.
4. **If only one installed:**
> "Only `<id>` is installed locally. The full Trident shines here -- two > independent research streams remove single-model blind spots before synthesis. > Install one of the available auditors (opencode, aider, etc.) to unlock the > complete picture."
Then offer to run the single-auditor partial flow.
5. **Fire Wave A in background** (see Wave A section below).
6. **After Wave A completes**, run `/cross-research compare` (or fire it automatically when both background jobs notify).
7. **Fire Wave B synthesis** via fresh Claude session (see Wave B section below).
8. **Render matrix** from `mergeResponses('research', responses)`.
9. **Archive** all files to `.ijfw/cross-audit/archive/<ts>-research/`.
Auditor picking
node --input-type=module -e "import('./mcp-server/src/audit-roster.js').then(m => console.log(m.formatRoster()))"Default pick order (first non-self): `codex → gemini → opencode → aider → copilot → claude`.
Research role assignment is mode-aware via `assignRoles('research', roster, self)` in `cross-dispatcher.js`:
- `codex` → `benchmarks` angle
- `gemini` → `citations` angle
- Synthesis always goes to a **fresh Claude session via `claude -p`** -- never the
caller's own session, even if self=claude, to prevent circularity.
---
Wave A -- Parallel fan-out
Step A.1 -- Generate Phase A requests via the dispatcher
Run one node call per auditor:
node --input-type=module -e "
import('./mcp-server/src/cross-dispatcher.js').then(m =>
process.stdout.write(m.buildRequest('research', '<target>', 'codex', 'benchmarks'))
)" > .ijfw/cross-audit/request-research-codex.mdnode --input-type=module -e "
import('./mcp-server/src/cross-dispatcher.js').then(m =>
process.stdout.write(m.buildRequest('research', '<target>', 'gemini', 'citations'))
)" > .ijfw/cross-audit/request-research-gemini.md> **Note:** `buildRequest` is synchronous and returns a string -- do NOT `.then()` it. Wrap it in `process.stdout.write(...)` directly.
Replace `<target>` with
IJFW — It Just F*cking Works. Ferrox Labs' local-first infrastructure for AI coding agents: shared memory, smart routing, multi-AI cross-audits, disciplined workflow.
Repo: FerroxLabs/ijfw
Other commands on ijfw.
- /compress
Compress a memory/context file into terse form. Saves ~40-50% tokens per session. Usage: /compress <filepath>
Open command - /consolidate
Dream cycle -- promote patterns, prune stale, reconcile contradictions, optionally promote to global.
Open command - /cross-audit
Second-model review. Picks an auditor (codex/gemini/opencode/aider/copilot), excludes the caller, writes a prompt to paste, reads the response back. Usage: /cross-audit [--with <id> | list | compare] <target>
Open command - /cross-critique
Adversarial multi-angle critique. All three auditors fire in parallel (codex=technical, gemini=strategic, claude=ux). Counter-args ranked by rebuttal survival score, not raw severity. Usage: /cross-critique [--with <id> | list | compare] <target>
Open command - /doctor
Run IJFW health check (files, MCP server, hooks, memory, caps, framing)
Open command - /handoff
Generate or load a session handoff. Usage: /handoff [create|resume]
Open command

