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 ordeny.tomledit), 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.Enteron a row opens that hunk — and each one also appears beside the file in the walkthrough, wherecturns 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 testnote. 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 namedtokenand 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(orgitleaks: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/ncarries on into the next section, taking the narration with it;step 7/23says how far through you are;zfolds 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.
Enterreads 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 | |
|---|---|
a | Ask about the selection — answered, never edited |
c | Comment (severity travels as priority, never as routing) |
Alt+U | Send the batch, with a preview of exactly what travels |
v | What changed here — the anchor before and after, before you verify |
r | Verify / resolve / reopen · c on a comment replies to it |
k | Skim — 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.