@clize/clize 0.35.5 → 0.36.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.
- package/dist/cli.js +23 -8
- package/dist/cli.js.map +1 -1
- package/dist/core/seo-cells.js +388 -0
- package/dist/core/seo-cells.js.map +1 -0
- package/dist/core/seo-classify.js +256 -17
- package/dist/core/seo-classify.js.map +1 -1
- package/dist/core/seo-pages.js +58 -0
- package/dist/core/seo-pages.js.map +1 -1
- package/dist/core/seo.js +480 -58
- package/dist/core/seo.js.map +1 -1
- package/dist/index.js +0 -0
- package/dist/remote.js +2 -0
- package/dist/remote.js.map +1 -1
- package/dist/tools/email.js +1 -1
- package/dist/tools/email.js.map +1 -1
- package/package.json +1 -1
- package/skills/clize-seo/SKILL.md +508 -597
|
@@ -18,7 +18,7 @@ description: >-
|
|
|
18
18
|
|
|
19
19
|
The commands are deliberately dumb: they compress facts, they never advise. `serp` will tell
|
|
20
20
|
you a page is a `listicle_window`; it will not tell you to pitch those listicles. That call is
|
|
21
|
-
yours
|
|
21
|
+
yours.
|
|
22
22
|
|
|
23
23
|
Run `clize seo <cmd> --help` for exact flags.
|
|
24
24
|
|
|
@@ -28,62 +28,55 @@ for *everyone*, so result pages are flooded with competent content and authority
|
|
|
28
28
|
are what actually separate pages now — placement (§6) weighs more than its nominal 30%.
|
|
29
29
|
|
|
30
30
|
**Three failure shapes account for most flat lines, and they need different moves.** Shape A,
|
|
31
|
-
*no placement
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
the tools if the site has none, before pitching a roundup. The counter-evidence sits in the same dogfood: tabledi and kunavo earned
|
|
48
|
-
page-1 positions with zero links, on tool and long-tail pages. Settle it per site with one round
|
|
49
|
-
of such rows enrolled in `check`, not by argument.
|
|
31
|
+
*no placement*: on-page at 120%, referring domains at zero, every non-brand keyword flat at
|
|
32
|
+
position 65+ (tenant zero, nine weeks) — the fix is §6. Shape B, *lost pages*: a ranking site
|
|
33
|
+
with no links loses its impressions to a migration (tabledi, 2026-09: 79 URLs returning 404
|
|
34
|
+
held 38% of three months' impressions, and from the keyword side it read exactly like Shape A);
|
|
35
|
+
the fix is technical — restore or redirect the URLs, get them re-crawled; links would not have
|
|
36
|
+
moved it. The 10% is 10% of the *ceiling*; a 404 takes 100% of the *floor*. `gsc.pages` (§9)
|
|
37
|
+
tells the two apart: impressions collapsed and live status not 200 is Shape B. **Do not
|
|
38
|
+
diagnose Shape A until you have read the pages face.** Shape C, *wrong bets*: every funded row
|
|
39
|
+
is a head term — `stretch` / `wall`, or `attackable` on a page held by high-authority sites —
|
|
40
|
+
and none is a tool, long-tail, `no_volume` or `pre_emergence` cell (tenant zero, 2026-09: 45
|
|
41
|
+
pages in eleven weeks, 0 clicks). Read `keywords.byBand` against the ledger's `format` column:
|
|
42
|
+
if the ledger holds no row your authority can win, placement is not the fix either — re-derive
|
|
43
|
+
it toward tool, long-tail and locale cells (§1.2, §7.2), building the tools if the site has
|
|
44
|
+
none, before pitching a roundup. tabledi and kunavo earned page-1 positions with zero links on
|
|
45
|
+
tool and long-tail pages: settle it per site with one round of such rows enrolled in `check`,
|
|
46
|
+
not by argument.
|
|
50
47
|
|
|
51
48
|
**§10 is the cycle that strings everything together. If a site exists, every session starts
|
|
52
|
-
there — with the free entry read (`clize seo check`), not with buying data. No site yet (
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
ending a session with a ledger full of buildable rows and no pages shipped (§3 test 6, §7).
|
|
49
|
+
there — with the free entry read (`clize seo check`), not with buying data. No site yet (nothing
|
|
50
|
+
to point `--domain` at)? Begin at §1, ship the first batch, and enter the cycle at your first
|
|
51
|
+
enrolled check.** §1–§3 run a discovery round, §4–§5 read its data, §6–§7 turn rows into
|
|
52
|
+
placement and pages, §8 is writing for AI engines, §9 reads the scoreboard. The two most common
|
|
53
|
+
failures are not misreadings of a number: testing a keyword set that was never enumerated (§1),
|
|
54
|
+
and ending a session with buildable rows and no pages shipped (§3 test 6, §7).
|
|
59
55
|
|
|
60
56
|
---
|
|
61
57
|
|
|
62
58
|
## 1. Where the seeds come from
|
|
63
59
|
|
|
64
|
-
Every command except `competitors` is a **verifier**: you hand it words, it prices them.
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
how the candidate list was built.
|
|
60
|
+
Every command except `competitors` is a **verifier**: you hand it words, it prices them. Only
|
|
61
|
+
`competitors` and `check`'s `newQueries` hand you a word you did not think of. The quality
|
|
62
|
+
ceiling of the analysis is set before you spend a cent, by how the candidate list was built.
|
|
68
63
|
|
|
69
64
|
**Enumerate the list. Do not recall it.** A list produced by thinking hard about the product is a
|
|
70
|
-
sample of your own memory: small, English-only, biased toward words you already believed in
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
payment long-tails with no recorded volume sitting at positions 4.5 and 8 in Search Console.
|
|
75
|
-
None of those were in the 19.
|
|
65
|
+
sample of your own memory: small, English-only, biased toward words you already believed in
|
|
66
|
+
(kunavo, 2026-08-31: 19 recalled keywords gave six themes and zero workable rows; a 37-cell
|
|
67
|
+
matrix the same day gave `openrouter alternative` at KD 1, a German pricing cluster and two
|
|
68
|
+
payment long-tails already at positions 4.5 and 8 in Search Console — none of them in the 19).
|
|
76
69
|
|
|
77
70
|
One free source comes before the paid ones: **the entry read's own gsc face** (§10) —
|
|
78
|
-
`gsc.topQueries` / `newQueries
|
|
79
|
-
|
|
71
|
+
`gsc.topQueries` / `newQueries`, Google's list of what it already considers you relevant for.
|
|
72
|
+
The best-fitted word source there is on a site with history; empty on a new one.
|
|
80
73
|
|
|
81
74
|
### 1.1 The sweep — exhaust the competitor space once, then top it up
|
|
82
75
|
|
|
83
76
|
`competitors` is the one command that hands you keywords you did not think of, and it is cheap
|
|
84
|
-
enough to run to exhaustion — which no round had done before 2026-09-03
|
|
85
|
-
|
|
86
|
-
|
|
77
|
+
enough to run to exhaustion — which no round had done before 2026-09-03 (a dozen rivals at
|
|
78
|
+
`--limit 25`, ledgers of 40–60 rows against cell spaces of a few hundred). Once per site, and
|
|
79
|
+
again whenever a product line is added:
|
|
87
80
|
|
|
88
81
|
```
|
|
89
82
|
clize seo competitors a.com b.com c.com --limit 100 # one call per market: --locale
|
|
@@ -97,18 +90,18 @@ clize seo competitors a.com b.com c.com --limit 100 # one call per market
|
|
|
97
90
|
| `seo serp` on every `attackable`, `no_volume` and `no_data` survivor (§5) | ~300 | ~$6 |
|
|
98
91
|
| rows into the ledger, each with a verdict | 80–120 buildable | — |
|
|
99
92
|
|
|
100
|
-
About $8 and one session
|
|
101
|
-
`topKeywords[].keyword`, drop their brand terms, keep the rest.
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
93
|
+
About $8 and one session; the ledger goes from forty rows to a hundred-plus. Read
|
|
94
|
+
`topKeywords[].keyword`, drop their brand terms, keep the rest. The sweep is not re-run every
|
|
95
|
+
round (the 30-day cache makes that pointless — top up with the new hosts each round's SERPs
|
|
96
|
+
reveal), and it does not replace §1.2 (a rival's list is what *they* rank for; your capability
|
|
97
|
+
cells are what *you* can serve). Expect the SERP step to kill a third to a half of the low-KD
|
|
98
|
+
survivors — walls the difficulty score cannot see (§4; PDF→Excel at KD 0 was Adobe and
|
|
99
|
+
iLovePDF in all five markets). That is the funnel working.
|
|
107
100
|
|
|
108
101
|
### 1.2 Capability-surface enumeration — cross the axes, don't brainstorm
|
|
109
102
|
|
|
110
103
|
Ask what the product can actually absorb a visitor for, find the axes of that surface, and take
|
|
111
|
-
the cross-product.
|
|
104
|
+
the cross-product.
|
|
112
105
|
|
|
113
106
|
| pattern | axis A | axis B | rows you get |
|
|
114
107
|
| --- | --- | --- | --- |
|
|
@@ -121,9 +114,9 @@ the cross-product. Mechanical is the point.
|
|
|
121
114
|
| Locale × head term | your two or three head terms | each market you can serve | `de-DE` pricing cluster (price it; §7.2 on whether to build it) |
|
|
122
115
|
|
|
123
116
|
- **Write every cell, then filter.** Filtering while enumerating is recalling again.
|
|
124
|
-
- **Do the non-English cells.** They hold the low-competition rows
|
|
125
|
-
|
|
126
|
-
|
|
117
|
+
- **Do the non-English cells.** They hold the low-competition rows a recalled list always skips.
|
|
118
|
+
Priceable markets: `en-US, en-GB, en-CA, en-AU, de-DE, fr-FR, es-ES, ja-JP, ko-KR, zh-TW,
|
|
119
|
+
pt-BR` — anything else is a 400.
|
|
127
120
|
- **Cells you can't serve are not candidates.** Ranking for a query you cannot answer is a bounce.
|
|
128
121
|
- 30–100 cells is a normal matrix; a full site with tools, hosts and locales is 100–150. Twelve
|
|
129
122
|
means you have not found your axes.
|
|
@@ -139,259 +132,235 @@ your list. No amount of enumeration produces this. Fold it back into the matrix
|
|
|
139
132
|
|
|
140
133
|
A round is a funnel with a known size and a known price — and there is no such thing as an
|
|
141
134
|
"analysis round": every round ends in pages or in a blocker the human must clear (§10).
|
|
135
|
+
**Two funnels, by what the cell is** (design: `seo-cell-funnel.md`). A sibling page costs
|
|
136
|
+
$0.01–0.05 and a SERP $0.02, so the SERP is not a gate for siblings; it is the gate for
|
|
137
|
+
everything that needs a brief.
|
|
142
138
|
|
|
143
139
|
```
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
→
|
|
147
|
-
→ seo
|
|
148
|
-
→
|
|
149
|
-
|
|
150
|
-
|
|
140
|
+
A · siblings of a verified family (a tool that already earns in one market, the same tool in another)
|
|
141
|
+
clize seo check → cells.missing / cells.queue the product counts the family × locale grid (§7.2)
|
|
142
|
+
→ write the native phrasing the only step that is yours
|
|
143
|
+
→ clize seo check --add-keywords "<word>@<locale>#<family>" volume is fetched to order cells, never to drop one
|
|
144
|
+
→ build every queued cell; the next check binds the live page to the cell and prunes (retire / cannibal / defects)
|
|
145
|
+
|
|
146
|
+
B · a family's first page, a new page type, a head term, a commercial term, a sweep survivor
|
|
147
|
+
§1.1 sweep / §1.2 matrix → clize seo serp <cell> [<cell>…] batch; verdict + composition + clusters (§4)
|
|
148
|
+
→ brief with an angle (§7.1 ①) → build → --add-keywords as above
|
|
151
149
|
```
|
|
152
150
|
|
|
153
151
|
### What it costs (measured, current version)
|
|
154
152
|
|
|
155
153
|
| step | price | note |
|
|
156
154
|
| --- | --- | --- |
|
|
157
|
-
| `seo keywords`, 40 words | **~$0.10** | one batched call; per-word cost is negligible
|
|
158
|
-
| `seo competitors`, one domain × `--limit 100` | **~$0.04** | the cheapest words you will
|
|
159
|
-
| `seo serp`, one keyword | **~$0.02** | every survivor gets one, `no_data`
|
|
155
|
+
| `seo keywords`, 40 words | **~$0.10** | one batched call; per-word cost is negligible, so **always send the whole list at once** |
|
|
156
|
+
| `seo competitors`, one domain × `--limit 100` | **~$0.04** | the cheapest words you will buy; a 20-domain sweep is under a dollar |
|
|
157
|
+
| `seo serp`, one keyword | **~$0.02** | every new-family survivor gets one, `no_data` included; siblings none — 20–100 of these is $0.40–2.00 |
|
|
160
158
|
| `seo check` | **free**, plus ~$0.005/word to price words it has never priced | the metrics are reused for 30 days, so a re-check costs nothing |
|
|
161
159
|
| `seo spend` | **free** | itemized ledger of every charge — **copy it into the deliverable, never hand-tally** |
|
|
162
160
|
|
|
163
|
-
**The sweep is about $8, once; a round after it is about $1
|
|
164
|
-
|
|
161
|
+
**The sweep is about $8, once; a round after it is about $1; a sibling matrix is about $4, of
|
|
162
|
+
which the pages are $3.** Carry those *cost priors*.
|
|
165
163
|
|
|
166
|
-
|
|
164
|
+
What follows from them:
|
|
167
165
|
|
|
168
166
|
- **Do not sample to save money.** Checking 12 of 40 keywords saves about six cents and costs
|
|
169
|
-
you the analysis.
|
|
170
|
-
economy. Price the whole list.
|
|
167
|
+
you the analysis. Price the whole list.
|
|
171
168
|
- **Read the account off the receipts; never reconstruct it.** Every response's `notes[0]` is
|
|
172
169
|
that call's charge in words — `this call: $0.3025 (competitors, 3 domains, limit 25, en-US)`,
|
|
173
170
|
or on a cache hit `this call: $0 — cache hit (…; would cost $0.3025 fresh)`. **A cache hit is
|
|
174
|
-
$0
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
balance; the fuse blows before the balance does.
|
|
193
|
-
- **Finish the loop.** The last step of the funnel is `seo check --keywords <survivors>`, and it
|
|
194
|
-
is free. `seo serp` reminds you of this on every response for a reason: an analysis with no
|
|
195
|
-
baseline cannot be compared against anything next round, so the work you just paid for only
|
|
196
|
-
half-lands.
|
|
197
|
-
|
|
198
|
-
> If you are carrying a mental model where `seo check` cost a dollar or two: that was the old
|
|
199
|
-
> check, which scraped a full SERP for every tracked keyword every round. It doesn't any more.
|
|
200
|
-
> Measurement is free; the exact-position scrape is now a deliberate single act (`seo serp`).
|
|
171
|
+
$0; never bill it at the fresh price**, and never price a call from the table above — a
|
|
172
|
+
*prior for planning*, not an invoice. `clize seo spend` is free and prints every charge
|
|
173
|
+
itemized with subtotals by command: **copy those numbers**. A hand-tallied total that disagrees
|
|
174
|
+
with it is your bug.
|
|
175
|
+
- **You do not need a budget — you need the prior.** The unit of work is one batch of shipped
|
|
176
|
+
pages, not one month; do not ration a monthly number. The `cap` block normally carries only
|
|
177
|
+
`usd` (where the fuse sits); if it also carries `spentThisMonth` / `remainingUsd`, **that
|
|
178
|
+
itself is the signal** — you are past 80% of the fuse, and `notes` says so. Then, or whenever
|
|
179
|
+
spend is far beyond ~$1 per analysis, **stop and run `clize seo spend`** (a retry loop is the
|
|
180
|
+
usual cause) before running anything else.
|
|
181
|
+
- **The cap is a runaway fuse, not a ration.** Default $25/month, sized so normal use never
|
|
182
|
+
touches it. Tripping it means a runaway loop (check yourself first) or genuinely heavy use;
|
|
183
|
+
for the latter, `--cap <usd>` on any `clize seo` command raises it and runs the command in
|
|
184
|
+
one step — the flag *is* the consent, no second confirmation. The hard limit is the account
|
|
185
|
+
balance; the fuse blows first.
|
|
186
|
+
- **Finish the loop.** The funnel's last step, `seo check --keywords <survivors>`, is free;
|
|
187
|
+
`seo serp` reminds you on every response because an analysis with no baseline cannot be
|
|
188
|
+
compared next round.
|
|
201
189
|
|
|
202
190
|
---
|
|
203
191
|
|
|
204
192
|
## 3. The ledger
|
|
205
193
|
|
|
206
|
-
**The worksheet is not the write-up of one analysis. It is the system state** — the ledger —
|
|
207
|
-
it outlives every session that touches it. One row = one bet, and the row holds the whole
|
|
208
|
-
what the world says (sv, kd, serp verdict), **what you put in** (
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
|
219
|
-
|
|
|
220
|
-
|
|
|
221
|
-
|
|
|
222
|
-
| メッセージストリームでエラー | ja-JP | 2,900 | 0 | definition_wall (UGC) | informational |
|
|
223
|
-
|
|
224
|
-
- **`
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
have caught it is in §4 ("Search Console beats the SERP read"). Import **skip rows and
|
|
248
|
-
cell-level lessons** only. Do not import site-level verdicts — "the content side has nothing
|
|
249
|
-
left", "the bottleneck is authority" — those expire, and are re-derived every round from the
|
|
250
|
-
cell count (§10, cadence); kunavo carried one such verdict through seven rounds, each session
|
|
251
|
-
re-confirming it instead of counting cells. And a family described in prose is not in the
|
|
252
|
-
ledger: a cluster, a locale axis or a page family with no rows and no `target page` will never
|
|
253
|
-
be built — write the rows (kunavo's nine-cell integrations family sat as a paragraph for two
|
|
254
|
-
rounds while every session executed "the existing ledger").
|
|
255
|
-
- **Narrative goes underneath as footnotes.** Two or three lines about what the pattern means.
|
|
256
|
-
Not six paragraphs of themes.
|
|
194
|
+
**The worksheet is not the write-up of one analysis. It is the system state** — the ledger —
|
|
195
|
+
and it outlives every session that touches it. One row = one bet, and the row holds the whole
|
|
196
|
+
bet: what the world says (sv, kd, serp verdict), **what you put in** (placement, angle), and why.
|
|
197
|
+
§10 reads it at allocation and writes it back at the end.
|
|
198
|
+
|
|
199
|
+
**Where it lives: `docs/seo/worksheet.md` in the project repo.** Not chat, not a summary:
|
|
200
|
+
cross-session handoff is that file, and a new session opens it to find where every bet stands.
|
|
201
|
+
`check` remembers the keyword list, the brand, the GSC property and the site's pages; it cannot
|
|
202
|
+
measure whether you sent the pitch or why you skipped a row, so that half of the state exists
|
|
203
|
+
only here.
|
|
204
|
+
|
|
205
|
+
| keyword | locale | family | sv | kd | serp verdict | intent | placement | format · angle | priority |
|
|
206
|
+
| --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
|
|
207
|
+
| openrouter alternative | en-US | openrouter | 1,300 | 1 | listicle_window | commercial | pitched: apidog roundup, 08-31 | comparison · *the only gateway that publishes its failover log* + pitch 8 roundups | P0 |
|
|
208
|
+
| email api for ai agents | en-US | inbox | 0 (no_volume) | — | listicle_window | commercial | none | landing · *an inbox the agent owns, not a Gmail it borrows* + pitch 4 roundups | P0 |
|
|
209
|
+
| csv 分割 | ja-JP | split-csv | 170 | 0 | (sibling — family earns in en-US) | tool | none | tool · Shift-JIS kept, header in every part | P1 |
|
|
210
|
+
| メッセージストリームでエラー | ja-JP | — | 2,900 | 0 | definition_wall (UGC) | informational | none | skip: Reddit/Zenn own it | — |
|
|
211
|
+
|
|
212
|
+
- **`family` is the cell key; page state is read, never written.** Whether the page for
|
|
213
|
+
(family, locale) exists, is indexed, earns, or should be retired comes from `check.cells`
|
|
214
|
+
(§9) — the product records pages as assets from the sitemap or the deploy plan. The ledger
|
|
215
|
+
holds what the product cannot measure: angle, priority, placement, the reason for a skip.
|
|
216
|
+
`placement` (`none` / `pitched:<target, date>` / `listed:<where>`) is yours to maintain.
|
|
217
|
+
- **A cell with a page and no placement is half a bet** (Shape A, top of this file).
|
|
218
|
+
- **`format` and the angle are part of the row.** "This keyword is good" is not a unit of work;
|
|
219
|
+
"write /compare/openrouter/ as a comparison page and pitch these eight roundups" is — and the
|
|
220
|
+
angle (§7.1 ①) says why that page and not a competent copy of the occupants. Siblings inherit
|
|
221
|
+
the family's angle and change terminology and FAQ only.
|
|
222
|
+
- **Rows you decided against stay in the table**, with the reason — that stops the next session
|
|
223
|
+
re-buying the same keyword, and a `skip` row with a reason is a real finding.
|
|
224
|
+
- **Opening the ledger on a site that already has analysis documents**: import their skip rows and
|
|
225
|
+
cell-level lessons *before* writing a new row — a lesson you do not import is re-learned at full
|
|
226
|
+
price (tabledi, 2026-09-01: a page recorded in prose as the site's third-best earner was re-marked
|
|
227
|
+
for retargeting the next day; §4 catches it). Do not import site-level verdicts — "the content
|
|
228
|
+
side has nothing left", "the bottleneck is authority" — those expire and are re-derived each round
|
|
229
|
+
from the cell count (§10, cadence; kunavo re-confirmed one through seven rounds instead of
|
|
230
|
+
counting cells). A family described in prose is not in the ledger and will never be built: write
|
|
231
|
+
the rows, or enroll the cells with `--add-keywords` (kunavo's nine-cell integrations family sat as
|
|
232
|
+
a paragraph for two rounds).
|
|
233
|
+
- **Narrative goes underneath as footnotes.** Two or three lines on what the pattern means, not
|
|
234
|
+
six paragraphs of themes.
|
|
257
235
|
- **Every ledger file counts, and a plan is a queue.** A site may carry more than one ledger
|
|
258
|
-
(tabledi: `worksheet.md` for en-US
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
run on. One row per shipped batch, updated at every check from `gsc.pages`:
|
|
236
|
+
(tabledi: `worksheet.md` for en-US, `worksheet-global.md` for the rest); rows in all of them
|
|
237
|
+
are the site's rows, and `check.cells` counts pages whichever file the row sits in. A batch
|
|
238
|
+
plan written under an earlier count rule (`≤5, wait for impressions`) is not re-planned and
|
|
239
|
+
never "the next batch": each cell is re-gated under gate 1 (§7.3), and every cell that passes
|
|
240
|
+
is a `to build` row for step ⓪ of the next session (§10; tabledi's B1–B4 sat under "next
|
|
241
|
+
batch" through three sessions — when counted, 15 cells had a SERP and 6 were unbuilt). A new
|
|
242
|
+
family's one SERP ($0.02) is bought in the same session, never "next time"; a verified
|
|
243
|
+
family's siblings need none.
|
|
244
|
+
|
|
245
|
+
**Page batches — the second table in the ledger.** What the site's composition is doing — what
|
|
246
|
+
the batch gate and retire rule (§7.3) run on. One row per shipped batch, updated at every check
|
|
247
|
+
from `gsc.pages` and `cells`:
|
|
271
248
|
|
|
272
249
|
| batch | shipped | pages | indexed | not indexed | zero-impression windows | retired |
|
|
273
250
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
274
251
|
| seo-tools-1 — llms.txt / hreflang / faq × en+de+ja | 2026-09-02 | 7 | 0 | 7 | 0 | 0 |
|
|
275
252
|
|
|
276
|
-
`indexed` / `not indexed` come from `gsc.pages.unseen[].index` (and
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
is found by `firstSeen` on the unseen rows
|
|
280
|
-
|
|
253
|
+
`indexed` / `not indexed` come from `gsc.pages.unseen[].index` (and `latest` once a page earns);
|
|
254
|
+
`zero-impression windows` counts full windows since shipping in which the batch earned nothing
|
|
255
|
+
(`cells.retire` lists the pages that have reached two); `retired` counts pages noindexed,
|
|
256
|
+
merged or redirected under §7.3. A batch is found by `firstSeen` on the unseen rows, and
|
|
257
|
+
`unseenTotal` says how much of the site the list is showing you.
|
|
281
258
|
|
|
282
259
|
### The pass/fail test
|
|
283
260
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
6. **Rows without pages — and families without rows.** Buildable rows — a serp verdict that is
|
|
313
|
-
not a wall, an intent you can serve — left unshipped at session end, or handed to "next
|
|
314
|
-
round" without one of the three blockers in §10 ⑤, are stock, not output.
|
|
315
|
-
An opportunity written in prose (a cluster, a family, a locale axis) with no rows behind it
|
|
316
|
-
is test 1 wearing a different coat. The deliverable counts shipped
|
|
317
|
-
URLs, not qualified rows; a ledger of twenty rows and two pages is a session that spent itself
|
|
318
|
-
on the analysis. Observed on kunavo: five rounds, five pages, three of the rounds at zero; and on clize.ai
|
|
319
|
-
the opposite failure — eleven weeks in which no round ran at all. If a page costs a session, the first deliverable is the generator (§7).
|
|
261
|
+
Seven ways a round fails.
|
|
262
|
+
|
|
263
|
+
1. **Themes instead of rows.** A set of *directions* or *themes*, or a table with fewer than ten
|
|
264
|
+
actionable rows: **the fix is upstream, in §1** — enumerate more cells, do not write it up
|
|
265
|
+
(kunavo round one, 2026-08-31: six well-argued themes, not one row anybody could start on).
|
|
266
|
+
2. **You priced fewer keywords than you enumerated, with no recorded rule for the gap.** A
|
|
267
|
+
225-cell matrix of which you bought 36 is sampled, not "focused" — and the rows you did not
|
|
268
|
+
buy are where the cheap wins were (§1). The only legitimate shrink before spending is a
|
|
269
|
+
**zero-cost rule written into the deliverable** ("dropped 14 pure-brand queries for
|
|
270
|
+
competitors' own names") that anyone can re-derive; "to save money" is not one — the whole
|
|
271
|
+
225 costs about what a sampled 36 does plus a quarter (§2).
|
|
272
|
+
3. **The money in the write-up does not match `seo spend`.** Sub-totals that don't add up, or a
|
|
273
|
+
cache hit billed fresh, mean the account was reconstructed instead of read off the receipts
|
|
274
|
+
(§2). Run `clize seo spend` and copy it.
|
|
275
|
+
4. **No baseline.** Without `seo check --keywords <survivors>` you have bets and no scoreboard.
|
|
276
|
+
It is free; run it before the summary.
|
|
277
|
+
5. **P0 pages with no placement rows.** Pages funded with no pitch, submission or participation
|
|
278
|
+
action beside them is Shape A written down in advance. The targets are already in the serp
|
|
279
|
+
data you paid for — `parasiteTargets`, the directories and discussions in `items` — so write
|
|
280
|
+
them as rows next to the pages they support (2026-08-31: five funded pages, placement nearly
|
|
281
|
+
invisible).
|
|
282
|
+
6. **Rows without pages — and families without rows.** Buildable rows — a verdict that is not a
|
|
283
|
+
wall, an intent you can serve — left unshipped at session end, or handed to "next round"
|
|
284
|
+
without one of the three blockers in §10 ⑤, are stock, not output; an opportunity in prose
|
|
285
|
+
(a cluster, a family, a locale axis) with no rows behind it is test 1 in a different coat.
|
|
286
|
+
The deliverable counts shipped URLs, not qualified rows (kunavo: five rounds, five pages,
|
|
287
|
+
three at zero; clize.ai: eleven weeks with no round). If a page costs a
|
|
288
|
+
session, the first deliverable is the generator (§7).
|
|
320
289
|
7. **Pages without a brief.** A page whose row names no occupant gap and no product asset is a
|
|
321
|
-
competent copy of the top 10, and at zero authority
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
the ledger row; no angle, no page.
|
|
290
|
+
competent copy of the top 10, and at zero authority that does not rank (kunavo's five model
|
|
291
|
+
spec pages, built from the query alone, read zero for three to eight weeks). The brief
|
|
292
|
+
(§7.1 ①) comes before the page and its angle sits in the row; no angle, no page.
|
|
325
293
|
|
|
326
294
|
---
|
|
327
295
|
|
|
328
296
|
## 4. Reading a results page (`seo serp`)
|
|
329
297
|
|
|
330
|
-
`verdict` compresses **who occupies the page**.
|
|
331
|
-
|
|
298
|
+
`verdict` compresses **who occupies the page**. Five values, and what each means for whether
|
|
299
|
+
you can get in:
|
|
332
300
|
|
|
333
301
|
| verdict | what it means | what it implies |
|
|
334
302
|
| --- | --- | --- |
|
|
335
|
-
| `official_wall` | The brand named in the query owns ≥3 of the top 5 |
|
|
336
|
-
| `definition_wall` | Big vendors / encyclopedias hold ≥4 of the top 10 with "what is X" content | Do not write another definition. Go long-tail, or go where the discussion is (Reddit, HN)
|
|
337
|
-
| `listicle_window` | Roundups hold ≥3 of the top 10 | **The only shape you can enter without authority.** `parasiteTargets` lists the roundups —
|
|
338
|
-
| `
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
303
|
+
| `official_wall` | The brand named in the query owns ≥3 of the top 5 | A navigational query in a category costume; you are not getting in |
|
|
304
|
+
| `definition_wall` | Big vendors / encyclopedias hold ≥4 of the top 10 with "what is X" content | Do not write another definition. Go long-tail, or go where the discussion is (Reddit, HN) |
|
|
305
|
+
| `listicle_window` | Roundups hold ≥3 of the top 10 | **The only shape you can enter without authority.** `parasiteTargets` lists the roundups — inclusion is cheaper than outranking them |
|
|
306
|
+
| `tool_window` | Tool pages hold ≥3 of the top 10 | A tool page can enter; the angle is what the occupant tools do not do (nothing uploaded, locale-aware text handling) |
|
|
307
|
+
| `open` | No single occupancy pattern the classifier can identify | Read `composition` — it is never a blind box any more |
|
|
308
|
+
|
|
309
|
+
### Read `composition`, then `items`
|
|
310
|
+
|
|
311
|
+
Every SERP carries `composition`: the top 10 counted by kind — `tool`, `tutorial`, `ugc`,
|
|
312
|
+
`listicle`, `reference`, `docs`, `directory`, `template`, `app`, `other` — with per-market
|
|
313
|
+
lexicons. `open` with `{tutorial: 6, ugc: 3}` is a tutorial field a tool page can enter
|
|
314
|
+
(tabledi's Japanese dedupe won one); `open` with reference and consulting hosts on top is a
|
|
315
|
+
definition wall in everything but the label; `template` on top is download intent, not tool
|
|
316
|
+
intent. Intent is still yours: the classifier does not know that `두 리스트 비교` is a Python
|
|
317
|
+
question, but its `ugc`/`tutorial` hosts and titles put that in front of you.
|
|
347
318
|
|
|
348
319
|
### KD and the SERP are different questions — check both
|
|
349
320
|
|
|
350
|
-
`seo keywords` says `stripe mcp server` is KD 4, `band: attackable
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
`
|
|
321
|
+
`seo keywords` says `stripe mcp server` is KD 4, `band: attackable`; `seo serp` on it returns
|
|
322
|
+
`official_wall` — three of the top five are Stripe's own properties. **A low difficulty score
|
|
323
|
+
on a page nobody can enter is not an opportunity.** Never pick keywords from `band` alone; run
|
|
324
|
+
`serp` on any new family before investing a page in it (siblings inherit the verdict, §7.3).
|
|
354
325
|
|
|
355
326
|
The reverse trap is just as expensive: a Japanese error-message query at 2,900/month and KD 0
|
|
356
|
-
looks like a gift until `serp` shows
|
|
357
|
-
|
|
358
|
-
available to you*.
|
|
327
|
+
looks like a gift until `serp` shows wall-to-wall Reddit, Zenn and Qiita threads. High volume,
|
|
328
|
+
zero difficulty and a pure-UGC page means *the demand is real and not available to you*.
|
|
359
329
|
|
|
360
330
|
### The classifier does not judge intent — you do
|
|
361
331
|
|
|
362
|
-
`ai agent deployment` returns `open
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
`
|
|
366
|
-
before committing to a keyword**, whatever the verdict says.
|
|
332
|
+
`ai agent deployment` returns `open`, but its items are about deploying *agent runtimes*, not
|
|
333
|
+
agents deploying *websites* — an intent mismatch a rule engine cannot see, because it requires
|
|
334
|
+
knowing your product; `ai domain registration` likewise means "buy a .ai domain". **Always read
|
|
335
|
+
`items` before committing to a keyword**, whatever the verdict says.
|
|
367
336
|
|
|
368
337
|
### Search Console beats the SERP read
|
|
369
338
|
|
|
370
339
|
The SERP shows who Google ranks first; Search Console shows which queries Google already sends
|
|
371
|
-
to *your* page. When they disagree about intent, Search Console is the fact about you
|
|
340
|
+
to *your* page. When they disagree about intent, Search Console is the fact about you: **a
|
|
372
341
|
keyword your site already earns impressions or clicks on is never an intent-mismatch skip and
|
|
373
342
|
never a retarget**, whatever the top 10 looks like. The move on such a row is additive — a
|
|
374
|
-
section that answers the query, internal links into the page —
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
not entered yet; once Google has put you on a query, it has already answered the intent question.
|
|
343
|
+
section that answers the query, internal links into the page — keeping the title and H1 that
|
|
344
|
+
earned the impressions (tabledi, 2026-09: `invoice data extraction` read as an enterprise wall
|
|
345
|
+
from the SERP while the page was the site's third-best earner at 262 impressions). The
|
|
346
|
+
intent-mismatch rule is for keywords you have not entered yet; once Google has put you on a
|
|
347
|
+
query, it has answered the intent question.
|
|
380
348
|
|
|
381
349
|
### `aiOverview: true`
|
|
382
350
|
|
|
383
|
-
An AI Overview
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
on being *quotable* (§8) than on being *ranked*.
|
|
351
|
+
An AI Overview answers the query above the organic results. Position 3 under one is worth much
|
|
352
|
+
less than position 3 without, and some impressions will never become clicks. Note it, factor it
|
|
353
|
+
into expectations, and lean harder on being *quotable* (§8) than on being *ranked*.
|
|
387
354
|
|
|
388
355
|
### One page or two?
|
|
389
356
|
|
|
390
|
-
Two
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
357
|
+
Two rules, by tier. **Same family, same market: one page** — the second phrasing is a second
|
|
358
|
+
keyword on the same page (`--add-keywords "<word>@<locale>#<family>"` attaches it; the product
|
|
359
|
+
never makes a second page). **Two candidates that may or may not be one intent: read the
|
|
360
|
+
`cluster`** a batch `serp` returns — same-market cells whose top-10 share ≥5 URLs are one page
|
|
361
|
+
in the occupants' eyes (fr *comparer deux tableaux* / *deux feuilles* shared 5: one page;
|
|
362
|
+
ko *파일 비교* / *시트 비교* shared 3: two). The product gives the shared count; the intent call
|
|
363
|
+
is yours. Siblings inherit the verified market's structure; `cells.cannibal` corrects them later.
|
|
395
364
|
|
|
396
365
|
---
|
|
397
366
|
|
|
@@ -409,55 +378,32 @@ For a site with near-zero authority (new domain, few referring domains):
|
|
|
409
378
|
|
|
410
379
|
**Within the same band, intent ranks before volume — until the site's own clicks say
|
|
411
380
|
otherwise.** Commercial rows (`<rival> alternative`, `X vs Y`, `pricing`, `best X for Y`)
|
|
412
|
-
outrank informational rows (`what is X`)
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
a
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
nothing whatsoever about demand. Never report it as "nobody searches for this."
|
|
428
|
-
- **`no_volume`** — it *was* priced and the volume really is 0. That is a **signal**, and often
|
|
429
|
-
a valuable one: a keyword the tools have not caught up with. `email api for ai agents` had no
|
|
430
|
-
volume and a `listicle_window` with four roundups on it. On kunavo, two payment long-tails
|
|
431
|
-
came back at volume 0 and Search Console showed them at positions 4.5 and 8 with real
|
|
432
|
-
impressions — **people were already arriving on words the keyword tool scored as empty.**
|
|
433
|
-
That configuration has a name in `check` output: `pre_emergence` (§9) — and since 0.34.0 the
|
|
434
|
-
same label fires when the window's impressions reach twice the priced monthly volume, because
|
|
435
|
-
a small `sv` next to a large impression count is the same fact (the tool has not caught up,
|
|
436
|
-
or it priced one market while Search Console counts all of them). Either way, the impressions
|
|
437
|
-
are the demand; the `sv` is not a reason to downgrade the row.
|
|
438
|
-
|
|
439
|
-
So: a `no_volume` row whose SERP is already full of category roundups is worth an early page.
|
|
440
|
-
A `no_data` row goes to `seo serp` like any other survivor — the SERP does not need a volume
|
|
441
|
-
figure to show who occupies it. Open and servable → buildable, enrolled as `pending`; wall →
|
|
442
|
-
skip row with the reason. What `no_data` never is: a reason to drop the cell. Measured across
|
|
443
|
-
three sites: the demand the table could not see was real (clize.ai's German MCP cluster,
|
|
444
|
-
`no_data` in the table, 130 impressions in Search Console), and the only page-1 positions any
|
|
445
|
-
of the sites hold are on such cells (kunavo's payment long-tails at 4.5 and 5.8), while the
|
|
446
|
-
priced `attackable` rows sat at 65+ or unseen — the table's coverage and the incumbents'
|
|
447
|
-
coverage are the same coverage. On 2026-09-02, 82 of 119 cells left the funnel at
|
|
448
|
-
the pricing step without a single SERP look; keeping them would have cost $1.64 in serp calls.
|
|
381
|
+
outrank informational rows (`what is X`): they sit at the bottom of the funnel, they convert,
|
|
382
|
+
and conversion evidence funds the next batch. Fill `priority` by intent first, volume second —
|
|
383
|
+
a KD 8 commercial row beats a KD 5 informational row. That is the prior for a site with no
|
|
384
|
+
history; a site with history overrules it — read `gsc.pages.latest` (§9) and rank the intents
|
|
385
|
+
that already earn clicks first (tabledi: 105 of 134 clicks from tool and how-to pages, zero
|
|
386
|
+
from anything commercial).
|
|
387
|
+
|
|
388
|
+
### `no_data` and `no_volume` mean opposite things — and neither drops a cell
|
|
389
|
+
|
|
390
|
+
`no_data` is an absence of data (no upstream row); `no_volume` is a priced 0. Both were the
|
|
391
|
+
cells the page-1 wins came from on three sites (kunavo's payment long-tails at 4.5 and 5.8,
|
|
392
|
+
clize.ai's German MCP cluster at 130 impressions). **Volume orders cells; it never removes one.**
|
|
393
|
+
A sibling with `no_data` is built like any other; a `no_data` head term goes to `serp` like any
|
|
394
|
+
other survivor — the `keywords` receipt's last line says which. `check` labels the configuration
|
|
395
|
+
when it appears: `pre_emergence` (§9).
|
|
449
396
|
|
|
450
397
|
### `--ai` is a different unit
|
|
451
398
|
|
|
452
|
-
`--ai` adds `aiSv`, the volume inside AI engines. **It is a different unit from `sv
|
|
453
|
-
`agent mail
|
|
454
|
-
keyword to itself over time, or rank keywords against each other — never
|
|
455
|
-
|
|
399
|
+
`--ai` adds `aiSv`, the volume inside AI engines. **It is a different unit from `sv`**
|
|
400
|
+
(`agent mail`: 5,400 on Google, 125 in AI engines; `ai email agent`: 140 and 5). Compare a
|
|
401
|
+
keyword to itself over time, or rank keywords against each other — never treat `sv` and
|
|
402
|
+
`aiSv` as the same quantity, and never add them.
|
|
456
403
|
|
|
457
|
-
One locale carries its own
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
honestly does not measure.)
|
|
404
|
+
One locale carries its own caveat: **ko-KR volumes are Google-side only**, and in Korea Naver
|
|
405
|
+
holds the majority of search — read Korean `sv` as a floor, not the market. Simplified Chinese
|
|
406
|
+
is not in the locale list at all: Baidu is a data ecosystem the product does not measure.
|
|
461
407
|
|
|
462
408
|
---
|
|
463
409
|
|
|
@@ -466,55 +412,52 @@ honestly does not measure.)
|
|
|
466
412
|
Priority order, most effective first for a low-authority site:
|
|
467
413
|
|
|
468
414
|
1. **Third-party trust positions.** Registries and directories that accept submissions, and the
|
|
469
|
-
roundups in `parasiteTargets
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
is not, and it will cost you the account and the credibility.
|
|
488
|
-
3. **Your own site last.** Not because it doesn't matter, but because on a new domain it is the
|
|
489
|
-
slowest of the three. Publish there, then go get the first two.
|
|
415
|
+
roundups in `parasiteTargets`: getting listed in a page that already ranks beats outranking
|
|
416
|
+
it. Each target carries `owner`: `publisher` (independent media, review or directory site —
|
|
417
|
+
pitch first), `unknown` (go look at who runs it), `vendor` (the host sells in this category,
|
|
418
|
+
or the roundup sits under a product site's `/blog/`-type path — pitch last, and only if what
|
|
419
|
+
you sell is not what they sell; a vendor's roundup of its own category rarely adds a rival
|
|
420
|
+
and never a product from another category — tabledi's five `client reporting tool` targets
|
|
421
|
+
were all vendor blogs with zero fit, queued as P0 placement anyway). **If every target is
|
|
422
|
+
`vendor`, the `listicle_window` is narrower than the verdict says** — one or two pitches, not
|
|
423
|
+
a placement plan. Directory/forum submissions stay manual — the product produces the target
|
|
424
|
+
list, it does not post. Platforms with a publish API (dev.to, Hashnode) are manual **once**:
|
|
425
|
+
a human creates the account and mints an API key; after that the agent drafts, sets
|
|
426
|
+
`canonical_url` back to your own page (skip it and you compete with yourself), and pushes
|
|
427
|
+
each post as a draft for a human glance-and-publish. The *email* half of outreach: §6.2.
|
|
428
|
+
2. **Where the discussion already is.** Reddit and HN rank on a large share of these queries.
|
|
429
|
+
Participating is legitimate; astroturfing is not, and it
|
|
430
|
+
will cost you the account and the credibility.
|
|
431
|
+
3. **Your own site last.** On a new domain it is the slowest of the three. Publish there, then
|
|
432
|
+
go get the first two.
|
|
490
433
|
|
|
491
434
|
### 6.1 Link strategies an agent can actually run
|
|
492
435
|
|
|
493
436
|
Links are the ~30% (see the formula up top) and the part agents historically skip. Of the
|
|
494
|
-
classic white-hat playbook, these survive
|
|
495
|
-
|
|
437
|
+
classic white-hat playbook, these survive — each produces the asset or the target list, with a
|
|
438
|
+
human approving anything that leaves the building:
|
|
496
439
|
|
|
497
440
|
- **Statistics / first-party-data articles.** Publish numbers nobody else has (your own measured
|
|
498
|
-
data)
|
|
441
|
+
data); ranked stats pages attract citations on their own. Cheapest durable link magnet.
|
|
499
442
|
- **Free tool pages** (§7.2). A tool that ranks becomes a link magnet without outreach.
|
|
500
443
|
- **Parasite pitches.** `serp` hands you `parasiteTargets` — roundups already ranking on your
|
|
501
|
-
keyword
|
|
502
|
-
- **Resource pages / awesome lists.** The dev-ecosystem version of resource-page link building
|
|
503
|
-
|
|
444
|
+
keyword; getting added to one beats months of trying to outrank it. Loop: §6.2.
|
|
445
|
+
- **Resource pages / awesome lists.** The dev-ecosystem version of resource-page link building;
|
|
446
|
+
find them via `serp` on `<topic> resources`-shaped queries; submissions are manual.
|
|
504
447
|
- **HARO-type platforms** (Featured, Qwoted, etc.). Agent drafts the pitch, human sends. Cap the
|
|
505
448
|
experiment: a few per week for a month; no hits → stop.
|
|
506
449
|
|
|
507
|
-
Explicitly out: mass templated outreach (spam — and structurally impossible here
|
|
508
|
-
|
|
450
|
+
Explicitly out: mass templated outreach (spam — and structurally impossible here, every email
|
|
451
|
+
passes an approval gate), buying links, link exchanges. One more filter: **a link any
|
|
509
452
|
competitor can replicate in an afternoon is worth little; price a strategy by how hard it is
|
|
510
|
-
to copy.** Known data gap
|
|
511
|
-
|
|
512
|
-
|
|
453
|
+
to copy.** Known data gap: no competitor-backlink command yet ("who links to this site" —
|
|
454
|
+
Skyscraper/broken-link prospecting needs it; trigger condition in the product doc); until then
|
|
455
|
+
target lists come from `serp` and manual research.
|
|
513
456
|
|
|
514
457
|
### 6.2 The outreach email loop
|
|
515
458
|
|
|
516
|
-
The pitch email is where placement actually gets executed
|
|
517
|
-
|
|
459
|
+
The pitch email is where placement actually gets executed; the inbox is real and outbound is
|
|
460
|
+
gated:
|
|
518
461
|
|
|
519
462
|
```
|
|
520
463
|
serp → parasiteTargets → agent reads the target page, finds the contact
|
|
@@ -522,29 +465,27 @@ serp → parasiteTargets → agent reads the target page, finds the contact
|
|
|
522
465
|
→ replies land in the real inbox → agent reads them and follows up
|
|
523
466
|
```
|
|
524
467
|
|
|
525
|
-
Discipline that keeps this white-hat: every email individually approved
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
apart from "we placed and it didn't take".
|
|
468
|
+
Discipline that keeps this white-hat: every email individually approved; a handful per week, not
|
|
469
|
+
dozens; each pitch written from the target's actual page (name the section your entry fits, say why
|
|
470
|
+
their readers care — two pitches that could be swapped between targets are templates and will read
|
|
471
|
+
as such); every attempt logged in the ledger's `placement` column (§3) — target, date, status — so
|
|
472
|
+
the next session doesn't re-pitch the same page, and a flat round can tell "we never placed
|
|
473
|
+
anything" from "we placed and it didn't take".
|
|
532
474
|
|
|
533
|
-
**Which channel actually sends the mail — decide before drafting, not after.** The loop
|
|
534
|
-
|
|
475
|
+
**Which channel actually sends the mail — decide before drafting, not after.** The loop assumes
|
|
476
|
+
the sending half is in place, and on most cold-start sites it is not:
|
|
535
477
|
|
|
536
478
|
- Run it through `clize email` when the sending domain (a subdomain is fine) is already set up
|
|
537
|
-
there **and** outreach is a standing rhythm — several pitches a week, replies
|
|
538
|
-
|
|
479
|
+
there **and** outreach is a standing rhythm — several pitches a week, replies followed up from
|
|
480
|
+
the inbox across sessions.
|
|
539
481
|
- At one-off volume — two or three pitches, main domain not on clize — the human sending your
|
|
540
|
-
approved drafts from their everyday mailbox **is the optimal path, not a fallback
|
|
541
|
-
send needs their approval anyway
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
gave you in chat. It will be blocked; don't burn the attempt.
|
|
482
|
+
approved drafts from their everyday mailbox **is the optimal path, not a fallback**: every
|
|
483
|
+
send needs their approval anyway, an established mailbox out-delivers a fresh domain by a
|
|
484
|
+
wide margin, and DNS on a production domain for three emails is infrastructure nobody asked
|
|
485
|
+
for. Drafts plus verified recipient addresses is the agent's whole share.
|
|
486
|
+
- Do not drive the user's webmail through a browser instead: host platforms gate agent-composed
|
|
487
|
+
mail behind their own permission layer, separate from any approval given in chat. It will be
|
|
488
|
+
blocked; don't burn the attempt.
|
|
548
489
|
- Never route cold outreach through a transactional channel (Resend and the like) — complaint
|
|
549
490
|
rates poison the sending reputation that receipts and alerts depend on.
|
|
550
491
|
|
|
@@ -553,58 +494,53 @@ assumes the sending half is in place, and on most cold-start sites it is not:
|
|
|
553
494
|
## 7. From row to page
|
|
554
495
|
|
|
555
496
|
An SEO page differs from an ordinary page in three load-bearing ways. Its **brief is a
|
|
556
|
-
worksheet row
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
unranked content). The more mechanical the constraint, the lower the output variance.
|
|
497
|
+
worksheet row** — keyword, locale, serp verdict, intent, format; no row, no page. Its **success
|
|
498
|
+
is measurable and lags by weeks** — so shipping the page and enrolling its keyword (§7.1 ⑤) are
|
|
499
|
+
one act, or the page is an orphan with no scoreboard. And its **format precedes creativity** —
|
|
500
|
+
the SERP dictates the structure, which is what suppresses an agent's worst habit: competent,
|
|
501
|
+
generic, unranked content.
|
|
562
502
|
|
|
563
503
|
**Where the specs live:** `clize build site start` returns the page-type skeletons (landing /
|
|
564
504
|
comparison / tool page) plus the on-page and GEO spec sheet — slug, title, meta, headings, FAQ
|
|
565
505
|
schema rules. **That pack is the single source of truth for specs; this file only carries the
|
|
566
506
|
judgment calls.** Don't improvise slugs and titles from memory.
|
|
567
507
|
|
|
568
|
-
**If a page costs a session, the first deliverable is the generator, not the page.** A
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
**On a site that already has tools, this round's page count is
|
|
576
|
-
|
|
577
|
-
first (§7.2). Siblings come in two prices
|
|
578
|
-
|
|
579
|
-
`tools/apps.js`; clize.ai: a `strings.<loc>.mjs`) — ten in a session is ordinary
|
|
580
|
-
(duplicates, compare, clean) carries locale semantics — full-width and half-width forms in
|
|
508
|
+
**If a page costs a session, the first deliverable is the generator, not the page.** A page
|
|
509
|
+
family — one stem × N locales, one `tool.js`, one skeleton, a strings file per locale (the spec
|
|
510
|
+
pack's Page families section) — costs a strings file per page after the first, where a
|
|
511
|
+
hand-written page costs a session (clize.ai: one page a session to seven the day a generator
|
|
512
|
+
existed; tabledi: forty in two days from one). Build the generator before the second page of
|
|
513
|
+
any family, and never machine-translate a family page.
|
|
514
|
+
|
|
515
|
+
**On a site that already has tools, this round's page count is `check.cells.missing` plus
|
|
516
|
+
`queue`** — the locale siblings of the tools it has, counted by the product; a site without
|
|
517
|
+
tools derives the set first (§7.2). Siblings come in two prices: a *format* tool (viewer,
|
|
518
|
+
merge, split, convert) is one strings entry (tabledi: a `DICT` table in
|
|
519
|
+
`tools/apps.js`; clize.ai: a `strings.<loc>.mjs`) — ten in a session is ordinary; a *text*
|
|
520
|
+
tool (duplicates, compare, clean) carries locale semantics — full-width and half-width forms in
|
|
581
521
|
Japanese, composed and decomposed accents in French — and a sibling that ignores them reports
|
|
582
|
-
"0 duplicates" on a real file
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
the deploy: ship the pages, hold the change. Step ⓪ is done when the pages are *live*, not
|
|
595
|
-
committed — tabledi, 2026-09-02: one session built three things and ended asking about a
|
|
596
|
-
redirect; the next found all three returning 404 in production and ended the same way. Four
|
|
597
|
-
pages built across two sessions, zero live. A session does not end with built, undeployed pages.
|
|
522
|
+
"0 duplicates" on a real file (gate 3 failed); two or three of those per session. Read
|
|
523
|
+
`check.cells` before anything else (tabledi's grid, counted by hand on 2026-09-03: 15 tools × 7
|
|
524
|
+
markets, 51 cells open after three sessions of "next batch"). New tools are code and tests, one
|
|
525
|
+
to three per session — the next batch's rows, not this batch's excuse.
|
|
526
|
+
|
|
527
|
+
**Building and publishing a page that passed the gates on the user's own site is never a question
|
|
528
|
+
for the human.** The human's gates are money, changes that alter what the world already sees (a
|
|
529
|
+
redirect, DNS, a canonical), sends, and posts on other people's platforms. Ask for those in one line
|
|
530
|
+
and build while you wait — never bundle the pages into the question; when a human-gated change
|
|
531
|
+
shares a deploy with pages (a redirect map in the same `vercel.json`), ship the pages and hold the
|
|
532
|
+
change. Step ⓪ is done when the pages are *live*, not committed (tabledi, 2026-09-02: four pages
|
|
533
|
+
built across two sessions, zero live). A session does not end with built, undeployed pages.
|
|
598
534
|
|
|
599
535
|
### 7.1 The pipeline — five steps, each with a pass/fail
|
|
600
536
|
|
|
601
537
|
| step | act | it passed if |
|
|
602
538
|
| --- | --- | --- |
|
|
603
|
-
| ① brief | five fields, written into the row before a word of the page: **intent** — what the searcher wants, from the query, the
|
|
539
|
+
| ① brief | five fields, written into the row before a word of the page: **intent** — what the searcher wants, from the query, the top-10 shapes, and Search Console when the site already earns on it (§4); **occupants** — open and *read* the top 3–5 pages, not their titles: structure, length, what each answers, promises and lacks (fetch them yourself; no command, $0); **product truth** — what the product actually does for this intent (gate 3) and what only it has: first-party data, a working tool, a capability the occupants lack; **angle** — one sentence naming an occupant gap that a product truth fills; **form** — page type from the top 10, length ≈ closest-shaped rival × 1.1–1.2, every H2 mapped to an occupant or a gap, the first 200 words, the FAQ in that market's phrasing. One brief per family; locale siblings change terminology and FAQ only | the angle names a gap *and* an asset — no angle, no page, and the row becomes `skip: no angle`. The three pages that worked had one (clize's OpenClaw "inbox the agent owns"; tabledi's Japanese full-width dedupe; kunavo's 529 failover numbers); the five that read zero did not |
|
|
604
540
|
| ② produce | skeleton from `build site start`, judgment from here, words and code from you | first 200 words answer the query completely; your definition sentence is verbatim-identical site-wide |
|
|
605
541
|
| ③ self-check | against the spec sheet — there is deliberately no audit command | visible FAQ ↔ JSON-LD strictly 1:1; ≥2 internal links with varied anchors |
|
|
606
542
|
| ④ deploy | ship it | page live, in sitemap |
|
|
607
|
-
| ⑤ enroll | `seo check --keywords
|
|
543
|
+
| ⑤ enroll | `seo check --add-keywords "<keyword>@<locale>#<family>"` — the next check binds the live page to the cell (`built`); nothing to write in the ledger | the cell leaves `queue`; the keyword shows under `pending` until a window that includes the ship date closes, then under `latest` or `unseen` |
|
|
608
544
|
|
|
609
545
|
Page type from row type: variant row → landing; `alternative`/`vs` row → comparison; action-
|
|
610
546
|
intent row → use-case; tool-intent row → tool page.
|
|
@@ -614,101 +550,92 @@ intent row → use-case; tool-intent row → tool page.
|
|
|
614
550
|
The one page type where the content *is* the function — and the strongest link asset (§6.1).
|
|
615
551
|
|
|
616
552
|
**A site with fewer than five tools has no multiplier, and inventing the tool set is its first
|
|
617
|
-
production task** — not a product decision to wait for. Three sources, all paid for
|
|
553
|
+
production task** — not a product decision to wait for. Three sources, all already paid for or
|
|
618
554
|
free: (1) the sweep (§1.1) — every rival keyword shaped like a calculator, converter, counter,
|
|
619
|
-
checker, estimator or generator
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
generation-cost estimator, a list of formats is a converter; every number the product already
|
|
624
|
-
maintains is a tool nobody else can keep current; (3) the neighbours of the tools you have.
|
|
555
|
+
checker, estimator or generator (tabledi's teardown: rows.com, formulabot and quadratic earn
|
|
556
|
+
their organic traffic from free calculators, not product pages); (2) the product's own data — a
|
|
557
|
+
price catalog is a cost calculator, a limits table a context-window checker, a media catalog a
|
|
558
|
+
generation-cost estimator, a format list a converter; (3) the neighbours of the tools you have.
|
|
625
559
|
Each candidate gets an English SERP ($0.02) before a line of code; two or three tools per
|
|
626
560
|
session is the honest rate; once the family exists, §7's sibling rule multiplies it by every
|
|
627
|
-
verified market
|
|
628
|
-
round — the page-type mix set that ceiling
|
|
561
|
+
verified market (kunavo, 2026-09-03: two tool URLs, 43 hand-written locale guides, six pages a
|
|
562
|
+
round — the page-type mix set that ceiling).
|
|
629
563
|
|
|
630
564
|
Judgment calls that matter:
|
|
631
565
|
|
|
632
566
|
- **Three words are the whole quality bar: free, instant, no signup.** Tool above the fold,
|
|
633
|
-
explanatory content and FAQ below it
|
|
567
|
+
explanatory content and FAQ below it; the skeleton in the spec pack encodes this layout.
|
|
634
568
|
- **The boundary is the browser sandbox.** Hosted sites are static: build only tools that run
|
|
635
|
-
entirely client-side (generators, converters, calculators — llms.txt
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
- **One tool × N locales is legitimate multiplication, and the
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
clicks — so the failure is the *type*, in every language; kunavo's 199 untranslated copies
|
|
648
|
-
were duplicates, collapsed by canonicalization, and say nothing about locales; the locale
|
|
649
|
-
pages that do earn on both sites are translated guides and tools (kunavo's Korean pricing
|
|
650
|
-
guide is its top non-brand page). The bar for adding a locale to a marketing page is local
|
|
651
|
-
non-brand impressions on the ones that exist — indexing is the floor, not the pass. Locale is
|
|
652
|
-
not a page-generation primitive; a SERP-backed intent is.
|
|
569
|
+
entirely client-side (generators, converters, calculators — llms.txt, robots.txt, JSON-LD
|
|
570
|
+
generators). Tools that must fetch other people's sites (checkers) die on CORS — don't attempt
|
|
571
|
+
them until the platform offers a fetch proxy.
|
|
572
|
+
- **One tool × N locales is legitimate multiplication, and the product keeps the grid.** Each
|
|
573
|
+
locale page is a real, distinct intent — not page-stuffing. `check.cells` derives every page's
|
|
574
|
+
family from its hreflang cluster and lists `missing` (family × served market with no page and
|
|
575
|
+
no keyword) and `queue` (a keyword with no page); a `verified` family (any page earning, or
|
|
576
|
+
any keyword with an enterable verdict) needs **no SERP for its siblings** — one SERP per new
|
|
577
|
+
family, one page per family per market (a second phrasing is a second keyword on that page).
|
|
578
|
+
Marketing and landing pages do not multiply — clize.ai's 72 translated landing pages earn
|
|
579
|
+
what their English originals earn, which is nothing; the locale pages that earn are tools and
|
|
580
|
+
guides.
|
|
653
581
|
- **Pick tools with a shelf life.** Protocol- and format-level tools (llms.txt, schema, robots)
|
|
654
|
-
keep earning links for years; trend-chasing tools die with the trend.
|
|
655
|
-
|
|
582
|
+
keep earning links for years; trend-chasing tools die with the trend. Will anyone search this
|
|
583
|
+
in a year?
|
|
656
584
|
|
|
657
585
|
### 7.3 The four gates
|
|
658
586
|
|
|
659
587
|
Written for an agent with zero SEO experience to follow without wrecking anything — the gates
|
|
660
588
|
do the protecting, not experience:
|
|
661
589
|
|
|
662
|
-
1. **One page, one
|
|
663
|
-
|
|
664
|
-
|
|
590
|
+
1. **One page, one cell.** Every page is a (family, market) cell the product can see in
|
|
591
|
+
`check.cells`, and its family is verified — earning already, or holding an enterable
|
|
592
|
+
verdict from one SERP. A family's first page never skips that SERP; its siblings never
|
|
593
|
+
need one.
|
|
665
594
|
2. **The SERP writes the outline.** Step ① is derivation from `items`, not free composition.
|
|
666
595
|
3. **Promise only what exists.** Features described must actually work; for a tool page, run
|
|
667
596
|
the tool yourself before shipping. Pages that oversell poison the domain's trust and your
|
|
668
597
|
own E-E-A-T.
|
|
669
598
|
4. **Throttle by the site, not the session.** Google's scaled-content rule has three terms —
|
|
670
599
|
many pages, built to manipulate ranking, not helping users — counted per site, with no term
|
|
671
|
-
for how many pages one session shipped
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
- **each page has its own row and its own SERP** (gate 1) — the query exists and is
|
|
676
|
-
enterable;
|
|
600
|
+
for how many pages one session shipped or how they were produced. So there is no page count
|
|
601
|
+
here, per batch or per session. A batch is gated by the site's composition,
|
|
602
|
+
three checks:
|
|
603
|
+
- **each page is a verified cell** (gate 1);
|
|
677
604
|
- **the family is not a template with the noun swapped** — before deploy, diff the
|
|
678
|
-
non-skeleton text of each new page against its siblings and the site.
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
605
|
+
non-skeleton text of each new page against its siblings and the site. Mostly-identical
|
|
606
|
+
pages are doorway pages whatever their keywords say, and one thin family drags the whole
|
|
607
|
+
site's classifier score, tool pages included. Distinct real content per page: a locale page
|
|
608
|
+
written in-locale, a host page whose install and config really differ;
|
|
682
609
|
- **the last batch is being indexed** — `gsc.pages.unseen` (§9) shows the previous batch's
|
|
683
|
-
`index`; find the batch by `firstSeen
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
produces the same state. Mostly indexed → ship the next family
|
|
689
|
-
on a clean implementation → the round is indexing and pruning, not
|
|
690
|
-
paces shipping; it does not certify composition
|
|
691
|
-
fine and earned nothing
|
|
610
|
+
`index`; find the batch by `firstSeen` and book the counts in the batch table (§3). `URL
|
|
611
|
+
is unknown to Google` and `Discovered - currently not indexed` are the queue (a day-old
|
|
612
|
+
batch sits there; not a verdict); `Crawled - currently not indexed` is Google's verdict on
|
|
613
|
+
a page it has read — once you rule out your own hand (a canonical pointing elsewhere,
|
|
614
|
+
hreflang missing or one-way, a stray `noindex`; `cells.defects` lists the hreflang ones),
|
|
615
|
+
which produces the same state. Mostly indexed → ship the next family; mostly
|
|
616
|
+
crawled-not-indexed on a clean implementation → the round is indexing and pruning, not
|
|
617
|
+
shipping. This check paces shipping; it does not certify composition (kunavo's 440 locale
|
|
618
|
+
model pages indexed fine and earned nothing) — that is the second check and the retire
|
|
619
|
+
rule.
|
|
692
620
|
Impressions are not the gate for the next batch: at zero authority they arrive five to six
|
|
693
|
-
weeks after shipping and clicks may not arrive in a quarter
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
the index.
|
|
621
|
+
weeks after shipping and clicks may not arrive in a quarter; a rule that waits for them ships
|
|
622
|
+
nothing for months. Waiting is for *deciding a new
|
|
623
|
+
page type* (§10), never for siblings of a type already decided. The retire rule is the other
|
|
624
|
+
half: a page indexed for two windows with no impressions (`cells.retire` lists them), or
|
|
625
|
+
refused by the index for two, is retired — `noindex` by default (it keeps serving users; only
|
|
626
|
+
its index exposure goes), merge or redirect when another page carries the intent, delete
|
|
627
|
+
only what nobody visits. The composition stays clean only if dead pages leave the index.
|
|
701
628
|
|
|
702
629
|
### 7.4 E-E-A-T floor and locales
|
|
703
630
|
|
|
704
631
|
AI-generated content gets judged hardest on what it usually lacks: a real author entity (name,
|
|
705
632
|
bio, `sameAs` to real profiles) on cornerstone pages, cited sources for claims and numbers, and
|
|
706
|
-
a visible dated update.
|
|
633
|
+
a visible dated update. Cheap to add, expensive to lack.
|
|
707
634
|
|
|
708
|
-
Multi-locale placement (
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
635
|
+
Multi-locale placement (the other half of the non-English cells in §1.2): unified-operation
|
|
636
|
+
sites use slash paths (`/de/`, `/ja/`) not subdomains; hreflang pairs point both ways; keep the
|
|
637
|
+
same slug stem across locales. Write in-locale terminology, never machine-translate the English
|
|
638
|
+
page.
|
|
712
639
|
|
|
713
640
|
---
|
|
714
641
|
|
|
@@ -716,32 +643,30 @@ translate the English page.
|
|
|
716
643
|
|
|
717
644
|
Retrieval-augmented engines quote passages, not pages. What survives extraction:
|
|
718
645
|
|
|
719
|
-
- **Answer completely in the first 200 words.** Assume the extractor never reaches
|
|
646
|
+
- **Answer completely in the first 200 words.** Assume the extractor never reaches the second
|
|
720
647
|
section.
|
|
721
|
-
- **One-sentence extractables.** Each key claim
|
|
722
|
-
|
|
648
|
+
- **One-sentence extractables.** Each key claim stands alone when lifted out of context;
|
|
649
|
+
pronouns and "as mentioned above" destroy quotability.
|
|
723
650
|
- **Statistics and named sources.** Concrete numbers with attribution get quoted; adjectives
|
|
724
651
|
don't.
|
|
725
|
-
- **Define your terms verbatim and identically everywhere.**
|
|
726
|
-
|
|
652
|
+
- **Define your terms verbatim and identically everywhere.** A definition that varies between
|
|
653
|
+
pages lets no single phrasing accumulate authority.
|
|
727
654
|
- **Machine-readable surface**: `llms.txt`, schema.org markup, a sitemap, and IndexNow pings.
|
|
728
655
|
|
|
729
656
|
### Measuring whether it worked
|
|
730
657
|
|
|
731
|
-
The scoreboard is `check` → `traffic.ai
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
**Do not build a citation-probe cron**
|
|
738
|
-
Field-tested and rejected: self-authored prompts
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
plus the spot-check; and all AI-citation measurement is sampling — trends against your own
|
|
744
|
-
baseline, never absolute share.
|
|
658
|
+
The scoreboard is `check` → `traffic.ai`: an AI-engine referral is a real user who clicked
|
|
659
|
+
through, and the first non-zero is the milestone (§9). While it is all zeros, the interim
|
|
660
|
+
instrument is a **manual spot-check**: every week or two, ask the 3–5 questions your money
|
|
661
|
+
pages answer in the engines themselves (~15 minutes, logged in) and note who gets named. Zero
|
|
662
|
+
is a reading.
|
|
663
|
+
|
|
664
|
+
**Do not build a citation-probe cron** (a saved prompt set fired at N engines on a schedule).
|
|
665
|
+
Field-tested and rejected: self-authored prompts self-confirm, a low-authority site's probe is a
|
|
666
|
+
flat zero that still costs keys and upkeep, and a measurement nobody is present to act on is
|
|
667
|
+
inventory. A probe earns its keep only when there is something to *attribute* — sustained AI
|
|
668
|
+
referrals, a before/after around a launch. Until then, referrers plus the spot-check; all
|
|
669
|
+
AI-citation measurement is sampling — trends against your own baseline, never absolute share.
|
|
745
670
|
|
|
746
671
|
---
|
|
747
672
|
|
|
@@ -752,26 +677,25 @@ baseline, never absolute share.
|
|
|
752
677
|
`rank.source` is always `"gsc"`: positions come from Search Console, and measurement makes no
|
|
753
678
|
upstream calls — the only thing `check` may pay for is pricing words it has never priced.
|
|
754
679
|
|
|
755
|
-
- `position` is the **impression-weighted average over `rank.window`**, not a rank at a moment
|
|
680
|
+
- `position` is the **impression-weighted average over `rank.window`**, not a rank at a moment:
|
|
756
681
|
one good day barely moves it, and it is not comparable to a scraped SERP position. `delta` is
|
|
757
|
-
positive when you moved up, against `rank.prevWindow`; `series` is weekly, newest first,
|
|
682
|
+
positive when you moved up, against `rank.prevWindow`; `series` is weekly, newest first,
|
|
758
683
|
empty weeks absent — read the dates.
|
|
759
684
|
- **`movers` runs on two axes**: position shifted by 3+, *or* impressions halved / doubled with
|
|
760
685
|
the larger side at 20+ (`prevImpressions` / `prevClicks` sit on every row). Traffic is
|
|
761
|
-
impressions × CTR, and position alone is blind to the event that matters most
|
|
762
|
-
duplicate-finder page fell from 3,088 impressions to 50 while
|
|
763
|
-
|
|
764
|
-
|
|
686
|
+
impressions × CTR, and position alone is blind to the event that matters most (tabledi's
|
|
687
|
+
duplicate-finder page fell from 3,088 impressions to 50 while `delta` read −0.5). A word with
|
|
688
|
+
impressions last window and none now appears with `position: null`. **A collapse with a flat
|
|
689
|
+
position is a page problem — go to `gsc.pages` before you touch the ledger.**
|
|
765
690
|
- `pending` lists words **enrolled after `rank.window.to`**: no reading yet, not in `unseen`, no
|
|
766
|
-
signal form
|
|
691
|
+
signal form; a zero on a pending word says nothing. One exception you apply yourself: a word
|
|
767
692
|
enrolled for a page older than the window reads as `unseen`.
|
|
768
693
|
- Every row carries **`sv` and `kd` next to the Search Console numbers** — demand and delivery
|
|
769
694
|
side by side. `sv: 27100` at `position: 74` and `sv: 0` at `position: 4.5` are different worlds.
|
|
770
|
-
- `unseen` lists words **Search Console did not see this window
|
|
695
|
+
- `unseen` lists words **Search Console did not see this window** — not "not ranking"; GSC has a
|
|
771
696
|
row only once you get impressions. A real position for one of them is a deliberate
|
|
772
697
|
`clize seo serp <keyword>` (~$0.02); never for all of them. Non-English cells appear as
|
|
773
|
-
`word@locale`,
|
|
774
|
-
`locale` as a field.
|
|
698
|
+
`word@locale`, as enrolled; `latest` / `pending` / `signals` rows carry `locale` as a field.
|
|
775
699
|
- `rank: null` means the round had nothing to synthesise from (no Search Console access, or no
|
|
776
700
|
list) — read `notes`. **Competitor positions are not in `check`**; `--competitors` is remembered
|
|
777
701
|
configuration, and a head-to-head is `seo serp <keyword>`.
|
|
@@ -780,51 +704,47 @@ upstream calls — the only thing `check` may pay for is pricing words it has ne
|
|
|
780
704
|
|
|
781
705
|
Every `rank.latest` row carries **`topPage`** — the page of yours that took the most impressions
|
|
782
706
|
on that query — and **`pages`**, how many of yours got any. Pure aggregate; the judgment is the
|
|
783
|
-
comparison with the
|
|
707
|
+
comparison with the page the cell is bound to (`check.cells`, §3):
|
|
784
708
|
|
|
785
709
|
| configuration | what it means | what to do |
|
|
786
710
|
| --- | --- | --- |
|
|
787
|
-
| **Accidental carrier** —
|
|
788
|
-
| **Mismatch** —
|
|
789
|
-
| **Self-cannibalisation** — `pages` > 1 | Your pages are splitting one query | Merge, or canonical one to the other — after looking: `pages` is a count, not a split, and `2` with one page taking almost everything is ordinary |
|
|
711
|
+
| **Accidental carrier** — the cell has no page of its own, `topPage` has a value | Google picked a carrier out of pages you built for something else | Go with its pick: internal links and a section that answers the query on *that* page. Cheapest double-down there is |
|
|
712
|
+
| **Mismatch** — the cell's page is A, `topPage` is B | A is not recognised as the answer | Structure, not content: links and anchors into A, title/H1 alignment, is A indexed. More words on A is the reflex to resist |
|
|
713
|
+
| **Self-cannibalisation** — `pages` > 1 (`cells.cannibal` expands it) | Your pages are splitting one query | Merge, or canonical one to the other — after looking: `pages` is a count, not a split, and `2` with one page taking almost everything is ordinary |
|
|
790
714
|
|
|
791
715
|
### `gsc.pages` — the page face
|
|
792
716
|
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
enumerates and builds (§10).
|
|
717
|
+
Three facts per page, no judgment (by page since 0.34.0). Reading it is the first fifteen minutes of
|
|
718
|
+
a round, not the round: the shapes below say what to fix, and the round still enumerates and builds
|
|
719
|
+
(§10).
|
|
797
720
|
|
|
798
721
|
| list | what is in it | the facts per row |
|
|
799
722
|
| --- | --- | --- |
|
|
800
723
|
| `latest` | the 20 pages with the most impressions this window | `impressions` / `clicks` and their `prev*` twins, `position`, live `status` (final HTTP status; `finalUrl` when it landed elsewhere) |
|
|
801
724
|
| `movers` | pages whose impressions halved or doubled (larger side 20+), including pages that went to zero | the same, plus `index` for the collapsed ones |
|
|
802
|
-
| `unseen` | sitemap URLs with no impressions this window —
|
|
725
|
+
| `unseen` | sitemap URLs with no impressions this window — newest `firstSeen` first, then `lastmod`; up to 200, `unseenTotal` gives the total | `firstSeen` (when `check` first saw the URL in the sitemap), `status`, `index` — Google's own words: `Submitted and indexed`, `Crawled - currently not indexed`, `Discovered - currently not indexed`, `URL is unknown to Google` |
|
|
803
726
|
|
|
804
727
|
Read it as three shapes, in this order:
|
|
805
728
|
|
|
806
729
|
- **Lost page** — in `movers`, impressions collapsed, `status` ≠ 200 or a `finalUrl` elsewhere.
|
|
807
730
|
Shape B: restore the URL or 301 it to the page with the same intent (a mismatched redirect is
|
|
808
|
-
a soft 404), request indexing, leave the ledger alone —
|
|
809
|
-
|
|
810
|
-
- **Not on the shelf** — in `unseen` with `index` anything but indexed
|
|
811
|
-
discovery and content cannot help it. Internal links, sitemap `lastmod`, an indexing
|
|
812
|
-
then wait a window.
|
|
813
|
-
this shape until proven otherwise. This list is also the batch gate (§7.3): the last batch
|
|
814
|
-
mostly `indexed` → ship the next family; mostly `Crawled - currently not indexed` → Google's
|
|
815
|
-
own verdict on those pages, and this round prunes instead of shipping.
|
|
731
|
+
a soft 404), request indexing, leave the ledger alone — a window in which the page was dead
|
|
732
|
+
reads nothing.
|
|
733
|
+
- **Not on the shelf** — in `unseen` with `index` anything but indexed: not in the race yet,
|
|
734
|
+
and discovery and content cannot help it. Internal links, sitemap `lastmod`, an indexing
|
|
735
|
+
request, then wait a window. This list is also the batch gate (§7.3 gate 4).
|
|
816
736
|
- **Indexed and ignored** — in `unseen` with `index` indexed, for a window after its ship date.
|
|
817
|
-
Only now
|
|
818
|
-
|
|
737
|
+
Only now a keyword question (§4, §5); after a second such window a retire question (§7.3,
|
|
738
|
+
`cells.retire`).
|
|
819
739
|
|
|
820
740
|
Index status costs a quota call per URL, so `check` inspects at most 30 per run — collapsed
|
|
821
|
-
movers first, then the newest unseen sitemap URLs, then top pages — and `notes` says how many
|
|
741
|
+
movers first, then the newest unseen sitemap URLs, then top pages — and `notes` says how many;
|
|
822
742
|
`index: null` means *not inspected this round*, never "not indexed". `unseen` order follows
|
|
823
|
-
`firstSeen`, then `lastmod
|
|
824
|
-
(clize.ai, 2026-09-02: 124 of 124) cannot push the newest batch out of the inspection budget
|
|
825
|
-
the first check after 0.35.0 `firstSeen`
|
|
826
|
-
|
|
827
|
-
`
|
|
743
|
+
`firstSeen`, then `lastmod`, so a site-wide edit that stamps every page with today's `lastmod`
|
|
744
|
+
(clize.ai, 2026-09-02: 124 of 124) cannot push the newest batch out of the inspection budget
|
|
745
|
+
(the first check after 0.35.0 seeds `firstSeen` from `lastmod`). If `notes` says inspection is
|
|
746
|
+
unavailable, the service account is `Restricted`; `Full` unlocks it. No sitemap means no
|
|
747
|
+
`unseen` list — publish one.
|
|
828
748
|
|
|
829
749
|
### `rank.signals` — the cross-source read, done for you
|
|
830
750
|
|
|
@@ -834,27 +754,27 @@ so you can overrule it:
|
|
|
834
754
|
|
|
835
755
|
| form | the configuration | how to read it |
|
|
836
756
|
| --- | --- | --- |
|
|
837
|
-
| `pre_emergence` | priced volume is **0**, or the window's impressions are **at least twice** the priced monthly volume — and Search Console shows real impressions (10+) | Demand is ahead of the keyword tools; on a low-authority site
|
|
838
|
-
| `authority_limited` | many impressions, position 50+, **zero clicks** | Google offers the
|
|
757
|
+
| `pre_emergence` | priced volume is **0**, or the window's impressions are **at least twice** the priced monthly volume — and Search Console shows real impressions (10+) | Demand is ahead of the keyword tools; on a low-authority site the cheapest entry there is. Write the page. A small `sv` next to a large impression count is the same fact — never let `sv` downgrade the row |
|
|
758
|
+
| `authority_limited` | many impressions, position 50+, **zero clicks** | Google offers the surface and withholds the position: an authority bottleneck **on that theme** — another page on it will not move it; go do §6.1. Per keyword: production on other themes continues |
|
|
839
759
|
| `demand_no_surface` | real search volume, **no impressions at all** this window | Google is not putting you on the shelf. A discovery question (what occupies it? → `seo serp`), not a measurement one |
|
|
840
760
|
|
|
841
761
|
`demand_no_surface` is capped at the five most attackable words (lowest KD, then volume;
|
|
842
762
|
`pending` words never take this form); the full list is `rank.unseen`. On a cold-start site
|
|
843
|
-
nearly every word is in this shape — normal state, not a finding
|
|
844
|
-
failure. There is deliberately no `data_conflict` form: `check` has one position source
|
|
845
|
-
a scrape disagrees with Search Console, believe Search Console — a 28-day average of
|
|
846
|
-
Google served against one personalised fetch of a rotating page.
|
|
763
|
+
nearly every word is in this shape — normal state, not a finding — and an empty `signals` is
|
|
764
|
+
not a failure. There is deliberately no `data_conflict` form: `check` has one position source,
|
|
765
|
+
and when a scrape disagrees with Search Console, believe Search Console — a 28-day average of
|
|
766
|
+
what Google served against one personalised fetch of a rotating page.
|
|
847
767
|
|
|
848
768
|
### `keywords.byBand`, `traffic`, `gsc`
|
|
849
769
|
|
|
850
770
|
- `byBand` counts **only priced keywords**; the unpriced gap is stated in `notes`. `no_data`
|
|
851
|
-
inside it means "we asked and the upstream has no row" —
|
|
852
|
-
|
|
771
|
+
inside it means "we asked and the upstream has no row" — about a long-tail word, not about
|
|
772
|
+
demand (§5).
|
|
853
773
|
- `traffic.ai` is always present, **including when it is all zeros — zero is the finding**, and
|
|
854
|
-
the first non-zero referral is the milestone. The numbers are adaptively sampled and rounded
|
|
774
|
+
the first non-zero referral is the milestone. The numbers are adaptively sampled and rounded:
|
|
855
775
|
compare over time, never quote as exact counts. Same-host referrers are already excluded.
|
|
856
|
-
- `gsc.newQueries` is the feedback loop closing (§1.3) — the most valuable output of the
|
|
857
|
-
command; fold them into the matrix. `gsc: null` is not an error: read `notes
|
|
776
|
+
- `gsc.newQueries` is the feedback loop closing (§1.3) — the most valuable output of the
|
|
777
|
+
command; fold them into the matrix. `gsc: null` is not an error: read `notes`; usually the
|
|
858
778
|
service account is not on the property yet.
|
|
859
779
|
|
|
860
780
|
### The one rule that ties it together
|
|
@@ -869,75 +789,72 @@ sentence (`authority_limited`); the roundups still come from a deliberate `seo s
|
|
|
869
789
|
## 10. The cycle
|
|
870
790
|
|
|
871
791
|
**The loop starts at measurement, and its purpose is allocation.** Between rounds the only
|
|
872
|
-
thing that changes is what *your* actions did
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
**A round is a pipeline, and it opens by building.** ⓪ **ship the
|
|
878
|
-
`
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
"
|
|
887
|
-
skipped, and skipping it breaks step ② two weeks later: "flat, no signal" and "flat, no signal,
|
|
888
|
-
*and we already pitched five roundups*" are different rows, and only the ledger can tell them
|
|
889
|
-
apart.
|
|
792
|
+
thing that changes is what *your* actions did, and that shows up only in `check`, which is free.
|
|
793
|
+
Each round's real question is
|
|
794
|
+
**where the next unit of work goes** — double down where a signal appeared, stop where none
|
|
795
|
+
did, and keep enumerating cells the ledger has not priced yet.
|
|
796
|
+
|
|
797
|
+
**A round is a pipeline, and it opens by building.** ⓪ **ship the queue** — every cell in
|
|
798
|
+
`check.cells.queue` (a keyword with no page) and every `missing` cell you can phrase, siblings
|
|
799
|
+
from the family brief and new families from their own (§7.1 ①) — before reading a single
|
|
800
|
+
number → ① read the feedback (`check`, free) → ② allocate
|
|
801
|
+
(double down / stop loss / new bet) → ③ execute what is cheap now (siblings, retargets,
|
|
802
|
+
placement drafts) and write the rest as the next session's `to build` rows → ④ book it (§3) →
|
|
803
|
+
⑤ report it (two tables, below). This round's analysis qualifies the *next* round's batch; it
|
|
804
|
+
does not postpone this one's. Step ⓪ vanished in three consecutive runs, each naming itself an
|
|
805
|
+
"analysis round"; step ④ is the other one skipped, and without it step ② cannot tell "flat, no
|
|
806
|
+
signal" from "flat, *and we already pitched five roundups*".
|
|
890
807
|
|
|
891
808
|
```
|
|
892
809
|
clize seo check # free — every session on an existing site starts here
|
|
893
810
|
```
|
|
894
811
|
|
|
895
812
|
**Domain of the loop: a site that exists.** `check` needs `--domain` (or a clize project
|
|
896
|
-
directory). No site yet?
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
813
|
+
directory). No site yet? Pre-cycle work: discovery (§1), first batch (§7), enroll — the cycle
|
|
814
|
+
starts at that first check. **Round one is not special — it is the round that reads zero.** The
|
|
815
|
+
zeros are the baseline, and the entry read still pays before you spend a cent: it surfaces the
|
|
816
|
+
GSC service-account setup (a 2-minute human step — hand it over now, in parallel) and, on a
|
|
817
|
+
site with history, free seeds (`gsc.topQueries` / `newQueries`).
|
|
901
818
|
|
|
902
819
|
### ②–③ Allocate, then execute — branch on what the read says
|
|
903
820
|
|
|
904
821
|
| the read says | this round is |
|
|
905
822
|
| --- | --- |
|
|
906
|
-
| nothing yet (round one), or `demand_no_surface` across the board | **discovery + first bets**: `seo competitors <2–3 rivals>` → capability matrix (§1.2, seeded
|
|
907
|
-
| `movers` rising, a `rank.latest` row's clicks first going non-zero, or `traffic.ai.total` first non-zero | **double down** — the branch the
|
|
823
|
+
| nothing yet (round one), or `demand_no_surface` across the board | **discovery + first bets**: `seo competitors <2–3 rivals>` → capability matrix (§1.2, seeded from the entry read) → `seo keywords <the whole list>` in one call → drop `wall` → `seo serp` each survivor → ledger rows (§3) → first batch: **at least three page types, every buildable row in each**, through the §7 pipeline (a generator first for any family, specs from `build site start`, prose per §8) → enroll: `seo check --keywords <survivors> --brand <you>` → start placement (§6) immediately, without waiting for rankings to "settle". Total ≈ $1 |
|
|
824
|
+
| `movers` rising, a `rank.latest` row's clicks first going non-zero, or `traffic.ai.total` first non-zero | **double down** — the branch the flywheel exists for: enumerate that keyword's sibling cells and price only the new ones (old ones are cached), add internal links into the page actually carrying it (`topPage` is Google's answer, the cell's page is yours — when they disagree, §9), add placement on that theme. Returns compound where the signal already is |
|
|
908
825
|
| `pre_emergence` | write that page this round — demand is ahead of the tools |
|
|
909
826
|
| a `rank.movers` row whose impressions collapsed with a flat position, or a `gsc.pages.movers` row with `status` ≠ 200 | **technical round, no keyword work**: restore or redirect the URL, request indexing, re-read next window. Shape B (top of this file) — links and new pages do not fix a dead URL |
|
|
910
|
-
| `gsc.pages.unseen` rows whose `index` is not indexed | **indexing round**: internal links into them, sitemap `lastmod`, indexing requests;
|
|
827
|
+
| `gsc.pages.unseen` rows whose `index` is not indexed | **indexing round**: internal links into them, sitemap `lastmod`, indexing requests; judge their keywords only a window after they are indexed. Also the batch gate (§7.3 gate 4): mostly indexed → ship the next family; mostly `Crawled - currently not indexed` → no new pages this round, retire what Google refused twice |
|
|
911
828
|
| `rank.pending` non-empty | those words are not measured yet — no branch applies to them this round; do not read their zero as "missed" |
|
|
912
|
-
| `
|
|
829
|
+
| `cells.missing` or `cells.queue` non-empty | **production round**: phrase the missing cells in their language, `--add-keywords` them, build the queue — siblings of a verified family without a SERP; a new family through one `serp` first |
|
|
830
|
+
| `cells.retire` / `cells.cannibal` / `cells.defects` non-empty | **pruning round** for those pages: noindex or merge what two windows refused, collapse two pages on one intent into one, fix one-way hreflang (§7.3) |
|
|
831
|
+
| `authority_limited` | placement only **on that theme** — another page on it will not move it (§6). Per keyword, not per site: production continues on every other theme. Every funded theme reading this way is Shape C (top of this file): re-derive the ledger toward tool, long-tail and locale rows before pitching, building the tools first if the site has none (§7.2) |
|
|
913
832
|
| `gsc.newQueries` non-empty | mini-discovery: fold them into the matrix, price the new cells, extend the tracked list if they survive the SERP check |
|
|
914
|
-
| no movers two rounds running | the plan is stale, not slow — back to §1 and re-derive toward new page types
|
|
833
|
+
| no movers two rounds running | the plan is stale, not slow — back to §1 and re-derive toward new page types. The placement queue does not gate this: a queue that has waited on a human for two rounds is recorded as `blocked:` and handed over while production goes on — placement is human-gated, building is not, and one never holds the other (kunavo's four ready pitches held production for seven rounds) |
|
|
915
834
|
|
|
916
835
|
**Rows are not exclusive.** A round takes every branch its read matches — a technical fix, a
|
|
917
|
-
placement action and a production batch in
|
|
918
|
-
|
|
919
|
-
|
|
836
|
+
placement action and a production batch in one session is the normal shape, not three rounds.
|
|
837
|
+
`technical round` and `indexing round` say what to do *for those pages*; they never cancel the
|
|
838
|
+
production step for the rest of the site.
|
|
920
839
|
|
|
921
840
|
### ④ Book the round
|
|
922
841
|
|
|
923
|
-
Before the session ends, update `docs/seo/worksheet.md` (§3)
|
|
924
|
-
next round's allocation possible:
|
|
842
|
+
Before the session ends, update `docs/seo/worksheet.md` (§3):
|
|
925
843
|
|
|
926
|
-
- **`
|
|
927
|
-
|
|
928
|
-
a `pitched:` entry —
|
|
929
|
-
- **The reason for anything you skipped**, as a skip row
|
|
930
|
-
|
|
844
|
+
- **`placement`** for anything sent or accepted (`pitched:<target, date>` / `listed:<where>`);
|
|
845
|
+
pages are not booked by hand — `check.cells` reads them from the site. A pitch with no reply
|
|
846
|
+
is still a `pitched:` entry — that target was worked.
|
|
847
|
+
- **The reason for anything you skipped**, as a skip row — what stops the next session re-buying
|
|
848
|
+
a keyword this one ruled out.
|
|
931
849
|
- **New rows for whatever the read handed you** — `newQueries`, a keyword that just took a
|
|
932
850
|
`signals` form — with their serp verdict once you have it.
|
|
933
|
-
- **The batch table** (§3):
|
|
934
|
-
|
|
935
|
-
|
|
851
|
+
- **The batch table** (§3): per shipped batch, `indexed` / `not indexed` from `gsc.pages.unseen`
|
|
852
|
+
(found by `firstSeen`), and whether this window was another zero — what the next round's
|
|
853
|
+
batch gate and retire rule read.
|
|
936
854
|
|
|
937
|
-
The stop-loss branch
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
to fill in. That state lives in the ledger or nowhere.
|
|
855
|
+
The stop-loss branch ("no movers two rounds running") is answerable only if the previous round
|
|
856
|
+
wrote down what it put in; the product records pages, not pitches (a field it cannot measure
|
|
857
|
+
would be a form for you to fill in), so that state lives in the ledger or nowhere.
|
|
941
858
|
|
|
942
859
|
### ⑤ Report the round
|
|
943
860
|
|
|
@@ -951,59 +868,53 @@ every row the round touched, one line each:
|
|
|
951
868
|
| claude code preise | de-DE | official_wall | — | — | — | skip |
|
|
952
869
|
|
|
953
870
|
`status` is one of `built` (shipped this round), `to build`, `exists` (a page already carries
|
|
954
|
-
it), `skip` (with the reason)
|
|
955
|
-
`
|
|
956
|
-
|
|
957
|
-
"Analysis round", "next batch",
|
|
958
|
-
|
|
959
|
-
the session is not finished:
|
|
960
|
-
page / status (`sent` / `drafted` / `blocked: needs human`).
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
the cell count that justifies it
|
|
964
|
-
|
|
871
|
+
it), `skip` (with the reason); `built` and `exists` are read off `check.cells`, not from memory.
|
|
872
|
+
A `to build` row carries one of three blockers: `needs human` (a redirect, a send,
|
|
873
|
+
money — asked in one line, §7), `needs tool code` (a new client-side tool; name the session it
|
|
874
|
+
ships in), `needs generator` (no family scaffold yet). "Analysis round", "next batch",
|
|
875
|
+
"awaiting go-ahead" and "needs a SERP" are not blockers — a SERP is $0.02 inside the fuse,
|
|
876
|
+
bought on the spot — and a row wearing one means the session is not finished: back to step ⓪.
|
|
877
|
+
Second, **placement** — target / page / status (`sent` / `drafted` / `blocked: needs human`).
|
|
878
|
+
Then at most five lines of narrative. Findings with no pages table is test 1 (§3) in its final
|
|
879
|
+
form; an empty pages table says so *in* the table, with
|
|
880
|
+
the cell count that justifies it (kunavo round five: four findings, no table, three buildable
|
|
881
|
+
families in its own prose unbuilt).
|
|
965
882
|
|
|
966
883
|
**Cadence**: SEO is a weeks-to-months system and the window `check` measures is 4 weeks wide —
|
|
967
|
-
checking daily
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
three markets never priced, a nine-cell family in prose — the round shipped zero pages and
|
|
976
|
-
deferred the pricing for the third time, quoting this paragraph.
|
|
884
|
+
checking daily re-reads the same window; every two weeks is plenty. A round that re-reads an
|
|
885
|
+
unchanged window must not re-judge *existing rows*: same window, no movers, no new queries → the P0s
|
|
886
|
+
stand (tabledi, 2026-09-02, re-ran discovery on 09-01's data and flipped its P0: noise). **That rule
|
|
887
|
+
never means no new cells** — the window has no opinion on a cell the ledger has never priced. Every
|
|
888
|
+
round, whatever the window: count the unbuilt buildable cells (`cells.queue`, `cells.missing`, the
|
|
889
|
+
ledger's unbuilt rows) against the site's cell space (§1.2: 100–150 for a full site); fewer than ten
|
|
890
|
+
→ this round enumerates (§1) and builds (kunavo, 2026-09-02, round five: ledger exhausted, three
|
|
891
|
+
markets never priced, a nine-cell family in prose — zero pages, quoting this paragraph).
|
|
977
892
|
|
|
978
893
|
---
|
|
979
894
|
|
|
980
895
|
## 11. Calibration discipline
|
|
981
896
|
|
|
982
|
-
Every measurement here is a sample, not a census
|
|
983
|
-
rotating results page
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
0 to 40 a month" is defensible. "We have 3% AI visibility" is not, no matter which tool printed
|
|
989
|
-
it. Breaking this rule in customer-facing copy is a product-integrity failure, not a rounding
|
|
897
|
+
Every measurement here is a sample, not a census: rank sampling is one fetch of a personalized,
|
|
898
|
+
rotating results page; traffic is adaptively sampled; AI-engine visibility from any tool
|
|
899
|
+
samples a non-deterministic system (one independent evaluation found a major commercial tool
|
|
900
|
+
undercounting by 40×). So: **promise time series against yourself, never absolute share.** "Our
|
|
901
|
+
AI referrals went from 0 to 40 a month" is defensible; "we have 3% AI visibility" is not,
|
|
902
|
+
whichever tool printed it — in customer-facing copy a product-integrity failure, not a rounding
|
|
990
903
|
error.
|
|
991
904
|
|
|
992
|
-
**The cases in this file are samples of one to three sites,
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
copies varied *translation* (identical, so Google collapsed them); tabledi's page-1 tools varied
|
|
905
|
+
**The cases in this file are samples of one to three sites, each varying one thing.** Cite a
|
|
906
|
+
case only with what it varied, how many, and over which window: clize.ai's 72 locale pages
|
|
907
|
+
varied *page type*; kunavo's 199 copies varied *translation*; tabledi's page-1 tools varied
|
|
996
908
|
*age* (three years), not links; tabledi's 36 marketing locales were a day old when first read.
|
|
997
|
-
A rule that survives only because its example was misread is
|
|
998
|
-
|
|
909
|
+
A rule that survives only because its example was misread is waiting to fail — three such were
|
|
910
|
+
corrected here on 2026-09-02.
|
|
999
911
|
|
|
1000
912
|
---
|
|
1001
913
|
|
|
1002
914
|
## What this skill will not do
|
|
1003
915
|
|
|
1004
|
-
Generate the content (
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
is shipped URLs and their index status, not a ledger (§3 test 6).
|
|
916
|
+
Generate the content (clize is the hands, you're the brain); submit to directories or post to
|
|
917
|
+
forums for you (manual, on purpose — §6.2's email loop is in scope because every send passes a
|
|
918
|
+
human approval gate); promise rankings; or monitor on its own (a recheck happens when you run
|
|
919
|
+
one: measurement pays off only when someone can act on it). It does count pages: a round's
|
|
920
|
+
deliverable is shipped URLs and their index status, not a ledger (§3 test 6).
|