Skip to content

Each review is a session folder in the repository under review. The folder keeps every input, prompt, reviewer output and state file of the review, so a review can resume after the MCP server or the terminal has exited. Nothing leaves the machine except the reviewer’s own requests to its model provider, and the dashboard’s update check.

.cross-review/sessions/<skill>-<yyyymmdd>-<NNN>/
  • <skill> is the skill name, for example review-impl.
  • <yyyymmdd> is the date in UTC when the session was created.
  • <NNN> counts the sessions of that skill and day from 001.
.cross-review/
├── .gitignore ← "*": everything in .cross-review is ignored by git
├── config.json ← workspace settings (optional)
├── plans/ ← plans written by loop-plan
└── sessions/
└── review-impl-20261016-001/
├── state.json ← session state, updated at each step
├── rounds.json ← one entry per round
├── meta.json ← only when the session was finalized
├── prompt.txt ← the prompt of the latest round
├── prompts/
│ └── round-001.txt ← the rendered prompt of each round
├── inputs/
│ └── round-001.md ← the placeholder input of each round, as received
├── output.jsonl ← the reviewer's event log for the current round
├── review.md ← the review text of the current round
├── final.txt ← the current round's result, as JSON
├── runner-deadline.json ← only when the runner deadline passed
└── outputs/
├── output-round-001.jsonl
├── review-round-001.md
├── final-round-001.json
└── times-round-001.jsonl
File Written by Content
state.json The runner, at each step Skill, reviewer, working folder, current round, process ids, thread id, the reviewer’s model, effort and sandbox, the stall settings, the mode and skills folder, where each setting came from, the calling client, and when the session ended and how (end_outcome: finalized or stopped).
rounds.json The runner One entry per round: round, started_at, completed_at, elapsed_seconds, status, verdict, issues_found.
meta.json end (through finalize) Skill, reviewer, runner version, effort, sandbox, number of rounds, final verdict, timing per round, and a timestamp. Optional custom_notes and issues come from the finalize input. Written only for a session that was finalized.
prompt.txt The runner The prompt sent to the reviewer in the latest round.
prompts/round-NNN.txt The runner The rendered prompt of round NNN.
inputs/round-NNN.md The runner The placeholder input of round NNN exactly as it was received. The dashboard shows it.
output.jsonl The reviewer’s CLI The reviewer’s event log for the current round.
review.md The runner The review text of the current round.
final.txt The runner The current round’s poll result as JSON: status, parsed review, and recovery fields.
runner-deadline.json The runner A marker written when the runner deadline passes: the reason, the timeout in seconds, the round and when it was marked. Poll reads it to tell a runner deadline from other failures.

When a new round starts, the runner copies the previous round’s files here before the next round replaces the current ones:

File Content
output-round-NNN.jsonl The round’s event log.
review-round-NNN.md The round’s review text.
final-round-NNN.json The round’s result.
times-round-NNN.jsonl Timing rows for the event log, one per change in the number of complete lines: [complete lines, epoch seconds]. The dashboard uses them to time each activity.

When a session is created, the runner writes .cross-review/.gitignore if it is missing. It contains *, so the whole folder is ignored. When track_plans is on, the file keeps plans/ tracked instead. A .gitignore that you edited by hand is left alone.

  • A session’s files are not removed by the runner. Delete a session folder by hand when you no longer need it.
  • Sessions from before cross-review v15 (when the project was called codex-review) cannot be resumed.
  • The dashboard only reads these files. Its settings and avatars are kept in your home folder, not in the repository. See the dashboard guide.