# 07 Technical SEO / GEO / AEO Recheck — Subnautica2Maps

- task_id: `t_492bea0f`
- owner: 墨引
- date: 2026-05-20
- project_slug: `subnautica2maps`
- selected_keyword: `subnautica 2 map`
- target_market: US/en
- tenant: `site-rerun-subnautica2maps-20260520-clean`
- production_url: `https://subnautica2maps.com`
- frontend_commit: `a25cd5953d5bb9c10f0870044e76f9abdb888aa0`
- frontend_branch: `clean-rerun-public-reference-05a`
- output_artifact: `reports/site-pipeline/site-rerun-subnautica2maps-20260520-clean/subnautica2maps/07-technical-seo.md`

## 0. Verdict

SEO verdict: `NO_GO_FOR_GSC_SUBMISSION`.

Core map experience is live and usable, public-reference data/analytics endpoint are materially better than previous failed runs, but current production still fails the technical SEO/GEO/AEO gate.

P0 blockers:

1. `sitemap.xml` and `robots.txt` point to `https://subnautica2maps.pages.dev`, not `https://subnautica2maps.com`.
2. Sitemap includes URLs that currently return `noindex`/Next error shell on production: `/resources/copper/`, `/resources/silver/`, `/resources/sulfur/`, `/biomes/shallows/`, `/biomes/graveyard/`.
3. Canonicals for indexable pages also point to `subnautica2maps.pages.dev`; homepage has no canonical.
4. Structured data is missing: no `BreadcrumbList`, `FAQPage`, `WebApplication`, `CreativeWork`, `ItemList`, or `HowTo` JSON-LD found in rendered HTML.
5. `/map/` renders two H1s after marker/detail state is present: page H1 + selected marker detail H1. Detail title should be H2/H3 or isolated in a separate route/modal semantics.
6. No `og:url`; OG image URLs still use `subnautica2maps.pages.dev`.
7. Production response lacks HSTS in observed headers; CF SSL/Always HTTPS/Bot/Crawler/cache settings remain not verified in this task.
8. Footer contact uses `hello@subnautica2maps.pages.dev` and `support@subnautica2maps.pages.dev`; production-domain aliases are not verified.

Passes / positive evidence:

- `/`, `/map/`, `/sitemap.xml`, `/robots.txt`, legal pages return 200.
- Homepage has 1 H1, 3 H2, 3 H3, 3,147 rendered words, title 59 chars, description 154 chars.
- `/map/` has search/filter/detail UI, source/confidence labels, fan-made disclaimer, local progress controls, route fields.
- Browser test: search `silver` filtered to silver/resource/location matches; Resources filter narrowed to 5 silver resource markers.
- API ingestion passed for required P0 events: `pageview`, `hero_cta_click`, `tool_start`, `tool_result`, `pricing_cta_click`, `map_search`, `marker_open`, `filter_apply`, `detail_open`.
- Privacy guardrail passed: POST `/api/events` with raw `x/y/z` returned 400 `disallowed_property`.
- `npm test` passed marker validation, sitemap banned URL check, and banned phrase check.
- Git working tree was clean after test; HEAD matches frontend handoff commit.

## 1. Inputs read

Clean-rerun parent artifacts only:

- Frontend 05A report: `/root/.hermes/reports/site-pipeline/site-rerun-subnautica2maps-20260520-clean/subnautica2maps/05a-public-reference-frontend.md`
- Backend 05B report: `/root/.hermes/kanban/boards/site-factory/workspaces/t_03caa401/reports/site-pipeline/site-rerun-subnautica2maps-20260520-clean/subnautica2maps/05b-backend.md`
- Frontend repo from parent metadata: `/root/projects/subnautica2maps`
- Live production: `https://subnautica2maps.com`

Not read/reused: old PRD, old design, old seed data, old dist from previous tenant, old local path manifest contents, old report outputs outside the clean-rerun parent handoffs.

## 2. Live URL audit

