jig-ui 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -6,7 +6,7 @@ these, say so, list them, and stop.
6
6
 
7
7
  There are two kinds of subcommand, and they are not run the same way.
8
8
 
9
- **CLI-backed** — `install`, `update`, `init`, `check`, `explain`, `verdicts`, `gate`, `probe`. Run the
9
+ **CLI-backed** — `install`, `update`, `init`, `check`, `explain`, `verdicts`, `gate`, `probe`, `seo`. Run the
10
10
  matching command with `{{scripts_path}}`, passing the flags through unchanged,
11
11
  then do the work below for that subcommand. Read the command's full output —
12
12
  findings are ordered by severity, not position, so `head`, `tail`, `grep` and
@@ -218,6 +218,33 @@ Read `DECISIONS.md` before asking anything. Do not re-ask what it already record
218
218
  cite it instead. If the screen touches an item in its **Unresolved** section, ask the user
219
219
  about it by name; do not settle it in the spec.
220
220
 
221
+ ### 0. If the page already exists, describe it before you change anything
222
+
223
+ An existing page is specified from what is there, not redesigned on the way past.
224
+ Read the page and its stylesheet, render it at each size the spec will name, and
225
+ write the frontmatter from what you find: the regions in their real order, the
226
+ hierarchy as built, the navigation at each width. Then ask the user the questions
227
+ below only where the page does not answer them — what it is for, who arrives, what
228
+ is deferred — and show them the description to confirm or correct.
229
+
230
+ Two things this is not. It is not a redesign: a region you would have arranged
231
+ differently is still recorded as it is, and `critique` is where that argument
232
+ belongs, with the rules behind it. And it is not a rubber stamp: a page that
233
+ contradicts `DECISIONS.md` is described accurately and the contradiction noted in
234
+ the prose, because the spec is a record of what is, and the review is what says
235
+ whether that is right.
236
+
237
+ **Asked to redesign it instead, run this command normally.** The difference is
238
+ what the old page counts as: its content is the brief — the copy, the real data,
239
+ the questions its FAQ answers — and its structure is not. Decide the composition
240
+ from the rules and the answers, not from what the markup happens to do now, or
241
+ the redesign is the same page in new colours. Anything that genuinely must
242
+ survive is a constraint and belongs in the spec by name: a URL linked from
243
+ elsewhere, a field order the back end depends on, wording somebody signed off.
244
+ Ask which of those exist; do not assume the whole page is one.
245
+
246
+ The commands after this run unchanged.
247
+
221
248
  ### 1. Ask, two or three questions at a time
222
249
 
223
250
  **This is a required interaction, not a suggestion.** Ask two or three questions,
@@ -231,9 +258,17 @@ settled at `init` and live in `{{config_file}}` and the token layer; re-deciding
231
258
  them per screen creates a second source of truth for the values Jig exists to
232
259
  centralise. If the user raises appearance, record it and move on.
233
260
 
