# Independent Journey Review

Audience: AI coding agents first.

## Iron law

Reviewer reconstructs execution path from repository source. Journey claims are hypotheses, never evidence.

Creator MUST NOT author, edit, or repair review report. Reviewer ID MUST differ from journey `created_by`. Any journey or declared-source edit invalidates hashes and requires new reviewer.

**Rubric is FROZEN. A finding MUST cite one of the ten check IDs below. Concern outside the ten checks → append to `checks[].note` as non-blocking observation; NEVER a finding, NEVER a fail. Do NOT invent new defect classes.**

## Reviewer task

1. Read journey, `scan-problems.md`, and every declared source.
2. Reconstruct actor-to-terminal path independently. Use repository graph first when available.
3. Read complete trace ranges plus imports controlling auth, writes, external calls, responses, and terminal rendering.
4. Enumerate every condition, response, throw, catch, transport failure, partial write, retry, stale state, and concurrency outcome.
5. Compare independent trace against journey branch-by-branch.
6. Partition failures by dispatch/commit phase: before dispatch, pre-write, partial-write, post-commit response loss, and post-response client failure. Reject any combined phase.
7. Verify every visible oracle is business text/value/accessibility state; reject CSS classes, styling tokens, translation keys without literal-source evidence, and optimistic state that cannot distinguish in-flight from committed success.
8. Verify exact response bodies include every serialized conditional/optional field for declared fixture state.
9. Verify each blocker represents exactly one missing capability with matching resolution.
10. Fail on one contradicted, omitted, combined, unreachable, or falsely UNKNOWN claim.
11. Write report JSON. Do not modify journey.

## Required checks

| ID | Falsification target |
|---|---|
| `evidence_truth` | Every citation supports exact claim in surrounding context |
| `actor_reachability` | Primary actor reaches same trigger/component; permission probe uses same trigger and exact named actor state |
| `client_control_flow` | Every UI/client decision, catch, transport phase, optimistic state, decode failure, and refetch mapped |
| `request_response_contract` | Method, path, payload, status, full serialized body including conditional fields, redirect, and no-response cases exact |
| `boundary_authority` | Authn, role, owner, parser, and disclosure boundaries exact |
| `writes_constraints` | Actual writes, transactions, uniqueness, locks, commit phase, partial state, and fresh reads exact |
| `terminal_render` | Response/state drives stable business literal/value/accessibility state; no CSS-only oracle |
| `guard_atomicity` | One condition, transport/commit phase, and outcome per guard/branch; no unions |
| `blocker_scope` | One blocker ID per missing fixture/seam/decision; no unrelated blocker |
| `risk_consistency` | Branches, forbidden outcomes, retries, concurrency, and risk rows agree |

## Report path

`docs/user_journeys/reviews/UJ-NNN.review.json`

## Report schema

```json
{
  "schema_version": 1,
  "journey_id": "UJ-NNN",
  "journey_sha256": "64-lowercase-hex",
  "source_sha256": {
    "project/relative/source.ts": "64-lowercase-hex"
  },
  "reviewer": {
    "kind": "native-subagent",
    "id": "exact-reviewer-agent-id"
  },
  "verdict": "pass",
  "checks": [
    {
      "id": "evidence_truth",
      "passed": true,
      "evidence": ["project/relative/source.ts:42"],
      "note": "Independent finding, not copied journey prose."
    }
  ],
  "findings": []
}
```

Include all ten check IDs exactly once. Each check requires non-empty source evidence and independent note.

Evidence accepts `project/relative/source.ts:42` or inclusive `project/relative/source.ts:42-57`. Use ranges only for complete local control-flow context; never cite a range instead of naming decisive line in note.

Fail report uses `"verdict":"fail"`, sets failed checks to `false`, and records concrete findings:

```json
{
  "severity": "critical|major|minor",
  "check_id": "client_control_flow",
  "claim": "Journey claim being disproved",
  "evidence": ["project/relative/source.ts:42"],
  "required_fix": "Exact contract correction"
}
```

Severity definitions (use exactly):

- `critical` — contradicted claim, unreachable path, false oracle, wrong actor/boundary. Always a finding.
- `major` — omitted reachable branch/guard, imprecise response/durable contract. Finding.
- `minor` — wording, formatting, redundancy within a truthful claim. NOT a finding; record in `checks[].note`.

Fail report is diagnostic input for the creator's bounded repair loop (max 3 rounds — see SKILL.md step 8). Creator archives it to `reviews/UJ-NNN.review.fail-<round>.json` before repairing; never deletes, never edits. Reviewer never repairs journey or rewrites own report into pass.

## Hash command

```text
sha256sum docs/user_journeys/<actor>/<journey>.md
```

Copy first field exactly into `journey_sha256`. Add SHA-256 for EVERY `source_specs` file to `source_sha256`, keyed by exact project-relative path. Report becomes stale after any journey or source edit.

## Pass gate

Pass only when all checks true and findings empty. Uncertainty is a finding unless journey records exact bounded UNKNOWN with matching blocker.