| URL | HTTP | Index status | Canonical | Key findings |
|---|---:|---|---|---|
| `/` | 200 | indexable by absence of noindex | missing | Good content depth; no JSON-LD; no `og:url`; OG image points pages.dev |
| `/map/` | 200 | `index, follow` | `https://subnautica2maps.pages.dev/map/` | Functional map; two H1s; no JSON-LD; canonical wrong host |
| `/sitemap.xml` | 200 | n/a | n/a | All locs use `subnautica2maps.pages.dev`; includes noindex/error pages |
| `/robots.txt` | 200 | n/a | n/a | Sitemap line points `https://subnautica2maps.pages.dev/sitemap.xml` |
| `/resources/silver/` | 200 | `noindex` | missing | In sitemap but rendered as Next error/noindex shell; no H1 |
| `/resources/copper/` | 200 | `noindex` | missing | In sitemap but rendered as Next error/noindex shell; no H1 |
| `/resources/sulfur/` | 200 | `noindex` | missing | In sitemap but rendered as Next error/noindex shell; no H1 |
| `/biomes/shallows/` | 200 | `noindex` | missing | In sitemap but rendered as Next error/noindex shell; no H1 |
| `/biomes/graveyard/` | 200 | `noindex` | missing | In sitemap but rendered as Next error/noindex shell; no H1 |
| `/guides/how-to-find-coordinates/` | 200 | `index, follow` | pages.dev URL | Title 78 chars, description 166 chars; no JSON-LD |
| `/guides/does-subnautica-2-have-a-map/` | 200 | `index, follow` | pages.dev URL | Has answer-first text; title 68 chars; no JSON-LD |
| `/privacy/` | 200 | `index, follow` | pages.dev URL | Legal content present; no JSON-LD |
| `/terms/` | 200 | `index, follow` | pages.dev URL | Legal content present; no JSON-LD |
| `/legal/` | 200 | `index, follow` | pages.dev URL | Legal/DMCA content present; no JSON-LD |
| `/contact/` | 200 | `index, follow` | pages.dev URL | Contact content present; emails not production-domain verified |
| `/cookie-policy/` | 200 | `index, follow` | pages.dev URL | Present; likely unnecessary unless non-essential trackers added |

Evidence commands/tools:

- `execute_code`: fetched production URLs and parsed title/meta/canonical/H1-H3/img alt/JSON-LD/robots/noindex.
- `browser_navigate`: opened `/map/` and confirmed UI/search/filter/detail controls in rendered browser.
- `browser_type` + `browser_press`: searched `silver`.
- `browser_click`: applied `Resources` filter.
- `terminal`: `npm test` and git status in `/root/projects/subnautica2maps`.

## 3. Sitemap / robots / canonical gate

Status: `FAIL`.

Observed production sitemap locs:

```text
https://subnautica2maps.pages.dev/
https://subnautica2maps.pages.dev/map/
https://subnautica2maps.pages.dev/resources/copper/
https://subnautica2maps.pages.dev/resources/silver/
https://subnautica2maps.pages.dev/resources/sulfur/
https://subnautica2maps.pages.dev/biomes/shallows/
https://subnautica2maps.pages.dev/biomes/graveyard/
https://subnautica2maps.pages.dev/guides/how-to-find-coordinates/
https://subnautica2maps.pages.dev/guides/does-subnautica-2-have-a-map/
https://subnautica2maps.pages.dev/privacy/
https://subnautica2maps.pages.dev/terms/
https://subnautica2maps.pages.dev/legal/
https://subnautica2maps.pages.dev/contact/
https://subnautica2maps.pages.dev/cookie-policy/
```

Observed source:

- `src/app/sitemap.ts`: `const base='https://subnautica2maps.pages.dev';`
- `src/app/robots.ts`: `sitemap:'https://subnautica2maps.pages.dev/sitemap.xml'`
- `src/app/layout.tsx`: `metadataBase: new URL('https://subnautica2maps.pages.dev')`

Required fix:

- Set canonical production base to `https://subnautica2maps.com`.
- Rebuild sitemap/robots/canonicals/OG URLs against production domain.
- Remove any URL from sitemap unless the final live page is indexable, self-canonical, has unique H1/content, and is not an error shell.
- Do not submit sitemap to GSC/Bing until this passes.

## 4. Indexability gate

Status: `FAIL`.

Hard rule from 05B: sitemap cannot include noindex/thin/query/unverified pages.

Current violation:

- `/resources/copper/`, `/resources/silver/`, `/resources/sulfur/`, `/biomes/shallows/`, `/biomes/graveyard/` are present in sitemap but production HTML has `<meta name="robots" content="noindex"/>`, no H1, and generic fallback title.
- Static output confirms the resource page is an error/noindex shell: `/root/projects/subnautica2maps/out/resources/silver/index.html` begins `<html id="__next_error__">` and includes `meta name="robots" content="noindex"`.

Required fix options:

Option A — fastest safe path:

- Remove resource and biome URLs from sitemap.
- Keep them accessible only if they are not intended for index yet.
- Keep sitemap to `/`, `/map/`, guide/legal pages that pass self-canonical checks.

Option B — indexable content path:

- Fix static generation for resource/biome routes.
- Each resource/biome page must have unique Title/Description/H1, self-canonical to production domain, no noindex, source/confidence/last-updated blocks, ≥800 words for formal SEO gate or documented exception, H2 ≥3, and relevant JSON-LD.
- Only then include in sitemap.

## 5. Metadata / title / snippet gate

Status: `CONDITIONAL_FAIL`.

Findings:

- Homepage title: 59 chars, acceptable.
- Homepage meta description: 154 chars, acceptable.
- `/map/` title: 78 chars, too long for 40–60 char default gate.
- `/guides/how-to-find-coordinates/` title: 78 chars and description 166 chars; both too long.
- `/guides/does-subnautica-2-have-a-map/` title: 68 chars; slightly long.
- No `og:url` found on audited pages.
- OG/Twitter images point to `https://subnautica2maps.pages.dev/assets/og-image.png`, not production domain.
- Homepage has no canonical; many subpages canonicalize to pages.dev.

Required fix:

- Add explicit `alternates.canonical` for homepage and every indexable page.
- Add `openGraph.url` and production-domain OG image URLs.
- Shorten long titles/descriptions where possible.

## 6. Header / Core Web / crawlability gate

Status: `CONDITIONAL_FAIL`.

Pass:

- Core resources are not blocked by robots.
- `X-Content-Type-Options`, `Referrer-Policy`, `Content-Security-Policy`, `Permissions-Policy` observed.
- CSP avoids third-party script bloat except Google Fonts and inline script allowance.

Fail / unverified:

- `Strict-Transport-Security` was not observed in production response headers during audit.
- CF settings are not verified: SSL Full Strict, Always HTTPS, Bot Fight/equivalent, Crawler Hints, Browser Cache TTL, `/api` rate limit, static asset cache.
- Header `content-type`/`cache-control` was not surfaced by the Python header dict in the audit output; should be checked with raw `curl -I` in QA/launch.

Required fix:

- QA/launch must provide CF evidence for required settings before public submission.
- Add or verify HSTS at CF/header layer after SSL Full Strict is confirmed.

## 7. Structured data / GEO / AEO gate

Status: `FAIL`.

Rendered HTML had `jsonld_count: 0` across audited pages.

Required minimum:

- Sitewide or homepage: `WebSite` + `WebApplication` for the map tool.
- Breadcrumbs: `BreadcrumbList` on indexable non-home pages.
- Guide pages: `Article`/`CreativeWork` + `FAQPage` where FAQ content exists; `HowTo` for `/guides/how-to-find-coordinates/` if steps are explicit.
- Map/resource lists: `ItemList` for source-backed marker/resource lists after static route is fixed.
- Legal/contact: `ContactPage` or `Organization` contact point if used.

AEO content status:

- `/guides/does-subnautica-2-have-a-map/` has answer-first language and passes the intent direction.
- Homepage has FAQ text, but no FAQPage schema.
- `/map/` is useful but not answer-first enough for AI citation; add a 40–70 word summary block near top: what the map covers, data caveat, how to use search/filter/route.
- Add explicit citation blocks: `Sources`, `Last updated`, `Confidence`, `Public-reference data`, `Fan-made/no affiliation`.

## 8. Game/IP/legal SEO boundary

Status: `CONDITIONAL_PASS`.

Pass:

- Fan-made / public-reference / not exhaustive language is visible.
- Marker detail panel shows source/confidence style information.
- No official/endorsed wording found by validation script.
- No copied map tiles or third-party gameplay images observed in rendered audit.
- Legal/privacy/terms/contact/cookie pages exist.

Risks:

- Footer contact uses pages.dev email aliases, not production domain aliases.
- `hello@subnautica2maps.com` / `support@subnautica2maps.com` are not verified.
- DMCA/copyright path should be explicit and production-domain based before launch/GSC.

## 9. Interaction baseline

Status: `CONDITIONAL_PASS_FOR_USER_TASKS`, `FAIL_FOR_SEO_GATE`.

Observed browser tasks:

- Open `/map/`: pass.
- Search `silver`: pass; returned silver resources plus related locations.
- Filter `Resources`: pass; narrowed visible results to 5 silver resources.
- Marker/detail panel visible: pass.
- Source/confidence visible: pass.
- Route coordinate inputs visible: pass.
- Local progress buttons visible: pass.