261
+ **Every question carries an example answer**, for the same reason `decide`'s do: a
262
+ question someone has to decode gets a worse answer than one they can react to, and
263
+ the example shows the shape. Say it is an example, not a suggestion.
264
+
234
265
  - Round 1 — what is it for? What does the user need to do there ("create an
235
266
  invoice")? Who arrives, and what is the single most important thing they must be
236
267
  able to see or do?
268
+ > *For example: "comprehension first, sign-up second. They arrive from the
269
+ > product page having already decided to try it, so no explainer above the
270
+ > cards. The most important thing is the limits — the price matters equally and
271
+ > must never dominate."*
237
272
  - **Then scope it — be a pessimist.** Of everything this could include,
238
273
  what is the smallest version that is useful on its own? Ask that plainly and
239
274
  expect to cut. "Comments with attachments, mentions, reactions, editing,
@@ -242,11 +277,20 @@ centralise. If the user raises appearance, record it and move on.
242
277
  forgotten. Everything after this designs V1 only.
243
278
  - Round 2 — what content and states does it carry? Empty, loading, error,
244
279
  first-run, and the realistic range (0 items, 5, 500)?
280
+ > *For example: "three plans, a monthly/annual choice, four FAQ questions, a
281
+ > footer. The billing choice is the only state — the page is static, nothing
282
+ > loads, nothing fails."*
245
283
  - Round 3 — only what is still unresolved: entry points, where it leads, what
246
284
  must not happen here.
285
+ > *For example: "they arrive from the product page or a docs search, and every
286
+ > plan goes straight to sign-up. Nothing on this page may ask for a sales
287
+ > call."*
247
288
 
248
289
  **Ask about the phone by name.** What does the reader see first on a phone, and
249
- what moves, stacks, or goes behind a control? If the conversation only ever
290
+ what moves, stacks, or goes behind a control?
291
+ > *For example: "the plans come first on the phone" — that is the answer this
292
+ > question wants, and everything else about the narrow composition is the
293
+ > system's to settle.* If the conversation only ever
250
294
  describes the wide screen, the phone composition will be derived from it rather
251
295
  than designed — and a derived phone composition is a squeezed desktop.
252
296
 
@@ -296,9 +340,15 @@ sizes: # phone first. Each size is a whole composition, not
296
340
  grouping: { form: proximity, brand: common region }
297
341
  grid: { columns: 12, form: 5, brand: 6 }
298
342
  nav: none on this screen
343
+ wide: # judged at 1600px — where a layout with no upper bound shows itself
344
+ same-as: desktop
345
+ why: "content is capped at 1200px, so 1600 adds margin and nothing else"
299
346
  states: [default, loading, error, success]
300
347
  decisions: [The Engineer Reads First] # every DECISIONS.md entry this screen implements, by name
301
348
  later: [social sign-in, remember this device] # cut from V1, by name — the next specs start here
349
+ indexable: true # from the mode — editorial yes, product/operator no. Say why when you override it.
350
+ title: "Pricing — Hoistline" # ≤ 60 characters, the search result's first line
351
+ description: "Three plans, every price visible. No sales call." # ≤ 155
302
352
  mockup: pending # `mockup` sets approved or skipped, from the user's own words
303
353
  mockup_at: # where the approved drawing is: a .jig/mockups path, or a Figma or Stitch link
304
354
  deviations: [] # `make` writes here; `spec` leaves it empty
@@ -307,6 +357,24 @@ deviations: [] # `make` writes here; `spec` leaves it empty
307
357
 
308
358
  - **`phone` is written first, and in full.** It is the most common screen, and the
309
359
  one a derived composition fails on worst.
360
+ - **`indexable:`, `title:` and `description:` are copy, decided here.** The mode
361
+ sets the default — `editorial` is first-visit content and is indexable,
362
+ `product` and `operator` are what somebody reaches after signing in and are
363
+ not — and a page overrides it with a reason: a CV shared by link, a
364
+ confirmation page, a page that exists for one recipient. A page that is not
365
+ indexable needs no title or description here and must carry `noindex` when
366
+ built (`J-123`).
367
+ - **`wide` is required too, and is where an unbounded layout shows itself.** A
368
+ page judged only to 1280 never reveals that its content has no cap: at 1600 a
369
+ three-column grid becomes four thin ones, a header's logo and nav drift apart,
370
+ and a line of prose runs past its measure (`B-11`). `same-as: desktop` with a
371
+ `why:` is the right answer for a page that caps its content — and saying so is
372
+ the point.
373
+ - **`landscape` is optional, judged at 900px.** Write it only when the
374
+ composition genuinely changes between tablet and desktop — a navigation that
375
+ expands there, a grid that goes three to two. Most pages do not, and a size
376
+ written to be written costs a composition, a frame, a render and a row of
377
+ verdicts on every page afterwards.
310
378
  - **`tablet` and `desktop` are written in full too.** `same-as: <size>` is allowed
311
379
  when nothing changes, but only with `why:`. It is a claim that the composition
312
380
  holds at that width — `critique` checks it on a render — not a way to leave the
@@ -433,7 +501,7 @@ before drawing. Do not switch to HTML on their behalf; offer it, and let them
433
501
  choose.
434
502
 
435
503
  - **Drawing in Figma.** One page named for the feature, one frame per size at the
436
- spec's widths — 360, 768, 1280 — phone first. Grey fills and strokes only; no
504
+ spec's widths — 360, 768, 1280, 1600 — phone first. Grey fills and strokes only; no
437
505
  library components, styles or variables from the product's design system, for
438
506
  the same reason the HTML carries no tokens.
439
507
  - **Drawing in Stitch.** Ask for a low-fidelity grayscale wireframe of this one
@@ -488,7 +556,7 @@ look. So the drawing contains:
488
556
  what goes there. An icon is its name in brackets: `[search]`.
489
557
  - **Real words, not lorem ipsum.** Labels, headings and button text are part of the
490
558
  structure — "Create invoice" versus "Submit" is a decision worth reviewing.
491
- - **Every size the spec names, as its own frame** — phone, then tablet, then desktop,
559
+ - **Every size the spec names, as its own frame** — phone, then tablet, then desktop, then wide,
492
560
  stacked top to bottom, each drawn with its own markup. Size is structure, not
493
561
  detail: a phone composition that is only the desktop one narrower is the failure
494
562
  specs are written per size to prevent. A `same-as:` size is drawn anyway, so the
@@ -515,6 +583,8 @@ look. So the drawing contains:
515
583
  .frame[data-size="phone"] { width: 360px; }
516
584
  .frame[data-size="tablet"] { width: 768px; }
517
585
  .frame[data-size="desktop"] { width: 1280px; }
586
+ .frame[data-size="wide"] { width: 1600px; }
587
+ .frame[data-size="landscape"] { width: 900px; }
518
588
  .region { border: 1px dashed #aaa; padding: 12px; margin: 0 0 12px; }
519
589
  .region > .name { display: block; font-size: 12px; color: #777; margin: 0 0 8px; }
520
590
  .media { background: #ddd; color: #555; display: grid; place-items: center; min-height: 120px; }
@@ -654,6 +724,12 @@ describe the content accurately? Only when nothing fits is a generic container
654
724
  right. The page must read as what it is with the stylesheet off, in an order
655
725
  that makes sense; CSS then arranges it, and never the reverse.
656
726
 
727
+ **Write the metadata in this change, not the next one** (`J-120`). The title,
728
+ description and preview text are copy: they come from the spec, they are written
729
+ by whoever wrote the headline, and they move when it moves. A page that is not
730
+ indexable carries `noindex` instead, from its own metadata rather than from
731
+ `robots.txt`, which is public and advisory and protects nothing.
732
+
657
733
  Then the ordinary rules apply: tokens by semantic name, the relevant
658
734
  `03-patterns.md` section for each component, `05-copy.md` for every string.
659
735
 
@@ -688,7 +764,7 @@ one. A report with no `JIG_CHECK:` line, or one you typed yourself, is not a fin
688
764
  build.
689
765
 
690
766
  **2. The build matches the approved mockup at each size.** Skip only when
691
- `mockup: skipped`. Render the page at 360px, 768px and 1280px — with a browser, not in
767
+ `mockup: skipped`. Render the page at 360px, 768px, 1280px and 1600px — with a browser, not in
692
768
  your head — and set each render beside the mockup at the same width. Go region by
693
769
  region, in the mockup's order:
694
770
 
@@ -755,7 +831,9 @@ conversation that built the page. Running them in one head anchors them to each
755
831
  other; do not shortcut it for cost, speed or context size.
756
832
 
757
833
  - **A — the reader.** Delegate to a subagent. Give it the URL or file, the spec,
758
- the approved mockup (from `mockup_at:`), `DECISIONS.md`, and the corpus. It judges the `pass: screen` rules against the render, **and the `P-` patterns the spec's regions use** — a navigation region means `P-14`. Those patterns are not in `rules.index.json`, so walking the index alone never reaches them. It writes its verdicts to `.jig/critique/<surface>/screen.json` (step 1c). Do
834
+ the approved mockup (from `mockup_at:`), `DECISIONS.md`, and the corpus. It also
835
+ judges every decision in `DECISIONS.md` against the page and writes
836
+ `decisions.json` (step 1c). It judges the `pass: screen` rules against the render, **and the `P-` patterns the spec's regions use** — a navigation region means `P-14`. Those patterns are not in `rules.index.json`, so walking the index alone never reaches them. It writes its verdicts to `.jig/critique/<surface>/screen.json` (step 1c). Do
759
837
  **not** give it the build conversation. If it needs that conversation, it is
760
838
  not reviewing the page, it is agreeing with itself.
761
839
  - **B — the machine.** Run `check`. Deterministic, same input same output. It
@@ -850,9 +928,9 @@ Each reader arm writes its own file. The arm reports back only that it wrote it.
850
928
  ```json
851
929
  {
852
930
  "rendered": true,
853
- "artefacts": [".jig/critique/pricing/360.png", ".jig/critique/pricing/768.png", ".jig/critique/pricing/1280.png"],
931
+ "artefacts": [".jig/critique/pricing/360.png", ".jig/critique/pricing/768.png", ".jig/critique/pricing/1280.png", ".jig/critique/pricing/1600.png"],
854
932
  "verdicts": [
855
- { "id": "D-115", "verdict": "ok", "reason": "no sideways scroll at 360, 768 or 1280" },
933
+ { "id": "D-115", "verdict": "ok", "reason": "no sideways scroll at 360, 768, 1280 or 1600" },
856
934
  { "id": "P-14", "verdict": "finding", "reason": "menu button at 360 does not open; aria-expanded never set" },
857
935
  { "id": "A-60", "verdict": "n/a", "reason": "A-60 is about competing icons; this page has none" }
858
936
  ]
@@ -861,7 +939,28 @@ Each reader arm writes its own file. The arm reports back only that it wrote it.
861
939
 
862
940
  `screen.json` carries `rendered` and `artefacts`; `code.json` needs only `verdicts`.
863
941
 
864
- **A rendered review is measured, not only described.** At 360, 768 and 1280px, run the
942
+ **And the project's own decisions, one verdict each**, in
943
+ `.jig/critique/<surface>/decisions.json`:
944
+
945
+ ```json
946
+ {
947
+ "verdicts": [
948
+ { "decision": "Voice", "verdict": "finding", "reason": "headings and buttons are Title Case; the decision says lowercase" },
949
+ { "decision": "Trial and onboarding", "verdict": "finding", "reason": "Team and Scale say \"start free trial\"; the trial was replaced by the free Solo plan" },
950
+ { "decision": "Navigation", "verdict": "ok", "reason": "menu button top right at 360, five links at 768 and above" }
951
+ ]
952
+ }
953
+ ```
954
+
955
+ Every `##` and `###` heading in `DECISIONS.md` is a decision and gets exactly one
956
+ verdict, judged against the built page. `Unresolved` is not a decision. The rules
957
+ are the system's; these are the project's, and a page can satisfy all 115 rules
958
+ while breaking the file written to hold what this project chose. In a live round
959
+ one page shipped "start free trial" two commands after the owner had killed
960
+ trials, and another used Title Case against a lowercase decision. Both passed
961
+ every rule.
962
+
963
+ **A rendered review is measured, not only described.** At 360, 768, 1280 and 1600px, run the
865
964
  probe in the browser and save what it returns beside the verdicts:
866
965
 
867
966
  ```
@@ -927,17 +1026,30 @@ source and imagining the page is not a render.
927
1026
  that works: in a live run four of six pages shipped a phone menu that did not open,
928
1027
  or no menu at all, and every review that only looked passed them.
929
1028
  - **Render at every size the spec names** — phone at 360px, tablet at 768px,
930
- desktop at 1280px — and judge each size's fields against its own render. A
1029
+ desktop at 1280px, wide at 1600px — and judge each size's fields against its own render. A
931
1030
  `same-as:` claim is checked like any other field: render that size and see
932
1031
  whether the composition really does hold.
933
1032
  - At every size, measure `document.documentElement.scrollWidth` against
934
1033
  `clientWidth`. Greater means the page scrolls sideways at that width, which is a
935
1034
  finding however good the rest of it looks.
1035
+ - **Judge the collapse, not only the sizes** (`L-01` step 6). Between one width
1036
+ and the next: did the column count drop rather than the columns shrink, did the
1037
+ reading order hold, did an emphasised item stay distinguishable once everything
1038
+ was in one column, did anything genuinely wider scroll inside itself rather
1039
+ than taking the page with it?
936
1040
  - Compare the sizes. Did the phone change the **composition**, or only the
937
1041
  **dimensions**? Reordering, stacking, collapsing, a different control — that is
938
1042
  composition. The same layout with smaller numbers is not.
939
1043
  - Check the page is styled at all. A stylesheet that 404s renders a page that
940
1044
  passes every file-based check ever written.
1045
+ - **Read what a stranger meets first** (`J-120`). Open the head: does the title
1046
+ still describe this page, does the description still say what the page now
1047
+ says, and would either have survived the last copy change? A page whose
1048
+ metadata contradicts its own headline is the commonest drift there is, because
1049
+ a copy pass reads pages and nobody reads the head. Run `{{scripts_path}} seo`
1050
+ for what one page cannot see: a route that says `noindex` and sits in the
1051
+ sitemap, two pages claiming the same title, a site with neither sitemap nor
1052
+ robots.
941
1053
  - **Read the markup as a document, not a layout** (`H-119`). For each region:
942
1054
  does its element say what the content is? Would the page still read correctly
943
1055
  with the stylesheet off, in this order? A row of links that is not a `<nav>`, a
@@ -984,10 +1096,10 @@ preserve while fixing them.
984
1096
  Then the attestation:
985
1097
 
986
1098
  ```text
987
- JIG_CRITIQUE: version=<version> mode=<mode> surface=<name> spec=<confirmed|missing|unconfirmed> mockup=<approved|skipped|missing> rendered=<yes|no> screen=<ran|skipped>:<n> code=<ran|skipped>:<n> mechanical=<pass|fail|skipped>:<n> warnings=<n>
1099
+ JIG_CRITIQUE: version=<version> mode=<mode> surface=<name> spec=<confirmed|missing|unconfirmed> mockup=<approved|skipped|missing> rendered=<yes|no> screen=<ran|skipped>:<n> code=<ran|skipped>:<n> decisions=<ran|incomplete|missing>:<n> mechanical=<pass|fail|skipped>:<n> warnings=<n>
988
1100
  ```
989
1101
 
990
- **Take `screen=`, `code=` and `rendered=` from `jig verdicts`, never from your own
1102
+ **Take `screen=`, `code=`, `decisions=` and `rendered=` from `jig verdicts`, never from your own
991
1103
  count.** If it reported an arm incomplete, that arm is `skipped` here with the reason,
992
1104
  until it is re-run and passes.
993
1105
 
@@ -1042,6 +1154,22 @@ Run `{{scripts_path}} probe`. It prints one JavaScript expression — the render
1042
1154
  for the critique's screen arm to evaluate in a browser at each width. See step 1c of
1043
1155
  `critique`. It changes nothing on its own.
1044
1156
 
1157
+ ## seo
1158
+
1159
+ Run `{{scripts_path}} seo` and report what it says. It needs no `DECISIONS.md`,
1160
+ no spec and no confirmation: it reads what the project already serves, so it is
1161
+ safe to run on the first day and on somebody else's codebase. It audits the whole project,
1162
+ which is what one file cannot: a route whose metadata says `noindex` sitting in
1163
+ the sitemap, two pages claiming the same title, indexable pages with no sitemap,
1164
+ a sitemap that lists nothing.
1165
+
1166
+ It is not a phase. The per-page half belongs where the copy is decided and
1167
+ written — `spec` records whether a page is indexable and what it claims, `make`
1168
+ writes the metadata in the same change as the headline, `check` enforces the
1169
+ budgets — because a pass you run afterwards is a pass that gets skipped on the
1170
+ day the copy changes, which is exactly how a live site ended up serving
1171
+ positioning it had already dropped.
1172
+
1045
1173
  ## gate
1046
1174
 
1047
1175
  Not a command to run. In Claude Code, `install` adds a Stop hook that runs
@@ -1072,7 +1200,10 @@ wherever `brand` in `{{config_file}}` puts the token files.
1072
1200
 
1073
1201
  `spec`, `mockup`, `make` and `critique` are blocked until this exists: `spec` and
1074
1202
  `critique` refuse to start without it, and `mockup` and `make` need a confirmed spec.
1075
- Nothing else is blocked — `install`, `init`, `check` and `explain` run without it.
1203
+ Nothing else is blocked — `install`, `init`, `check`, `explain`, `seo`, `probe`
1204
+ and `verdicts` all run without it. `seo` in particular is an audit of what is
1205
+ already there, and a project with no decisions yet still has a sitemap that
1206
+ either contradicts its pages or does not.
1076
1207
  `init` comes first, because this file sits beside the token files `init` writes.
1077
1208
 
1078
1209
  ### What belongs in it, and what does not
@@ -1116,14 +1247,87 @@ at all. If the design system has a position, it is in the rules; if it has none,
1116
1247
  you are looking for is the places where this project has already chosen
1117
1248
  something, or will have to:
1118
1249
 
1250
+ **Ask every question with an example answer attached.** A question someone has to
1251
+ decode gets a worse answer than one they can react to, and the example shows the
1252
+ shape you need — a sentence about this product, not an adjective. Say plainly
1253
+ that it is an example, not a suggestion.
1254
+
1119
1255
  - Round 1 — what is this product, and who is it for in a sentence the team would
1120
1256
  recognise? What should it never look like? Name real products, not adjectives.
1257
+ > *For example: "hosted log search — you point it at your cluster and ask in
1258
+ > plain text. For a backend engineer who has tried grep over SSH. It must never
1259
+ > look like an enterprise console: no SKU matrix, no 'contact us' pricing.
1260
+ > Closer to Fly.io than to a Datadog dashboard."*
1261
+ - Round 1b — **what the product is for, and what you give up for it.** This file
1262
+ is project-wide, so both answers are about the product, not a page. A page's
1263
+ own purpose is `spec`'s question, and it inherits its direction from here.
1264
+ - *"If this product works, what can someone do that they could not before?"*
1265
+ That is the north star: one outcome, in the product's own words, that every
1266
+ later argument is settled against. A design direction without one drifts
1267
+ screen by screen, each change defensible on its own.
1268
+ > *For example: "an engineer finds the line in their logs without learning a
1269
+ > query language" — not "be the best log tool", which no screen can serve or
1270
+ > fail. The test: could you look at a design and say whether it moves toward
1271
+ > that sentence?*
1272
+ - *"When two good options conflict here, which side do you take?"* Fast over
1273
+ complete, plain over clever, fewer choices over more, density over comfort.
1274
+ > *For example: "comprehension wins over persuasion — if the clearer page
1275
+ > converts worse, we ship the clearer page", or "recovery wins over speed:
1276
+ > every destructive action is undoable, even where that costs a step".*
1277
+ Jig's own tiebreakers settle the system's conflicts; this settles the
1278
+ project's, and without it the agent settles them alone. In a live run a
1279
+ decision about where the accent may appear collided with a component rule
1280
+ and the agent resolved it on its own, correctly as it happens, and recorded
1281
+ the collision as a deviation. One line here would have decided it.
1282
+
1283
+ **Refuse an adjective, ask again.** "Bold", "human", "trustworthy" and
1284
+ "premium" cannot be checked against a page, and every decision in this file is
1285
+ now judged against one. Push for the form that can: what it is closer to, what
1286
+ it would rather be than, what it refuses.
1287
+ - Round 1c — **the personality, asked through the four things that produce it.**
1288
+ Every interface has one whether it was chosen or not, and it is not a mood
1289
+ board: it is decided by type, colour, corners and language, each of which is a
1290
+ value this project is about to set. Ask about all four, one question each, and
1291
+ say what each answer will become.
1292
+ - **Type.** Serif reads classic or editorial; a rounded sans reads friendly; a
1293
+ neutral sans stays out of the way and lets everything else carry the
1294
+ personality. Which is this? *(Becomes `--font-text` and `--font-display`.)*
1295
+ - **Colour.** Which colour is this product's, and what does it mean here? The
1296
+ psychology matters less than the reason: blue is familiar and safe, gold
1297
+ reads expensive, pink reads unserious. *(Becomes `--color-brand`, and the
1298
+ contrast floors still apply — a palette that fails them is not a
1299
+ personality.)*
1300
+ - **Corners.** Square reads formal or technical, a small radius is neutral,
1301
+ a large one reads playful. One answer for the whole interface: mixing square
1302
+ and round in one screen looks worse than either. *(Becomes the `--radius-*`
1303
+ scale.)*
1304
+ - **Language.** Official and impersonal, or plain and conversational? Words
1305
+ appear in every screen, so this decides more of the personality than any
1306
+ single visual choice. *(Becomes a voice decision here, applied by
1307
+ `05-copy.md`.)*
1308
+ > *For example: "neutral sans — the type should disappear. One colour, a muted
1309
+ > olive, because it is the one thing on the page that is not a plan or a price.
1310
+ > Square corners; this is a tool, not a toy. Lowercase and technical: ingest,
1311
+ > retention, seat — plain words, undefined, no throat-clearing."*
1312
+
1313
+ **When they have no gut feeling, ask what the reader already uses.** The sites
1314
+ this audience spends its day in set the expectation; matching that is cheaper
1315
+ than teaching a new one. Take the direction, never the design: a project that
1316
+ borrows from a direct competitor looks like a second-rate version of it, which
1317
+ is also `A-01`'s point about invented decoration seen from the other side.
1121
1318
  - Round 2 — for each thing the tokens already set, is there a rule about *how* it
1122
1319
  is used? Where does the brand colour go, and where is it forbidden? What earns
1123
1320
  emphasis?
1321
+ > *For example: "the accent appears exactly twice per page, both clickable —
1322
+ > the primary action and the active side of a control. Never on a checkmark, a
1323
+ > limit number or a feature list. Emphasis is earned by the one thing the
1324
+ > reader came to do."*
1124
1325
  - Round 3 — what has the team already argued about, or reversed? A decision with
1125
1326
  a history is the one most worth recording, because it is the one most likely to
1126
1327
  be re-made wrongly.
1328
+ > *For example: "we shipped a 'most popular' badge for six weeks. Conversion
1329
+ > rose slightly; wrong-plan signups and support tickets rose more. We pulled
1330
+ > it, and that covers the effect, not the widget — no raised card either."*
1127
1331
 
1128
1332
  **All three rounds run.** Do not write the file after round 2 because the answers
1129
1333
  look complete. Round 3 asks for the one kind of decision a user does not volunteer
@@ -1132,7 +1336,10 @@ reason. In the arm that did ask, round 3 is where the unresolved items surfaced.
1132
1336
 
1133
1337
  **Round 3 also asks, by name, what is still undecided.** "Is there anything the team
1134
1338
  has not settled yet — something still argued about, or waiting on someone?" Ask it
1135
- even when nothing so far suggests there is. Whatever the answer names goes in the
1339
+ even when nothing so far suggests there is.
1340
+ > *For example: "whether we publish a public status page. It is between showing
1341
+ > uptime on the pricing page and not mentioning it at all, and it waits on
1342
+ > whether support can staff it."* Whatever the answer names goes in the
1136
1343
  **Unresolved** section below, not into a decision the user did not make. Four of six
1137
1344
  files in a live run dropped the one open item the owner had named.
1138
1345
 
@@ -1154,6 +1361,27 @@ wrong.
1154
1361
  A name gives the team something to cite in review. A reason lets a future agent
1155
1362
  tell when the rule does not apply, which a bare instruction never can.
1156
1363
 
1364
+ **The north star and the tiebreaker are decisions like any other**, written with
1365
+ the same shape and judged against every page:
1366
+
1367
+ ```markdown
1368
+ ### What this page is for
1369
+
1370
+ A reader leaves knowing which plan fits them and which limit they would hit
1371
+ first. Nothing else on the page outranks that.
1372
+
1373
+ **Why:** they arrive from the product page already interested; the job is to
1374
+ remove the last doubt, not to sell again.
1375
+
1376
+ ### When two options conflict
1377
+
1378
+ Comprehension wins over persuasion. If a clearer page converts worse, we ship
1379
+ the clearer page.
1380
+
1381
+ **Why:** the reader is an engineer who has been sold to badly before, and the
1382
+ support cost of a wrong-plan signup outweighs the signup.
1383
+ ```
1384
+
1157
1385
  **The reason is the owner's, or it is not written.** Write the `Why:` the user gave,
1158
1386
  in their words or close to them. If they gave none, ask for it. If they still give
1159
1387
  none, write `**Why:** not given` — never a reason you supplied. A live run invented
@@ -24,6 +24,11 @@
24
24
  "argumentHint": "[--all] [--ci] [--json]",
25
25
  "status": "available"
26
26
  },
27
+ "seo": {
28
+ "description": "Audit what a search engine and a link preview read, across the whole project: a noindex route in the sitemap, two pages with one title, indexable pages with no sitemap, a sitemap that lists nothing. The per-page half lives in spec, make and check.",
29
+ "argumentHint": "[--json]",
30
+ "status": "available"
31
+ },
27
32
  "verdicts": {
28
33
  "description": "Verify a critique's verdict files: every rule in each pass judged once, no id that does not exist, no rule in the wrong arm, rendered only with a screenshot. Computes the counts the critique reports, so the agent never writes them.",
29
34
  "argumentHint": "<surface>",