seo 0.0.15 → 0.1.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/LICENSE +201 -0
- package/PRIVACY.md +95 -0
- package/README.md +338 -35
- package/SECURITY.md +55 -0
- package/TERMS.md +94 -0
- package/TRADEMARKS.md +27 -0
- package/dist/cli.js +125 -0
- package/dist/cli.js.map +1 -0
- package/dist/dist-CSY2_p-j.js +713 -0
- package/dist/dist-CSY2_p-j.js.map +1 -0
- package/dist/dist-FeAUNn9A.js +3 -0
- package/dist/index.d.ts +17921 -0
- package/dist/index.js +26769 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp.d.ts +57 -0
- package/dist/mcp.js +26744 -0
- package/dist/mcp.js.map +1 -0
- package/dist/package-uzXzqDW6.js +23818 -0
- package/dist/package-uzXzqDW6.js.map +1 -0
- package/package.json +101 -23
- package/skills/README.md +81 -0
- package/skills/affected-urls/SKILL.md +39 -0
- package/skills/affected-urls/agents/openai.yaml +4 -0
- package/skills/ai-readiness/SKILL.md +34 -0
- package/skills/ai-readiness/agents/openai.yaml +4 -0
- package/skills/ai-referrals/SKILL.md +31 -0
- package/skills/ai-referrals/agents/openai.yaml +4 -0
- package/skills/audit-page/SKILL.md +50 -0
- package/skills/audit-page/agents/openai.yaml +4 -0
- package/skills/audit-urls/SKILL.md +39 -0
- package/skills/audit-urls/agents/openai.yaml +4 -0
- package/skills/cannibalisation/SKILL.md +31 -0
- package/skills/cannibalisation/agents/openai.yaml +4 -0
- package/skills/community-intent/SKILL.md +39 -0
- package/skills/community-intent/agents/openai.yaml +4 -0
- package/skills/compare-crawls/SKILL.md +40 -0
- package/skills/compare-crawls/agents/openai.yaml +4 -0
- package/skills/content-optimization/SKILL.md +31 -0
- package/skills/content-optimization/agents/openai.yaml +4 -0
- package/skills/crawl-diff/SKILL.md +51 -0
- package/skills/crawl-diff/agents/openai.yaml +4 -0
- package/skills/crawl-history/SKILL.md +37 -0
- package/skills/crawl-history/agents/openai.yaml +4 -0
- package/skills/crawl-report/SKILL.md +37 -0
- package/skills/crawl-report/agents/openai.yaml +4 -0
- package/skills/crawler-rules/SKILL.md +34 -0
- package/skills/crawler-rules/agents/openai.yaml +4 -0
- package/skills/ctr-underperformers/SKILL.md +31 -0
- package/skills/ctr-underperformers/agents/openai.yaml +4 -0
- package/skills/decaying-pages/SKILL.md +31 -0
- package/skills/decaying-pages/agents/openai.yaml +4 -0
- package/skills/entity-readiness/SKILL.md +34 -0
- package/skills/entity-readiness/agents/openai.yaml +4 -0
- package/skills/explain-crawl-issue/SKILL.md +32 -0
- package/skills/explain-crawl-issue/agents/openai.yaml +4 -0
- package/skills/generate-llms-txt/SKILL.md +37 -0
- package/skills/generate-llms-txt/agents/openai.yaml +4 -0
- package/skills/geo-gaps/SKILL.md +37 -0
- package/skills/geo-gaps/agents/openai.yaml +4 -0
- package/skills/index-coverage/SKILL.md +84 -0
- package/skills/index-coverage/agents/openai.yaml +4 -0
- package/skills/index-coverage-plan/SKILL.md +50 -0
- package/skills/index-coverage-plan/agents/openai.yaml +4 -0
- package/skills/index-monitor/SKILL.md +49 -0
- package/skills/index-monitor/agents/openai.yaml +4 -0
- package/skills/index-watch/SKILL.md +77 -0
- package/skills/index-watch/agents/openai.yaml +4 -0
- package/skills/internal-links/SKILL.md +31 -0
- package/skills/internal-links/agents/openai.yaml +4 -0
- package/skills/link-recovery/SKILL.md +51 -0
- package/skills/link-recovery/agents/openai.yaml +4 -0
- package/skills/llms-txt-audit/SKILL.md +34 -0
- package/skills/llms-txt-audit/agents/openai.yaml +4 -0
- package/skills/measure-change/SKILL.md +52 -0
- package/skills/measure-change/agents/openai.yaml +4 -0
- package/skills/monthly-action-plan/SKILL.md +50 -0
- package/skills/monthly-action-plan/agents/openai.yaml +4 -0
- package/skills/monthly-report/SKILL.md +50 -0
- package/skills/monthly-report/agents/openai.yaml +4 -0
- package/skills/narrative-report/SKILL.md +51 -0
- package/skills/narrative-report/agents/openai.yaml +4 -0
- package/skills/okf-build/SKILL.md +39 -0
- package/skills/okf-build/agents/openai.yaml +4 -0
- package/skills/okf-validate/SKILL.md +43 -0
- package/skills/okf-validate/agents/openai.yaml +4 -0
- package/skills/page-opportunities/SKILL.md +31 -0
- package/skills/page-opportunities/agents/openai.yaml +4 -0
- package/skills/performance/SKILL.md +50 -0
- package/skills/performance/agents/openai.yaml +4 -0
- package/skills/performance-audit/SKILL.md +31 -0
- package/skills/performance-audit/agents/openai.yaml +4 -0
- package/skills/pseo-audit/SKILL.md +103 -0
- package/skills/pseo-audit/agents/openai.yaml +4 -0
- package/skills/query-clusters/SKILL.md +31 -0
- package/skills/query-clusters/agents/openai.yaml +4 -0
- package/skills/quick-wins/SKILL.md +31 -0
- package/skills/quick-wins/agents/openai.yaml +4 -0
- package/skills/redirect-trace/SKILL.md +51 -0
- package/skills/redirect-trace/agents/openai.yaml +4 -0
- package/skills/refresh-priorities/SKILL.md +48 -0
- package/skills/refresh-priorities/agents/openai.yaml +4 -0
- package/skills/search-performance-overview/SKILL.md +48 -0
- package/skills/search-performance-overview/agents/openai.yaml +4 -0
- package/skills/second-page/SKILL.md +50 -0
- package/skills/second-page/agents/openai.yaml +4 -0
- package/skills/segment-impact/SKILL.md +50 -0
- package/skills/segment-impact/agents/openai.yaml +4 -0
- package/skills/seo/SKILL.md +74 -0
- package/skills/seo/agents/openai.yaml +4 -0
- package/skills/seo-fix-queue/SKILL.md +50 -0
- package/skills/seo-fix-queue/agents/openai.yaml +4 -0
- package/skills/seo-geo-readiness/SKILL.md +60 -0
- package/skills/seo-geo-readiness/agents/openai.yaml +4 -0
- package/skills/seo-site-audit/SKILL.md +59 -0
- package/skills/seo-site-audit/agents/openai.yaml +4 -0
- package/skills/seo-to-ai-query/SKILL.md +31 -0
- package/skills/seo-to-ai-query/agents/openai.yaml +4 -0
- package/skills/setup-check/SKILL.md +49 -0
- package/skills/setup-check/agents/openai.yaml +4 -0
- package/skills/site-crawl/SKILL.md +39 -0
- package/skills/site-crawl/agents/openai.yaml +4 -0
- package/skills/striking-distance/SKILL.md +52 -0
- package/skills/striking-distance/agents/openai.yaml +4 -0
- package/skills/technical-watch/SKILL.md +49 -0
- package/skills/technical-watch/agents/openai.yaml +4 -0
- package/skills/top-fixes/SKILL.md +38 -0
- package/skills/top-fixes/agents/openai.yaml +4 -0
- package/skills/traffic-anomaly/SKILL.md +52 -0
- package/skills/traffic-anomaly/agents/openai.yaml +4 -0
- package/skills/update-correlation/SKILL.md +51 -0
- package/skills/update-correlation/agents/openai.yaml +4 -0
- package/skills/update-postmortem/SKILL.md +49 -0
- package/skills/update-postmortem/agents/openai.yaml +4 -0
- package/.jshintrc +0 -18
- package/.npmignore +0 -3
- package/.travis.yml +0 -3
- package/Makefile +0 -10
- package/index.js +0 -2
- package/lib/middleware.js +0 -159
- package/lib/seo.js +0 -32
- package/test/init.js +0 -43
- package/test/middleware.test.js +0 -111
- package/test/seo-page-result.html +0 -9
- package/test/seo-page.html +0 -9
- package/test/seo-routes.js +0 -5
- package/test/vendor/jquery-1.11.1.min.js +0 -4
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: index-watch
|
|
3
|
+
description: Monitor a bounded URL set with Google Search Console URL Inspection and interpret exact indexed-state evidence, current reviews, regressions, recoveries, failures, and quota-deferred checks. Use when an agent needs to check whether watched URLs changed indexing state, investigate exact robots/indexing/fetch/canonical evidence, or plan recurring sitemap monitoring without overstating URL Inspection as a live test.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Index watch
|
|
7
|
+
|
|
8
|
+
Call `seo_list_reports` with category `monitoring` when discovery is needed.
|
|
9
|
+
Call `seo_describe_report` with id `index-watch`, then call `seo_run_report`
|
|
10
|
+
with that id and only the described parameters. Read `structuredContent` as the
|
|
11
|
+
machine contract. Use report id `index-monitor` for a bounded oldest-first
|
|
12
|
+
sitemap sample. Use report id `index-coverage-plan` before monitoring a large
|
|
13
|
+
inventory across multiple Search Console properties.
|
|
14
|
+
|
|
15
|
+
For the shared schema-backed CLI path:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
seo reports describe index-watch --json
|
|
19
|
+
seo reports run index-watch --params '{"site":"sc-domain:example.com","urls":["https://example.com/a","https://example.com/b"],"dailyLimit":25}' --json
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
This validates the same parameters used by MCP. The focused commands below add
|
|
23
|
+
saved monitoring state, sitemap selection, and friendlier flags for recurring
|
|
24
|
+
human workflows.
|
|
25
|
+
|
|
26
|
+
## Run the report
|
|
27
|
+
|
|
28
|
+
1. Pass the selected Search Console property as `site`.
|
|
29
|
+
2. Keep explicit `urls` at 100 or fewer. Every URL must belong to the property.
|
|
30
|
+
3. Use `dailyLimit` only to set a lower local safety limit. It cannot exceed
|
|
31
|
+
Google's documented 2,000 daily inspections per property.
|
|
32
|
+
4. For sitemap monitoring, check `source.possiblyTruncated`, `dataStatus`,
|
|
33
|
+
`warnings`, `neverAttempted`, `neverSucceeded`, `retryWaiting`, `fresh`,
|
|
34
|
+
`stale`, `due`, `selected`, and `unselectedDue` before summarising coverage.
|
|
35
|
+
5. Read `currentIssues`, `regressions`, `recoveries`, `failed`, `quotaBlocked`,
|
|
36
|
+
and `deferred` separately.
|
|
37
|
+
|
|
38
|
+
CLI equivalents:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
seo index-watch --site sc-domain:example.com --urls https://example.com/a,https://example.com/b --json
|
|
42
|
+
seo index-watch --site sc-domain:example.com --sitemaps https://example.com/sitemap.xml --inspect-limit 25 --json
|
|
43
|
+
seo index-watch --site sc-domain:example.com --sitemaps https://example.com/sitemap.xml --plan --json
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Interpret evidence
|
|
47
|
+
|
|
48
|
+
- `inspectionStatus: succeeded` means Google returned an indexed snapshot.
|
|
49
|
+
- `indexStatus` maps exact verdicts: `PASS` to `indexed`, `NEUTRAL` to
|
|
50
|
+
`excluded`, `FAIL` to `invalid`, and everything else to `unknown`.
|
|
51
|
+
- `currentIssue` means stable enum or canonical evidence needs review against
|
|
52
|
+
the URL's intended state. An excluded URL or alternate canonical may be
|
|
53
|
+
intentional.
|
|
54
|
+
- `changeKind: regression` means a prior clear successful snapshot became an
|
|
55
|
+
issue. `recovery` means the reverse.
|
|
56
|
+
- `baseline` means there is no previous successful snapshot. A first-run issue
|
|
57
|
+
is still a current review and a new alert.
|
|
58
|
+
- `failed`, `quota-blocked`, and `deferred` are operational outcomes, not SEO
|
|
59
|
+
defects. They are not comparable with a successful indexed state.
|
|
60
|
+
- `requestSent: false` means the local quota broker blocked the call before it
|
|
61
|
+
reached Google. Use `retryAt` when it is present.
|
|
62
|
+
- Use `issueCodes` and typed `changes` for machine reasoning. Keep
|
|
63
|
+
`coverageState` as display evidence because Google localises that free text.
|
|
64
|
+
|
|
65
|
+
## Guardrails
|
|
66
|
+
|
|
67
|
+
- URL Inspection is Google's indexed version for one URL. It is not a live
|
|
68
|
+
crawl and does not guarantee current search appearance.
|
|
69
|
+
- Do not report every `NEUTRAL` verdict or canonical difference as a defect.
|
|
70
|
+
- Do not infer inventory-wide health from the bounded selected sample.
|
|
71
|
+
- Sitemap failures wait 24 hours before automatic selection retries. Do not
|
|
72
|
+
retry quota-blocked or deferred URLs before `retryAt`.
|
|
73
|
+
- The local UTC-day quota ledger cannot observe calls made by other machines or
|
|
74
|
+
Google clients. A provider 429 remains authoritative.
|
|
75
|
+
- Fix authentication and property access failures instead of treating the
|
|
76
|
+
report as sparse data.
|
|
77
|
+
- Prefer BYO Google credentials if shared OAuth project quota becomes a limit.
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
interface:
|
|
2
|
+
display_name: "Index Watch"
|
|
3
|
+
short_description: "Monitor exact Google indexed-state changes safely"
|
|
4
|
+
default_prompt: "Use $index-watch to inspect a bounded URL set, separate current index reviews from regressions and failures, and explain the evidence without treating Google URL Inspection as a live test."
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: internal-links
|
|
3
|
+
description: Find fetched source pages with query evidence relevant to one target URL and no verified contextual link; use when an agent needs bounded link candidates rather than automatic anchor insertion.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Internal link candidates
|
|
7
|
+
|
|
8
|
+
Use this report to find source pages whose retained GSC queries overlap with demand for a target URL. It resolves target aliases, fetches bounded candidate pages, checks technical state, and inspects observed links and placement before returning a review candidate. Exact query overlap is stronger than lexical overlap, but neither proves that a link belongs in the page or that adding one will improve rankings.
|
|
9
|
+
|
|
10
|
+
## Run the report
|
|
11
|
+
|
|
12
|
+
Use the compact MCP flow:
|
|
13
|
+
|
|
14
|
+
1. Call `seo_list_reports` with `{"category":"opportunities"}`.
|
|
15
|
+
2. Call `seo_describe_report` with `{"id":"internal-links"}`.
|
|
16
|
+
3. Call `seo_run_report` with `{"id":"internal-links","params":{"site":"sc-domain:example.com","targetUrl":"https://example.com/guides/seo","days":90,"limit":15,"checkLimit":40,"minImpressions":25}}`.
|
|
17
|
+
|
|
18
|
+
The CLI invokes the same handler:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
seo reports describe internal-links --json
|
|
22
|
+
seo reports run internal-links --params '{"site":"sc-domain:example.com","targetUrl":"https://example.com/guides/seo","days":90,"limit":15,"checkLimit":40,"minImpressions":25}' --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`site` and `targetUrl` are required. `checkLimit` bounds fetched candidates; `limit` bounds returned candidates. Increase fetch concurrency or enable JavaScript only when the site and task justify the extra load.
|
|
26
|
+
|
|
27
|
+
## Interpret and act
|
|
28
|
+
|
|
29
|
+
Check `dataStatus`, target verification, aliases, canonical, technical signals, and source completeness first. Review `selection.attemptedSources`, checked, failed, unchecked, technical exclusions, alias exclusions, and existing-link exclusions. A low `checkLimit` can leave plausible candidates unchecked. Each item includes exact or lexical query matches, shared terms, impressions, fetch diagnostics, technical signals, and `linkEvidence`. Distinguish `missing`, `non-contextual-only`, and `alias-contextual`; respect observed and limited link counts. Priority is a heuristic combining match evidence, not estimated impact.
|
|
30
|
+
|
|
31
|
+
Safe action is to read the source passage, confirm the target is genuinely useful there, choose natural anchor wording, add one contextual link, and recrawl to verify it. Do not insert links in bulk, replace navigation links without reason, link from technically unsuitable pages, or claim ranking impact from a candidate score.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: link-recovery
|
|
3
|
+
description: Join retained GSC page value with current redirect and indexability checks; use it to prioritise previously visible URLs that may now be broken or misdirected.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Recover search-value URLs
|
|
7
|
+
|
|
8
|
+
Use `link-recovery` to find retained GSC page rows with prior clicks or
|
|
9
|
+
impressions whose current fetch path ends in a technical problem. This joins
|
|
10
|
+
historical search observations with a present redirect trace, which is useful
|
|
11
|
+
for triage after migrations or URL changes. Prior visibility helps order the
|
|
12
|
+
queue. It does not prove that fixing a URL will restore the same traffic.
|
|
13
|
+
|
|
14
|
+
## Run the report
|
|
15
|
+
|
|
16
|
+
With MCP, call `seo_list_reports` with `{"category":"monitoring"}`, call
|
|
17
|
+
`seo_describe_report` with `{"id":"link-recovery"}`, then use `seo_run_report`.
|
|
18
|
+
Example:
|
|
19
|
+
`{"id":"link-recovery","params":{"site":"sc-domain:example.com","days":90,"limit":25,"minClicks":1,"minImpressions":100,"js":false,"refresh":true}}`.
|
|
20
|
+
|
|
21
|
+
The CLI has the same schema:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe link-recovery --json
|
|
25
|
+
seo reports run link-recovery --params '{"site":"sc-domain:example.com","days":90,"limit":25,"minClicks":1,"minImpressions":100,"refresh":true}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The discovery schema currently exposes broad number types. Use positive whole
|
|
29
|
+
days and bounded non-negative thresholds.
|
|
30
|
+
|
|
31
|
+
## Interpret the output
|
|
32
|
+
|
|
33
|
+
Confirm `range` and `summary.checked` before reading recoverable counts. The
|
|
34
|
+
summary separates high, medium, and low severity and totals observed clicks and
|
|
35
|
+
impressions for affected retained rows. Those `clicksAtRisk` and
|
|
36
|
+
`impressionsAtRisk` values describe the checked period; they are not a forecast
|
|
37
|
+
of future loss or recovery.
|
|
38
|
+
|
|
39
|
+
Each item preserves the original URL, final URL, GSC metrics, primary and full
|
|
40
|
+
issue lists, severity, the redirect `trace`, and a recommendation with evidence,
|
|
41
|
+
effort, and confidence. Inspect chain status, final-page indexability,
|
|
42
|
+
canonicals, and warnings directly. Failed checks, selection limits, or retained
|
|
43
|
+
GSC rows outside the returned set constrain coverage.
|
|
44
|
+
|
|
45
|
+
## Act safely
|
|
46
|
+
|
|
47
|
+
Restore a page only when it should still exist. Otherwise add one direct 301 to
|
|
48
|
+
the closest equivalent destination and align its canonical after verifying
|
|
49
|
+
intent. Fix server errors and accidental noindex controls before content work.
|
|
50
|
+
Do not redirect unrelated URLs to a homepage, remove intentional controls, or
|
|
51
|
+
promise traffic recovery from historical metrics.
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: llms-txt-audit
|
|
3
|
+
description: Inspect an optional llms.txt file and derive a bounded set of suitable page candidates from crawl evidence. Use when reviewing agent-facing site navigation without treating the file as a ranking requirement.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Audit llms.txt
|
|
7
|
+
|
|
8
|
+
`llms.txt` is optional publisher-provided navigation for agents. Its presence is not a general search requirement or ranking signal, and its absence is not a technical SEO defect. This report checks the observed file response and suggests eligible pages that could belong in a useful inventory.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
For MCP, call `seo_list_reports` with category `crawl` only when discovery is needed. Call `seo_describe_report` with `{ "id": "llms-txt-audit" }`, then `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "llms-txt-audit",
|
|
17
|
+
"params": { "reportId": "crawl_example_20260710" }
|
|
18
|
+
}
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Check MCP `isError`, then read `structuredContent`. The CLI exposes the same contract:
|
|
22
|
+
|
|
23
|
+
```sh
|
|
24
|
+
seo reports describe llms-txt-audit --json
|
|
25
|
+
seo reports run llms-txt-audit --params '{"reportId":"crawl_example_20260710"}' --json
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Using `url` instead of `reportId` starts a fresh crawl. Prefer a saved snapshot when the recommendations will be compared with other reports.
|
|
29
|
+
|
|
30
|
+
## Interpret the result
|
|
31
|
+
|
|
32
|
+
Review `exists`, the resolved file URL, response status, headline, issues, and `recommendedPages`. Candidate pages are drawn from successfully fetched, indexable pages and exclude common utility or private paths; ordering uses crawl evidence such as internal authority and content depth. That selection is a heuristic inventory, not proof that every important page is present or suitable for publication.
|
|
33
|
+
|
|
34
|
+
Check the source report's date, cap, partial state, failed requests, warnings, and caveats with `crawl-report`. A short recommendation list from a capped crawl is not sitewide evidence. If the file exists, verify that its URLs are current, canonical, public, and aligned with publisher intent. If it does not exist, recommend creating one only when it improves agent navigation. Keep any generated file concise and human-reviewed; never claim that adding it will improve indexing, rankings, traffic, AI selection, or citations.
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: measure-change
|
|
3
|
+
description: Measure the before-and-after impact of a saved or ad hoc SEO change with equal finalized Google Search Console windows, optional GA4 landing-page evidence, and an optional control. Use when an agent needs to evaluate a release, page edit, migration, template change, or SEO test without mistaking an incomplete after-period for a decline.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Measure SEO change
|
|
7
|
+
|
|
8
|
+
Call `seo_list_reports` with category `experiments` when discovery is needed.
|
|
9
|
+
Call `seo_describe_report` with id `measure-change`, then call `seo_run_report`
|
|
10
|
+
with that id and only the described parameters. Read `structuredContent` as the
|
|
11
|
+
machine contract. Use the CLI for CI, saved JSON, or environments without MCP.
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
seo reports describe measure-change --json
|
|
15
|
+
seo reports run measure-change --params '{"site":"sc-domain:example.com","scope":"page","target":"https://example.com/page","title":"Updated page","changedAt":"2025-10-01","beforeDays":28,"afterDays":28}' --json
|
|
16
|
+
|
|
17
|
+
seo tests report \
|
|
18
|
+
--project <project> \
|
|
19
|
+
--scope page \
|
|
20
|
+
--target https://example.com/page \
|
|
21
|
+
--date 2026-06-01 \
|
|
22
|
+
--before 28 \
|
|
23
|
+
--after 28 \
|
|
24
|
+
--json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Describe the report before building ad hoc parameters because the schema keeps
|
|
28
|
+
saved-test and inline-test inputs in one contract. The catalog runner and the
|
|
29
|
+
focused command execute the same measurement logic.
|
|
30
|
+
|
|
31
|
+
For a saved test, pass its `id` instead of the ad hoc site, scope, target, and date fields.
|
|
32
|
+
|
|
33
|
+
## Workflow
|
|
34
|
+
|
|
35
|
+
1. Use the same whole-number duration for `beforeDays` and `afterDays`. Raw totals from unequal calendar windows are not comparable.
|
|
36
|
+
2. Read `dataStatus`, `window`, `source`, `warnings`, and `caveats` before interpreting metrics.
|
|
37
|
+
3. Confirm `window.effectiveDays` equals `window.requestedDays`. If `afterWindowTruncated` is true, the tool uses an equal shortened baseline, returns `partial`, and withholds a directional verdict.
|
|
38
|
+
4. Require at least 7 finalized days in each window for a directional verdict. Shorter complete windows remain useful observations but return `not-enough-data`.
|
|
39
|
+
5. Treat GSC clicks, impressions, CTR, and impression-weighted average position as observed before/after evidence. Timing does not prove that the recorded change caused the movement.
|
|
40
|
+
6. For query-scoped tests, treat `retained-query-date-aggregates` as partial. A missing retained window returns null metrics and is not a zero or a loss.
|
|
41
|
+
7. If GA4 is present, check its property timezone and `source.analytics.status`. GA4 day boundaries can differ from GSC Pacific dates; sampling, thresholding, or `(other)` grouping makes GA4 evidence partial.
|
|
42
|
+
8. Use a control only when it represents a credible unaffected comparison. Adjusted deltas use a control-ratio counterfactual, not raw subtraction across differently sized groups.
|
|
43
|
+
9. Investigate query mix, devices, countries, indexability, SERP changes, seasonality, and other releases before recommending a rollout or reversal.
|
|
44
|
+
|
|
45
|
+
## Interpretation rules
|
|
46
|
+
|
|
47
|
+
- Never call `not-enough-data` positive, negative, or flat.
|
|
48
|
+
- Never annualize or forecast the observed delta.
|
|
49
|
+
- Do not compare this run with another run that used different effective window lengths.
|
|
50
|
+
- `clickPct: null` means the before value was zero; it is not an infinite percentage gain.
|
|
51
|
+
- A partial GA4 source does not invalidate complete GSC evidence, but it does limit analytics conclusions.
|
|
52
|
+
- Provider, auth, property, and invalid-date errors are failures, not zero movement.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: monthly-action-plan
|
|
3
|
+
description: Run a calendar-month reporting workflow with a narrative and explicit actions. Use it for a repeatable review whose caveats remain attached to each measurement.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Monthly workflow
|
|
7
|
+
|
|
8
|
+
This workflow packages the monthly narrative into a sequenced, agent-friendly
|
|
9
|
+
result with explicit steps and actions. It helps keep recurring reviews
|
|
10
|
+
consistent. It can report measured movement, but it cannot establish a cause,
|
|
11
|
+
promise recovery, or turn incomplete provider evidence into a full-property
|
|
12
|
+
conclusion.
|
|
13
|
+
|
|
14
|
+
## Run it
|
|
15
|
+
|
|
16
|
+
Use the exact MCP discovery flow:
|
|
17
|
+
|
|
18
|
+
1. Call `seo_list_reports` with `category: "workflows"` and select `monthly-action-plan`.
|
|
19
|
+
2. Call `seo_describe_report` with `id: "monthly-action-plan"`; confirm its current parameters.
|
|
20
|
+
3. Call `seo_run_report` with that id and only schema-valid parameters.
|
|
21
|
+
|
|
22
|
+
CLI parity:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
seo reports describe monthly-action-plan --json
|
|
26
|
+
seo reports run monthly-action-plan --params '{"site":"sc-domain:example.com","month":"2026-05","limit":10,"includeBrand":false}' --json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Supply `month` as `YYYY-MM`. `limit` controls retained output, not the provider's
|
|
30
|
+
underlying completeness. Keep `includeBrand` explicit when comparisons must be
|
|
31
|
+
reproducible across months.
|
|
32
|
+
|
|
33
|
+
## Interpret and act
|
|
34
|
+
|
|
35
|
+
Inspect the workflow envelope: `summary`, each entry in `steps`, `actions`, and
|
|
36
|
+
the nested `output`. Confirm the requested month, final-data window, provider
|
|
37
|
+
status, skipped sections, warnings, caveats, and retained caps. Follow narrative
|
|
38
|
+
claims back into their structured diagnosis or measurement. A skipped section
|
|
39
|
+
is not a zero, and a top-level successful workflow does not make every nested
|
|
40
|
+
source complete.
|
|
41
|
+
|
|
42
|
+
Use actions as a review queue, not automatic edit instructions. Verify affected
|
|
43
|
+
URLs and intentional controls, reproduce technical defects, and record any
|
|
44
|
+
approved changes for future measurement. Keep month-over-month movement
|
|
45
|
+
separate from explanations. Do not invent click, traffic, ranking, or revenue
|
|
46
|
+
forecasts, and do not attribute movement to an algorithm update or deployment
|
|
47
|
+
from timing alone.
|
|
48
|
+
|
|
49
|
+
Read MCP `structuredContent` as the machine contract. The rendered Markdown is
|
|
50
|
+
the human brief, not an alternative data source for agents.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: monthly-report
|
|
3
|
+
description: Generate a calendar-month SEO narrative from finalized first-party evidence. Use it to brief humans while preserving source status, caveats, and measured next actions.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Monthly report
|
|
7
|
+
|
|
8
|
+
Monthly reporting matters because it fixes the analysis to a named calendar
|
|
9
|
+
period and turns several measurements into one reviewable brief. The report can
|
|
10
|
+
show observed movement and prioritized investigations. It cannot establish why
|
|
11
|
+
traffic changed, guarantee that a recommended edit will help, or forecast
|
|
12
|
+
clicks, rankings, revenue, or future performance.
|
|
13
|
+
|
|
14
|
+
## Run it
|
|
15
|
+
|
|
16
|
+
Use the exact MCP discovery flow:
|
|
17
|
+
|
|
18
|
+
1. Call `seo_list_reports` with `category: "reporting"` and select `monthly-report`.
|
|
19
|
+
2. Call `seo_describe_report` with `id: "monthly-report"` and inspect the current schema.
|
|
20
|
+
3. Call `seo_run_report` with `id: "monthly-report"` and only described parameters.
|
|
21
|
+
|
|
22
|
+
The CLI exposes the same report:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
seo reports describe monthly-report --json
|
|
26
|
+
seo reports run monthly-report --params '{"site":"sc-domain:example.com","month":"2026-05","limit":10,"includeBrand":false,"verifyContent":true,"verifyLimit":5}' --json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use `YYYY-MM` for `month`. `limit` bounds retained findings, not provider row
|
|
30
|
+
retrieval. `verifyContent` fetches a bounded subset, so `verifyLimit` must not
|
|
31
|
+
be interpreted as full-site validation.
|
|
32
|
+
|
|
33
|
+
## Interpret and act
|
|
34
|
+
|
|
35
|
+
Confirm `month`, the underlying date windows, `dataStatus`, source completeness,
|
|
36
|
+
skipped sections, warnings, and caveats before reading the headline. Treat the
|
|
37
|
+
narrative as a rendering of structured evidence. Follow its references into
|
|
38
|
+
the diagnosis, measured changes, priorities, and monitoring results when a
|
|
39
|
+
claim needs verification. A zero from a complete source differs from an
|
|
40
|
+
unavailable, partial, filtered, or capped section.
|
|
41
|
+
|
|
42
|
+
Safe actions start with the highest-evidence priorities: validate affected URLs,
|
|
43
|
+
compare relevant templates, inspect confirmed technical regressions, and assign
|
|
44
|
+
owners to bounded tests. Keep brand filtering and content-verification status
|
|
45
|
+
visible. Record what changed so the next month can measure it. Do not rewrite a
|
|
46
|
+
page merely because it appears in a heuristic opportunity list, and do not
|
|
47
|
+
present update overlap or timing as causation.
|
|
48
|
+
|
|
49
|
+
Read MCP `structuredContent` as the machine contract. Use returned Markdown for
|
|
50
|
+
the human brief, but never parse it to recover data already present in JSON.
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: narrative-report
|
|
3
|
+
description: Assemble diagnosis, change measurement, and monitoring evidence into a readable SEO narrative. Use it for an evidence-linked briefing rather than a new source of truth.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Report narrative
|
|
7
|
+
|
|
8
|
+
This report turns several structured analyses into a coherent explanation. It
|
|
9
|
+
is useful when a person needs the important findings, caveats, and next actions
|
|
10
|
+
without reading every raw section. The narrative summarizes evidence; it does
|
|
11
|
+
not strengthen weak evidence, prove causation, or make missing and partial data
|
|
12
|
+
complete.
|
|
13
|
+
|
|
14
|
+
## Run it
|
|
15
|
+
|
|
16
|
+
Use the exact MCP discovery flow:
|
|
17
|
+
|
|
18
|
+
1. Call `seo_list_reports` with `category: "reporting"` and select `narrative-report`.
|
|
19
|
+
2. Call `seo_describe_report` with `id: "narrative-report"` before constructing parameters.
|
|
20
|
+
3. Call `seo_run_report` with `id: "narrative-report"` and schema-valid parameters.
|
|
21
|
+
|
|
22
|
+
CLI parity:
|
|
23
|
+
|
|
24
|
+
```sh
|
|
25
|
+
seo reports describe narrative-report --json
|
|
26
|
+
seo reports run narrative-report --params '{"site":"sc-domain:example.com","days":90,"recentDays":7,"limit":10,"includeBrand":false,"changeLimit":5}' --json
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Use explicit date bounds only when the described schema supports the intended
|
|
30
|
+
window; otherwise `days` and `recentDays` keep comparisons consistent.
|
|
31
|
+
`changeLimit` bounds attempted change measurements, while `limit` bounds
|
|
32
|
+
retained report items.
|
|
33
|
+
|
|
34
|
+
## Interpret and act
|
|
35
|
+
|
|
36
|
+
Read `headline` only after checking top-level caveats. Then inspect `sections`,
|
|
37
|
+
`priorities`, `diagnosis`, `changeMeasurements`,
|
|
38
|
+
`changeMeasurementAttempts`, and `monitoring`. A failed or skipped measurement
|
|
39
|
+
must stay visible; it is not a zero. Preserve each section's dates,
|
|
40
|
+
completeness, thresholds, limits, and evidence references. Treat update timing,
|
|
41
|
+
template groupings, and opportunity scores as investigation context, not
|
|
42
|
+
ranking causes.
|
|
43
|
+
|
|
44
|
+
Safe actions should trace back to observed evidence: reproduce a technical
|
|
45
|
+
failure, inspect the affected URLs, validate an intentional control, or run a
|
|
46
|
+
bounded content change with a recorded date. Keep recommended verification
|
|
47
|
+
steps separate from asserted defects. Do not invent traffic lift, rank gains,
|
|
48
|
+
revenue impact, or certainty that the source does not provide.
|
|
49
|
+
|
|
50
|
+
MCP `structuredContent` is the machine contract. Returned Markdown is for human
|
|
51
|
+
communication and should not replace the underlying JSON evidence.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: okf-build
|
|
3
|
+
description: Build a deterministic OKF Markdown knowledge bundle from a bounded crawl and validate its file contract. Use when an agent needs portable site evidence with explicit source selection and caveats.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Build an OKF bundle
|
|
7
|
+
|
|
8
|
+
An OKF bundle packages crawl-derived concepts, page inventory, link relationships, provenance, and caveats as portable Markdown. The builder ranks eligible pages deterministically and limits the selected concepts. This makes the artifact reproducible, but it does not make extracted claims true or current.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
For MCP, call `seo_list_reports` with category `crawl` only when discovery is needed. Call `seo_describe_report` with `{ "id": "okf-build" }`, then `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "okf-build",
|
|
17
|
+
"params": {
|
|
18
|
+
"reportId": "crawl_example_20260710",
|
|
19
|
+
"maxConcepts": 25,
|
|
20
|
+
"includeFiles": true,
|
|
21
|
+
"title": "Example site knowledge"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
Check `isError`, then use `structuredContent`. CLI parity is:
|
|
27
|
+
|
|
28
|
+
```sh
|
|
29
|
+
seo reports describe okf-build --json
|
|
30
|
+
seo reports run okf-build --params '{"reportId":"crawl_example_20260710","maxConcepts":25,"includeFiles":true,"title":"Example site knowledge"}' --json
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
`includeFiles` is opt-in because file bodies can be large. Request only the manifest when discovering scope.
|
|
34
|
+
|
|
35
|
+
## Inspect the bundle
|
|
36
|
+
|
|
37
|
+
Read the manifest's schema version, report id, source URL, generation time, crawl status, title, concept count, file paths, warnings, and caveats. The `selection` block distinguishes source, eligible, duplicate-final, selected, and limited page counts and records the deterministic ordering. If selected pages equal the limit, treat the bundle as bounded rather than exhaustive.
|
|
38
|
+
|
|
39
|
+
Review the returned validation before using files. Then inspect citations, canonical URLs, titles, summaries, and relationships against source pages, especially for sensitive or time-dependent claims. The generated log and caveat files should travel with the bundle. A successful structural validation does not establish ownership, freshness, factual accuracy, completeness, or safe downstream use. Rebuild from a comparable fresh crawl when the site changes; do not silently merge snapshots with different scope.
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: okf-validate
|
|
3
|
+
description: Validate OKF paths, frontmatter, required files, concept links, and citation structure deterministically. Use before consuming or distributing a bundle, while checking factual quality separately.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Validate an OKF bundle
|
|
7
|
+
|
|
8
|
+
Validation protects the file contract an agent depends on: required paths, unique files, root metadata, Markdown content, concept frontmatter, links, and citation sections. It does not browse cited sources or determine whether the knowledge is true, current, owned, complete, or safe.
|
|
9
|
+
|
|
10
|
+
## Run it
|
|
11
|
+
|
|
12
|
+
For MCP, call `seo_list_reports` with category `crawl` only if discovery is needed. Call `seo_describe_report` with `{ "id": "okf-validate" }`, then call `seo_run_report` with:
|
|
13
|
+
|
|
14
|
+
```json
|
|
15
|
+
{
|
|
16
|
+
"id": "okf-validate",
|
|
17
|
+
"params": {
|
|
18
|
+
"files": [
|
|
19
|
+
{ "path": "index.md", "content": "---\nokf: \"0.1\"\ntype: \"index\"\n---\n# Example" },
|
|
20
|
+
{ "path": "log.md", "content": "# Log" },
|
|
21
|
+
{ "path": "concepts/index.md", "content": "# Concepts" },
|
|
22
|
+
{ "path": "inventory/pages.md", "content": "---\ntype: \"inventory\"\n---\n# Pages\n\n# Citations" },
|
|
23
|
+
{ "path": "graph/links.md", "content": "---\ntype: \"graph\"\n---\n# Links\n\n# Citations" },
|
|
24
|
+
{ "path": "caveats.md", "content": "---\ntype: \"caveats\"\n---\n# Caveats\n\n# Citations" }
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Check `isError`, then consume `structuredContent`.
|
|
31
|
+
|
|
32
|
+
The CLI uses the same strict schema. This minimal six-file bundle is structurally valid:
|
|
33
|
+
|
|
34
|
+
```sh
|
|
35
|
+
seo reports describe okf-validate --json
|
|
36
|
+
seo reports run okf-validate --params '{"files":[{"path":"index.md","content":"---\nokf: \"0.1\"\ntype: \"index\"\n---\n# Example"},{"path":"log.md","content":"# Log"},{"path":"concepts/index.md","content":"# Concepts"},{"path":"inventory/pages.md","content":"---\ntype: \"inventory\"\n---\n# Pages\n\n# Citations"},{"path":"graph/links.md","content":"---\ntype: \"graph\"\n---\n# Links\n\n# Citations"},{"path":"caveats.md","content":"---\ntype: \"caveats\"\n---\n# Caveats\n\n# Citations"}]}' --json
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## Resolve findings
|
|
40
|
+
|
|
41
|
+
Read `validation.valid`, file and concept counts, then every issue's level, path, and message. Errors invalidate the supported contract and should be fixed file by file. Warnings identify weaker portability or provenance, such as missing citation sections, and still require review even when `valid` is true. Use `explanation.nextActions` as ordering guidance, not as evidence that automated edits are safe.
|
|
42
|
+
|
|
43
|
+
Preserve the original bundle while correcting a copy, rerun validation, and compare issue sets deterministically. After structural success, separately verify cited URLs, claims, dates, access restrictions, publisher intent, and the crawl snapshot recorded by the bundle. Never report `valid: true` as "fact checked."
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: page-opportunities
|
|
3
|
+
description: Review one URL against retained GSC demand, peer CTR evidence, and live page content; use when an agent needs query-level opportunities with verification and source limits intact.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Page opportunities
|
|
7
|
+
|
|
8
|
+
Use this report to investigate how one page performs for the query/page rows retained by Search Console. It compares the target rows with a bounded site-wide peer sample and can fetch the live page to distinguish covered, unverified, technical, framing, ranking, and possible content-gap observations. It does not expose anonymized queries, explain ranking causes, or prove that a benchmark shortfall is recoverable traffic.
|
|
9
|
+
|
|
10
|
+
## Run the report
|
|
11
|
+
|
|
12
|
+
Use the compact MCP flow:
|
|
13
|
+
|
|
14
|
+
1. Call `seo_list_reports` with `{"category":"ai-search"}`.
|
|
15
|
+
2. Call `seo_describe_report` with `{"id":"page-opportunities"}`.
|
|
16
|
+
3. Call `seo_run_report` with `{"id":"page-opportunities","params":{"site":"sc-domain:example.com","url":"https://example.com/pricing","days":90,"limit":15,"minImpressions":40,"verifyContent":true}}`.
|
|
17
|
+
|
|
18
|
+
The CLI shares that schema and implementation:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
seo reports describe page-opportunities --json
|
|
22
|
+
seo reports run page-opportunities --params '{"site":"sc-domain:example.com","url":"https://example.com/pricing","days":90,"limit":15,"minImpressions":40,"verifyContent":true}' --json
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
`site` and `url` are required. Use `includeBrand:true` only when branded demand belongs in the decision. `verifyContent:false` saves a fetch but makes content-specific conclusions unavailable.
|
|
26
|
+
|
|
27
|
+
## Interpret and act
|
|
28
|
+
|
|
29
|
+
Check `dataStatus`, `range`, `source.targetRowsFetched`, `selection`, and `benchmark` first. A `benchmark.possiblyTruncated` value of true means the peer sample reached its cap. Read `verification.status` and `reason`; only `verified` results support live-page coverage observations. For each `item`, retain the query metrics, opportunity type, benchmark evidence, verification evidence, and recommendation together. `estimatedCtrClickShortfall` is a directional calculation, not a click forecast, and `summary.opportunities` is a review queue rather than a defect count.
|
|
30
|
+
|
|
31
|
+
Safe actions include inspecting the live SERP, resolving status/indexability contradictions, testing title or description framing when the page already answers the query, strengthening a relevant answer, and adding a contextual internal link. Do not rewrite a page from query wording alone, infer an all-clear from partial data, or merge and delete pages without separate intent, canonical, and internal-link evidence.
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance
|
|
3
|
+
description: Audit and interpret one URL's Lighthouse lab performance and device-specific CrUX field Core Web Vitals with the local seo CLI or MCP server. Use when an agent needs to investigate LCP, INP, CLS, TBT, page-speed diagnostics, mobile-versus-desktop evidence, or performance remediation without confusing lab, field, and fallback measurements.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Performance
|
|
7
|
+
|
|
8
|
+
Run report id `performance-audit` through `seo_run_report` for structured agent
|
|
9
|
+
output. Call `seo_describe_report` first when its parameters are not already
|
|
10
|
+
known. Pass `url`, choose `strategy` as `mobile` or `desktop`, and use
|
|
11
|
+
`refresh: true` only when a fresh measurement is required.
|
|
12
|
+
|
|
13
|
+
CLI equivalents:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
seo perf audit --url https://example.com/page --json
|
|
17
|
+
seo perf audit --url https://example.com/page --strategy desktop --refresh --json
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
Set `SEO_CRUX_API_KEY` to request Chrome UX Report field data. The packaged
|
|
21
|
+
Lighthouse runtime needs a compatible local Chrome installation.
|
|
22
|
+
|
|
23
|
+
## Interpret the report
|
|
24
|
+
|
|
25
|
+
1. Check `dataStatus`, `labDataStatus`, `fieldDataStatus`, and `caveats` first.
|
|
26
|
+
2. Treat CrUX as rolling, device-specific field evidence. Check whether its
|
|
27
|
+
`scope` is the exact URL or the origin and quote the `collectionPeriod`.
|
|
28
|
+
3. Treat Lighthouse as one controlled navigation lab run. Use its compact
|
|
29
|
+
`labInsights` and metric evidence for diagnosis, not as field experience.
|
|
30
|
+
4. Treat Lighthouse TBT as a lab responsiveness diagnostic. Never rename it
|
|
31
|
+
INP. Field INP comes from CrUX.
|
|
32
|
+
5. Use the field p75 thresholds encoded by the report: LCP good at 2,500ms or
|
|
33
|
+
less, INP good at 200ms or less, and CLS good at 0.1 or less. All three must
|
|
34
|
+
be available and good for the field assessment to be good.
|
|
35
|
+
6. Prefer field findings when field and lab disagree. Explain that their
|
|
36
|
+
populations and measurement conditions differ.
|
|
37
|
+
7. Keep recommendations tied to returned metrics or insights. Do not infer
|
|
38
|
+
sitewide performance from one URL, device, or run.
|
|
39
|
+
|
|
40
|
+
## Guardrails
|
|
41
|
+
|
|
42
|
+
- `source: fetch-fallback` is unscored transport evidence. Its duration is the
|
|
43
|
+
complete local fetch workflow, not TTFB, Lighthouse, or Core Web Vitals.
|
|
44
|
+
- Stop performance conclusions when fallback evidence is blocked or non-2xx.
|
|
45
|
+
- `unavailable_no_coverage` means CrUX lacks enough data; it does not mean the
|
|
46
|
+
page passed or failed Core Web Vitals.
|
|
47
|
+
- `request_failed` is an operational provider problem, not a page finding.
|
|
48
|
+
- Missing field metrics make the Core Web Vitals assessment incomplete.
|
|
49
|
+
- Do not request or paste raw Lighthouse output unless a human explicitly
|
|
50
|
+
needs the underlying artifact; compact output is the stable agent contract.
|