Issues:

- Detail panel heading uses H1, creating a duplicate H1 on `/map/`.
- Route calculation click did not produce an obvious visible route result in the accessibility snapshot after entering `0,0,0`; needs QA follow-up.
- `pricing_cta_click` endpoint accepts ingestion, but no visible pricing/support CTA was verified in browser snapshot.

## 10. Analytics event gate

Status: `PASS_ENDPOINT_INGESTION`, `CONDITIONAL_FOR_UI_TRIGGER_PROOF`.

Direct endpoint evidence from production `POST /api/events`:

| Event | Result |
|---|---|
| `pageview` | 200 `ok:true`, `ingested:true` |
| `hero_cta_click` | 200 `ok:true`, `ingested:true` |
| `tool_start` | 200 `ok:true`, `ingested:true` |
| `tool_result` | 200 `ok:true`, `ingested:true` |
| `pricing_cta_click` | 200 `ok:true`, `ingested:true` |
| `map_search` | 200 `ok:true`, `ingested:true` |
| `marker_open` | 200 `ok:true`, `ingested:true` |
| `filter_apply` | 200 `ok:true`, `ingested:true` |
| `detail_open` | 200 `ok:true`, `ingested:true` |

Privacy check:

- Payload with raw `x/y/z` returned 400 `{"ok":false,"error":"disallowed_property","property":"x"}`.

Remaining QA requirement:

- Endpoint acceptance is not the same as UI-trigger proof. QA should still verify browser UI actually emits each event and that backend/dashboard/API stores the events.

## 11. Build/test/git verification

Command run in `/root/projects/subnautica2maps`:

```bash
npm test
```

Result:

```json
{
  "ok": true,
  "marker_count": 63,
  "sha256": "c99f73d23e61d0b96a01c2c4b3d7682d99c7314823a37f608c1e7c9a83bc66c2",
  "sitemap_checked": true,
  "no_banned_claims": true
}
```

Git verification:

```text
git rev-parse HEAD = a25cd5953d5bb9c10f0870044e76f9abdb888aa0
branch = clean-rerun-public-reference-05a
git status --short = clean
```

Note: the current validation script is too weak. It only bans `/markers/`, `/search`, and query URLs in sitemap; it does not catch wrong host, sitemap/noindex conflicts, missing canonical, missing JSON-LD, duplicate H1, or error-shell sitemap pages. Add SEO audit script before next deploy.

## 12. Required remediation before downstream acceptance

Assign to 墨界/frontend:

1. Replace all pages.dev SEO bases with production base `https://subnautica2maps.com`:
   - `metadataBase`
   - `sitemap.ts`
   - `robots.ts`
   - canonical URLs
   - OG/Twitter image URLs
   - footer production-domain emails if aliases are verified, otherwise mark launch blocker visibly.
2. Fix sitemap allowlist:
   - Remove resource/biome URLs now, or fix their static rendering and noindex state.
   - Never include `noindex`, Next error shell, query, marker detail, local state, or thin pages.
3. Add JSON-LD:
   - `WebSite` + `WebApplication` for homepage/map.
   - `BreadcrumbList` on all non-home indexable pages.
   - `FAQPage` for FAQ sections.
   - `HowTo` for coordinate guide if step structure is retained.
   - `ItemList` for resource/biome pages only after route/content is valid.
4. Fix `/map/` heading hierarchy:
   - Keep one page H1.
   - Marker/detail title should be H2/H3 or ARIA-labeled panel heading, not another H1.
5. Add/verify `og:url` on every indexable page.
6. Add a hard SEO audit script and make build/deploy fail on:
   - sitemap host != production host
   - sitemap URL has noindex or non-self canonical
   - page has missing/duplicate H1
   - missing canonical
   - missing title/description
   - missing OG/Twitter required fields
   - missing required JSON-LD
   - sitemap page rendered as Next error shell
7. Re-run build/test/deploy and provide same-commit evidence.

Assign to QA/launch after frontend fix:

- Verify CF settings evidence.
- Verify production-domain emails.
- Verify HSTS/caching headers with raw `curl -I`.
- Verify UI-triggered analytics ingestion for every P0 event.
- Only then proceed to GSC/Bing sitemap submission.

## 13. Acceptance checklist

