Luxe

Guided Review

Reading a change as a story rather than a wall of diff.

Agents write code faster than anyone can form a theory of it. Guided Review exists to close that gap: it reads the change back to you in the order it makes sense, grounded in what the agent was actually asked and actually did, so your attention goes to judgement rather than reconstruction.

It is not an inspection checklist. Finding bugs and checking logic is mostly the agents’ job now; what does not automate away is judgement — does this fit the system, does it solve the problem, what did it cost elsewhere. So there is no “reviewed 0/92” counter and no per-hunk ticking. Instead the review tells you what actually needs you, and accounts for the rest with named evidence:

What needs you
  14 changes need your review
  78 accounted for
      58  covered by `cargo nextest run`
      20  formatting / generated / lockfile churn

Accounting is a label, never a disappearance. Every one of those 78 is still in the diff, and each carries the reason on its own hunk header — covered by \cargo test`,not written by the agent— because a reviewer who cannot see that the harness decided something cannot disagree with it. The only thing that folds is mechanical churn (formatting, generated files, lockfiles, moves), and it folds into a row *in the diff* that says how much it stands for and opens onEnteror a click.f` opens all of it at once. A risk signal always outranks an excuse — a credential-shaped line, a weakened gate or a blindly-edited file stays on your list even where a test passes, because “a test passed” is not the question those ask.

A review is your change, not the directory. Everything Luxe writes while it works — sessions, logs, caches, screenshots, tool output, task and review memory — lives under .luxe/, which ignores itself in Git and never appears in a review or a changes list. It is a byproduct of the tool running, not something you asked for. If your repo carries other bookkeeping nobody reviews, review.exclude takes project-relative globs (["PROGRESS.md", "docs/plan/**", ".pi/**"]; *, **, ? and a trailing / for a directory). Excluded files are counted and named in the Brief — a review that shows less than the diff has to say so.

Open it with /diff (or Ctrl+G, the palette, or the dock’s “Review changes”). Sources: /diff working tree · /diff turn · /diff base <ref> · /diff commit <oid>. A base/commit review reads its own commit messages for its title and intent — finished work has no turn to account for it, and its messages are the closest thing to authored intent that exists. Only the commits in the reviewed range, and the Brief’s heading counts them (What these 3 commits say) so it is never mistaken for project history; a lone commit whose subject already titles the review says nothing twice.

Review the increment, not the accumulation. Nothing demands a review after every turn; what you have already walked is remembered per project, so the next review leads with N changes are new since your last review and the rest joins the accounted-for block. The dock keeps the count in view and the row above the composer offers Ctrl+G when a turn ends with unreviewed work — quietly, never a modal.

Three surfaces, and it lands on the first:

  • Brief — what you asked for (or what the commits say), what the agent did in its own words, how it was verified, the budget above, and what the guide might not tell you. That last list is short by construction, because the walkthrough is the review and this is only what its narrator — the same agent whose work you are reading — cannot be relied on to raise about itself: a credential-shaped addition, a weakened gate (a deleted #[test], an added #[ignore], a CI or deny.toml edit), a file it edited without ever reading, changes it did not write. It cannot report the middle two (it does not know), and has every reason to soften the others. Luxe sees all four because it is the harness. Enter on a row opens that hunk — and each one also appears beside the file in the walkthrough, where c turns it into a question the agent has to answer.

    Coverage gaps and fan-in are deliberately not here. A missing test is work, so it goes to the agent directly (see the test-gap advisory above), and the file you are reading carries its own relied on by 7 · no covering test note. Ranking them as warnings made the reviewer translate a list back into a prompt, and buried the four signals that matter under hundreds of rows.

    What remains is tuned to stay believable rather than to catch everything. A token that reads as a placeholder is not called a credential; the loose password = … rule needs real code and a real literal, so a function parameter named token and a sentence about secrets stay quiet, while a published key format (sk-, ghp_, AKIA…) is reported wherever it appears, comment or not. Gate heuristics look for attributes and lint flags only where code lives, not in prose or serialized data that quotes them. When a fixture genuinely has to look real, mark the line — // luxe:allow-secret (or gitleaks:allow, pragma: allowlist secret, nosec) exempts that one line and nothing else. Test files are not exempt wholesale: a credential committed to a test is still committed.

  • Walkthrough — the narrated read. Each section leads with its own prose at full width: what the change is, what it causes, then one sentence per file, then that file’s diff beneath it. It steps in the order the guide chose — the schema before the logic that consumes it, the call sites before the tests — which is the order the work was reasoned in and the whole reason a walkthrough beats a file list. Space/n carries on into the next section, taking the narration with it; step 7/23 says how far through you are; z folds the prose away if you want every row for code.

  • Map — the whole change on one page: every section, its files with status and counts, and the hunks of whichever file the cursor is on. It is for the questions the other two do not answer — what else is in here, how big is it, did anything land somewhere unexpected. Enter reads the row.

Chapters are model-authored but structurally guaranteed: the model may only reorder and explain items it was given, and a validator rejects any guide that invents, omits, or duplicates a hunk. Prose and section labels are treated as advisory (clipped, defaulted) while the item set is strict — being lenient about packaging is why a fenced JSON reply no longer costs you the entire narrative. Reviews open immediately on deterministic sections and upgrade in place, so the diff never waits on a provider, and a large change is chaptered in bounded, concurrent batches rather than falling back to generic buckets exactly when guidance matters most.

Diffs render side by side wherever the pane can give each column a readable width (review.diff_layout, Ctrl+B to flip). Side-by-side is a view of the same rows, so scrolling, selection, comments, search and clicks behave identically in both — including w (soft-wrap), where a wrapped pair takes its longer column’s height and pads the shorter one. Word-level emphasis bolds only what changed inside a replaced line, in the review and in edit/write tool cards alike.

Feedback is a conversation, not a form:

Key
aAsk about the selection — answered, never edited
cComment (severity travels as priority, never as routing)
Alt+USend the batch, with a preview of exactly what travels
vWhat changed here — the anchor before and after, before you verify
rVerify / resolve / reopen · c on a comment replies to it
kSkim — one row per hunk, for a change too large to read front to back
Alt+↵Finish: Accept · Accept and commit · Request fixes · Comment only

Accepting can turn the review into history: one commit per chapter, staged by hunk from the reviewed revision, with the chapter’s reasoning as the commit body and a review trailer. It refuses outright if the index is dirty or the working tree has moved on, and it never pushes or amends.