<!--
SPDX-FileCopyrightText: Amolith <amolith@secluded.site>

SPDX-License-Identifier: CC0-1.0
-->

# Crosscheck

Crosscheck is an [OpenProse 14][OpenProse]\* workflow that has a main LLM agent
orchestrate parallel subagents to review code, come up with findings, validate
those findings, and provide a report.

[OpenProse]: https://github.com/openprose/prose/tree/v0.14.0

I hate that there's terminology, but I think there has to be 😭 Maybe I'll come
up with clearer terms for the non-OpenProse things that won't require
explanation.

For Prose:

- OpenProse: Markdown files ("contracts") that turn the LLM agent you're
  interacting with into a sort of "virtual machine" that executes those Markdown
  contracts.
- Prose Complete: describes any LLM harness, like Crush, Claude Code, etc., with
  the required tools to execute OpenProse.
- Prose VM: the main, front-and-center conversation/session/thread with an LLM
  agent in a Prose Complete harness.

For Crosscheck:

- Runner: either a subagent in your Prose VM or a standalone Prose Complete
  harness invoked by your Prose VM through its shell tool.

\*Specifically OpenProse 14 because later versions change drastically, adding a
whole "reactor" thing that replaces Prose Complete harnesses, and OpenProse's
harness agnosticism is a huge reason I like it. So we're sticking with when it
was good :)

Run Crosscheck from the repository or worktree being reviewed:

<!-- rumdl-disable MD013 -->

```bash
# simple use
prose run ~/where/you/cloned/crosscheck/src -- subject: "current diff"
# with preferences
prose run ~/where/you/cloned/crosscheck/src -- subject: "git diff main" preferences: "crush run --yolo with minimax, kimi, qwen, and deepseek reviewers, no mimo"
```

<!-- rumdl-enable MD013 -->

- `subject`: current diff, ref range, branch, paths, PR description, or a
  natural-language review target
- `preferences`: optional runner/model/focus/exclusion/local-testing guidance

## Setup

You'll need [OpenProse 14][OpenProse]'s agent skill and standard-library
dependency cache. This installs both from the `v0.14.0` zip archive, replacing
any existing copies at those two paths.

<!-- rumdl-disable MD013 -->

```bash
set -euo pipefail

OPENPROSE_TAG=v0.14.0
tmpdir="$(mktemp -d)"

curl -fsSL \
  "https://github.com/openprose/prose/archive/refs/tags/${OPENPROSE_TAG}.zip" \
  -o "${tmpdir}/openprose.zip"

unzip -q "${tmpdir}/openprose.zip" -d "${tmpdir}"
srcdir="$(find "${tmpdir}" -mindepth 1 -maxdepth 1 -type d -name 'prose-*' | head -n 1)"
test -n "${srcdir}"

mkdir -p \
  "${HOME}/.agents/skills" \
  "${HOME}/.agents/prose/deps/github.com/openprose"

rm -rf \
  "${HOME}/.agents/skills/open-prose" \
  "${HOME}/.agents/prose/deps/github.com/openprose/prose"

cp -R "${srcdir}/skills/open-prose" \
  "${HOME}/.agents/skills/open-prose"

cp -R "${srcdir}" \
  "${HOME}/.agents/prose/deps/github.com/openprose/prose"

rm -rf "${tmpdir}"
```

<!-- rumdl-enable MD013 -->

The first `cp` installs the `open-prose` skill. OpenProse has a global
dependency cache of Markdown (seems crazy, but I guess it makes sense?) and the
second copy puts the `std/...` and `co/...` deps in the right place.

Other dependencies:

- `bash`, `curl`, `unzip`, and ordinary shell utilities such as `mktemp`,
  `find`, `head`, `mkdir`, `rm`, and `cp` for the setup command above.
- At least one Prose Complete harness like [Crush][Crush], [Pi][Pi], [Amp][Amp],
  [Claude Code][Claude Code], or [Codex][Codex] on your PATH that can load the
  `open-prose` skill and give the LLM filesystem and shell access.
  - You'll interact with the Prose VM and it must either use built-in subagents
    or invoke itself/another Prose Complete harness through the shell tool. If
    you want a read-only review, the Prose Complete harness should have an
    effective read-only mode.
- Model/provider credentials configured for the runner. Local models _can_ work
  well for this, but unless you have stellar hardware, the quantisations you'll
  be limited to might yield very poor results.
- The VCS CLI needed by your `subject`. The examples above use `git`, if your
  repo is `jj`, you'll need that.

Microsandbox is not required yet, but it will be for the escalation path where
reviewers and validators can build and execute adversarial probes inside
isolated environments.

[Crush]: https://github.com/charmbracelet/crush
[Pi]: https://github.com/earendil-works/pi/tree/main/packages/coding-agent
[Amp]: https://ampcode.com
[Claude Code]: https://claude.com/product/claude-code
[Codex]: https://github.com/openai/codex
