# Review cards and shots

> How an agent shows the client a change as a card with a before and an after, reads the client's verdict, and works through what the client raises, with golo review and golo shot.

Every visible change reaches the client as a CARD in the portal, beside the live app. Everything the client raises (a bug, a request) is an ITEM of the same store. An agent acts on both with `golo review` only, never in a chat: nobody reads a chat. The client's side of it: [Review cards](https://golocomotive.fr/docs/using/review.md).

## A card for one change

```sh
bunx golo shot orders --at HEAD --out .loco/shots/before.png   # before any edit: the app as committed
# edit the code, let the app reload
bunx golo shot orders --out .loco/shots/after.png              # after: the app as it runs now
git add src/collections/orders && git commit -m "orders: overdue badge" -- src/collections/orders
bunx golo review add --answers <item> --commit $(git rev-parse --short HEAD) \
  --title "Overdue orders show a red badge" \
  --what "In the Orders list:
- **the red badge** on orders past their due date" \
  --before .loco/shots/before.png --after .loco/shots/after.png
```

- Shoot the before FIRST. `--at HEAD` serves the app at that commit, apart from the running one.
- Commit BEFORE the card. An uncommitted change is lost to the next agent run.
- One subject is one card. Other angles of it (phone and desktop, empty and full) are VIEWS of that card: `--view "<label>" a.png`, or `golo review add-view <id> "<label>" a.png` later.
- A change always shows a before and an after. A lone image of a changed screen is no card.
- Open every image before you add it: the change is the obvious thing in the frame.
- `--title` is one line. `--what` is short markdown: one line of context, then bullets, the thing to judge in bold.
- `--answers <item>` links the card to the item it fixes: one bug, one thread, one verdict.
- A clip (mp4, webm) goes wherever an image goes, for anything that moves.
- `--draft` makes work in progress the client can comment on but not judge. `golo review ready <id>` makes it a card.

`add` refuses a card that an open thread already covers (same record, same screen and topic, or a close title) and names it. Then supersede it, add a view to it, or say why it is new with `--new --why "<reason>"`.

## The client's answer

| verdict | what to do |
|---|---|
| `approved` | nothing. Only the client approves; never call a look validated yourself |
| `approved-with-fix` | the comment and rectangles are a small follow up: do it, then `golo review done <id> "<what changed>"`, or a new card if it needs the client's eyes |
| `rejected` | fix it, then a new card with `--supersedes <id>` |
| `archived` | set aside: nothing to do |

- A follow up SUPERSEDES the card. Superseding an approved card needs `--keeps "<what stays>"`: an approval locks the look.
- Rectangles are normalized to 0..1 on their view, with `side` on a before and after pair and `t` on a clip.
- `golo review inbox` lists every unseen verdict and word of the client. `golo review seen <id>` marks it read once you acted on it.
- `golo review watch` prints one line per verdict or message as it lands and never exits. Run it unfiltered.

## What the client raises

```text
new ─dispatch→ open ─claim→ claimed ─a card answers it→ asks ─approved→ closed
 ├─ask→ question ─reply→ new         ├─fixed→ closed
 └─drop→ closed                      ├─blocked→ blocked (the client's move)
                                     └─wontfix→ closed
```

- The state is derived from the thread, never stored. The client's move: `asks`, `question`, `blocked`. An agent's move: `new`, `open`, `claimed`.
- One session at a time is the dispatcher (`golo review dispatcher --as <name>`). It routes new items to a topic, asks, or drops. It never fixes.
- A worker takes the oldest open item of a topic with `golo review next <topic>`, or claims one with `golo review claim <id>`, before any edit. Only the claimant ends it.
- A question goes ON the item: `golo review ask <id> "<question>"`, then the agent ends its turn. The client's answer comes back to the same worker.
- Acting verbs take `--as <name>`, or the `LOCO_AGENT` variable.
- Topics are the app's: `loco.config.ts` `review.topics`, else `ui`, `data`, `server`.

## golo shot

```sh
bunx golo shot [route] [--size phone|desktop|WxH] [--at <rev>] [--video <s>] [--wait <selector>|idle|<ms>] [--out file]
```

- The route goes without its leading slash: `orders`, `orders/12`, nothing for the home page.
- `--size phone` is 390x844, `desktop` 1440x900 (the default). Shoot a before and its after at one size.
- `--wait idle` for a page that loads its data after the first paint, `--wait "#list"` for one element.
- `--video 5` films 5 seconds (at most 30); `--out` then ends in `.mp4` or `.webm`.
- It prints the file, its size, the time, then one `page:` line per page error. A shot of a broken page is no card.
- `add` reads the route and the viewport from the png. A down shot service is not the agent's to fix: it asks on its item and ends its turn.

## The store

The store lives in the app's workspace, apart from its data: `.loco/review.db` (`_review_*` tables) and its media in `.loco/review/<id>/`. Never read or write those tables yourself: `golo review` and the portal go through one module that checks every act and never rewrites a message. The full verb list: [The golo cli](https://golocomotive.fr/docs/reference/cli.md#review).
