Skip to content
ExamsLibraryFor agentsConnect your agent

The review table

beginner·8 min·Markdown for agents

What this lesson teaches

Read and write a UI review as Before | After | Why rows, scan code against the checklist, and scope a review to what a change actually broke.

  1. 1Three columns, every time
  2. 2The checklist: a scan before taste
  3. 3Reviewing a change, not a codebase

Here is a review you have probably received: "The animation could be smoother, the transition is a bit long, consider a different easing curve."

You read it twice. You still don't know what to type.

✕ Prose review

The modal could be smoother. The transition is a bit too long and the scale starts too small. Consider a different easing.

✓ Table review

transition: transform 0.6s ease → 0.25s cubic-bezier(0.25, 1, 0.5, 1). Under 300ms feels responsive.
scale(0) → scale(0.95). Nothing real appears from nothing.

Three columns, every time

The skill makes every UI review a table with three columns. Emil Kowalski calls this format non-negotiable, because it forces concrete diffs instead of advice.

ColumnWhat goes in it
BeforeThe real line from your code, quoted. Never paraphrased.
AfterThe replacement. Same job, better feel.
WhyOne short sentence, ending with the skill node that goes deeper.

If you can't write the Why in one sentence, you're probably reaching. Drop the row.

  1. One issue per row

    Three problems in one line of CSS get three rows.
  2. Order by impact

    The thing that breaks keyboard users goes above the hairline.
  3. Nothing actionable in the prose

    Prose around the table is context only: "Three issues in the modal entrance:".
  4. Nothing to fix is a valid review

    "Looks good, nothing to change" beats invented nitpicks.

The checklist: a scan before taste

Before anyone argues about taste, there is a floor. The is thirty-nine common mistakes, each with a quick way to find it and a fix: transition: all, scale(0), ease-in on UI, a removed focus ring, z-index: 9999, 100vh on phones, placeholder names like "John Doe".

Edit the CSS below. Each rule is one of those quick checks; fix a line and its row disappears.

6 checklist rows apply
BeforeAfterWhy
transition: all 300ms ease-in;transition: transform 200ms, opacity 200ms`all` animates layout properties too and janks. [[transform-opacity-only]]
scale(0)scale(0.95); opacity: 0Nothing real appears from nothing. [[never-scale-from-zero]]
ease-incubic-bezier(0.23, 1, 0.32, 1)ease-in starts slow, so UI feels hesitant. [[easing-curves]]
no reduced-motion guard@media (prefers-reduced-motion: reduce) { … }Movement must honour the OS setting. [[prefers-reduced-motion]]
z-index: 9999;z-index: var(--z-popover)Arbitrary z-index escalates forever. [[z-index-strategy]]
outline: none;:focus-visible { outline: 2px solid; outline-offset: 2px }Keyboard users lose their place. [[accessibility-baseline]]
A slice of the checklist, running live. The table is the review.

Two warnings come with it. The checklist is a floor, not a ceiling: the best reviews catch what isn't on it. And it is a flag, not a law: a 500ms animation is fine on a rare celebration moment. Read the context before writing the row.

Ask for a proper review· for your agent
Review src/Modal.tsx as a Before | After | Why table.
Scan it against the review checklist first.
Quote my real lines in Before. End each Why with the node that owns it.
Three to five rows, most important first. If nothing fails, say so.

Reviewing a change, not a codebase

Now picture a pull request: a set of changes you want merged. The author is asking one question: did I make this worse?

A review that answers "here is everything wrong with this codebase" buries the two lines that matter under thirty that don't. A answers the real question.

checkout — feat/new-buttons
~/checkout❯
Scope: 3 commits ahead of main + 2 uncommitted files
Reading the removed lines… 1 lost <button>
Verdict: Blocked, one regression
StatusBeforeAfterWhy
Regression<div onClick={save}><button onClick={save}>The refactor turned a button into a div: no keyboard, no role.
Introducedtransition: all 300mstransition: transform 200msAnimate only what moves.
Pre-existingz-index: 9999z-index: var(--z-popover)Not this change. Listed, not blocking.
A branch review: the scope first, then the removed lines, then a Status on every row.

Resolve the scope

With no target named, the agent reviews the commits your branch has that main doesn't, plus anything uncommitted, and says how many of each. With nothing changed, it asks what to review instead of inventing a scope.

Follow the blast radius

A changed file is evidence, not the subject. Its is every screen that renders it. Change a token, and every component using that token is in scope.

Read the removed side

Regressions are invisible in the after state. A <button> that became a styled <div> in a "move to the new design system" refactor looks identical. Only the deleted lines show it.

So the agent searches the removed lines for signals that left: aria-*, <label>, :focus-visible, prefers-reduced-motion, a token swapped for a literal. Each is a lead, not a finding. aria-label replaced by aria-labelledby on visible text is fine; read the hunk before deciding.

The button-to-div swap is the regression people miss most.

Status by cause

Every finding gets a status, decided by what caused it, not by where it sits:

StatusMeansBlocks the merge?
Introducedthe change created ityes
Regressionthe change weakened something that workedyes
Pre-existingit was already there, not made worseno

An untouched screen whose contrast now fails because a shared token changed is Introduced. A bug three lines from the edit that the edit didn't touch is Pre-existing. List at most three of those, plainly marked as not this change's job. Thirty is another review.

Review my branch· for your agent
Review this branch as a change-scoped review.
Scope: commits ahead of main plus uncommitted files; tell me how many.
Read the removed lines for lost signals.
Columns: Severity | Status | Location | Before | After | Why.
Introduced and Regression only, then at most three Pre-existing.

Quick check

A pull request changes one shared color token. An untouched settings screen now fails contrast. What status does that finding get?

What this lesson builds on and leads to, across every course.

  • Routing the job
  • Your first review
  • What is a skill?
  • When text runs out of room