| Check | Status | Evidence |
|---|---|---|
| Kanban source of truth used | PASS | `kanban_show(t_492bea0f)` |
| START sent to Telegram | PASS | message sent to `telegram:-1003750190535:5318` |
| Clean-rerun parent frontend read | PASS | 05A frontend report path |
| Clean-rerun parent backend read | PASS | 05B backend report path |
| No old PRD/design/seed/dist/repo reused | PASS | Only clean parent handoff + current repo/live production inspected |
| site_type carried through | PASS | Game/fan-made interactive map/resource guide site |
| SERP/competitor interaction baseline carried through | PASS | map/search/filter/detail/route/source/confidence audited |
| core_user_tasks carried through | PASS | browser search/filter/detail/route controls checked |
| competitive_minimum carried through | CONDITIONAL | functional map present; SEO/schema/index hygiene below minimum |
| asset/content inventory carried through | PASS | 63 marker manifest, source URLs, public-reference posture checked |
| index/noindex+sitemap policy carried through | FAIL | sitemap includes noindex/error resource/biome pages; wrong host |
| analytics/event plan carried through | PASS/CONDITIONAL | endpoint ingestion passed; UI trigger proof still QA item |
| legal/policy boundary carried through | CONDITIONAL | fan-made visible; production-domain emails not verified |
| GTM/review mouth carried through | PASS | block GSC/Bing until remediation complete |
| Domain/CF P0 checked | CONDITIONAL_FAIL | live headers checked; CF settings/email not verified |
| SEO audit script present | FAIL | current `npm test` does not catch critical SEO issues |
| skill_contract_check included | PASS | §14 |
| Output written under required path | PASS | this file |

## 14. skill_contract_check

| 合同项 | 必需输入 | 必需产出 | 硬约束 | 验收项 | Evidence |
|---|---|---|---|---|---|
| Kanban source of truth | task `t_492bea0f`, parent metadata | 07 SEO report + Kanban metadata | Telegram only visibility; Kanban complete authoritative | START sent, DONE before complete | `kanban_show`; Telegram message id 5751 |
| Clean rerun | `clean_rerun=true`, new tenant, parent 05A/05B artifacts | Fresh technical SEO/GEO/AEO recheck under clean output path | Do not reuse old PRD/design/seed/dist/repo | Inputs list clean parent paths only | §1 |
| Bound skill: site-seo-review | frontend/backend delivery, live production | SEO verdict, technical checks, AEO/GEO/schema checks, index policy | Missing critical input blocks; no invented data | Verdict and blockers stated | §§0-13 |
| Technical SEO | live pages, repo metadata, sitemap, robots | Title/meta/canonical/noindex/H1/header findings | Production must be crawlable/indexable | sitemap/canonical/noindex audited | §§2-6 |
| GEO/AEO | rendered content and schema | JSON-LD/AEO/AI citation assessment | AI citation requires answer-first + source/confidence blocks | schema absence identified | §7 |
| Game/IP SEO | public-reference data and legal pages | fan-made/no-affiliation/source/confidence assessment | No official/endorsed/copying claims | conditional pass and email blocker | §8 |
| Interaction baseline | browser-rendered `/map/` | search/filter/detail/route control evidence | Tool pages must satisfy real tasks, not just keywords | silver search + Resources filter verified | §9 |
| Analytics | `/api/events` production endpoint | ingestion + privacy guardrail results | Real ingestion proof required; raw coords rejected | required event posts 200; raw x/y/z 400 | §10 |
| Build/test verification | repo from parent metadata | `npm test`, git status, commit check | Review cannot mark unverified build state as pass | test passed; git clean | §11 |
| Remediation handoff | failed gates | next assignee input | Do not submit sitemap before fixes | explicit frontend/QA fix list | §12 |

## 15. Handoff summary

Next assignee input for 墨界/frontend:

- Treat current SEO result as `NO_GO_FOR_GSC_SUBMISSION`.
- Fix production host base, sitemap/robots/canonical/OG URL mismatch.
- Remove noindex/error-shell resource and biome URLs from sitemap or fix their static rendering before indexing.
- Add JSON-LD and hard SEO audit script.
- Fix duplicate H1 on `/map/` marker/detail panel.
- Rebuild/test/deploy from same pushed commit and provide deployment evidence.

Next assignee input for 墨测/QA:

- After frontend repair, re-audit sitemap vs noindex/canonical, JSON-LD, heading hierarchy, headers, CF settings, domain emails, and UI-triggered analytics ingestion.

Next assignee input for 墨运/launch:

- Do not submit `https://subnautica2maps.com/sitemap.xml` to GSC/Bing until SEO recheck passes.
