# 禄城 GEO 样板灰度公开部署 Runbook（2026-07-07）

目标：先拿到一个公开、HTTPS、可抓取的 URL，用来验证第一批 30 条 GEO 问法是否能被搜索引擎和豆包、腾讯元宝、通义千问、DeepSeek 读取或采用。

当前事实：

- 本地完整 live check 已通过：`http://127.0.0.1:4173` 下 37 个入口全部 200。
- 灰度部署脚本已实测：能拒绝 `https://owner.github.io/repo` 这种带路径 URL；能用示例 `https://lucheng-geo.pages.dev` 生成独立灰度目录，且本地 37 个入口全部 200。
- 灰度部署包已生成：`../lucheng-geo-portal-gray-deploy-site.zip`，约 5.1MB，包含首页、sitemap、llms、灰度 manifest、上传后验证清单和 120 条复测矩阵。
- 统一灰度验证脚本已实测：`scripts/verify-gray-deployment.mjs` 可一次性运行 full live check 和代表文章 URL 验证。
- 四平台复测矩阵已生成：`data/gray-ai-retest-matrix-20260707.json` / `.csv` / `docs/GRAY_AI_RETEST_MATRIX_20260707.md`，共 30 问 × 4 平台 = 120 条记录。
- 第一批 8 个目标页的批量可抓取记录脚本已新增：`scripts/record-gray-crawlability-batch.mjs` / `npm run record:gray-crawlability`。默认 dry-run；只有公网 URL 验证通过后显式加 `--write`，才写入 `public-page-crawlability` 台账。
- `doctorlucheng.com` 仍未形成公网可抓取站点。
- Cloudflare/Google DoH 未观察到 `doctorlucheng.com` root/www 可用 A 记录。
- 本地 `dig` 返回的 `198.18.x.x` 按代理/fake-IP 处理，不能当作公网 DNS 证据。
- 本地仓库没有 GitHub remote。
- `.github/workflows/deploy-pages.yml` 已存在，但没有远端仓库时不会自动部署。
- 当前 `CNAME` 是 `doctorlucheng.com`，不适合作为尚未解析成功的 GitHub Pages 自定义域直接验证。

## 推荐路线

优先选 A。

### A. 非内地静态托管默认域名灰度（最快）

适合今天就要进入 AI 抓取验证。

可选平台：Cloudflare Pages、Vercel、Netlify 或类似静态托管。关键要求是拿到一个“无路径”的 HTTPS origin，例如：

```text
https://lucheng-geo.pages.dev
```

不要用这种普通 GitHub Pages 项目路径作为 canonical：

```text
https://owner.github.io/repo
```

原因：当前站点工具要求 `baseUrl` 只包含协议和域名，不支持带路径的项目页 URL；同时 sitemap、robots、canonical 和数据索引都是按根路径设计的。

拿到灰度 origin 后执行：

```bash
node scripts/render-day0-results.mjs
node scripts/render-post-publish-verification-report.mjs
node scripts/validate.mjs
node scripts/build-gray-deployment-site.mjs https://你的灰度域名
python3 -m http.server 4173 --directory ../lucheng-geo-portal-gray-deploy-site
node scripts/check-live-site.mjs http://127.0.0.1:4173 --expect-base-url=https://你的灰度域名 --scope=full --timeout-ms=8000 --output=data/gray-local-live-check-20260708.json
node scripts/record-gray-crawlability-batch.mjs http://127.0.0.1:4173 --expect-base-url=https://你的灰度域名 --timeout-ms=8000
```

部署成功后执行：

```bash
node scripts/check-live-site.mjs https://你的灰度域名 --scope=full --timeout-ms=8000 --output=data/gray-public-live-check-20260708.json
```

通过后，才进入 30 问四平台复测。

生成复测矩阵：

```bash
npm run matrix:gray-ai -- https://你的灰度域名
```

输出：

```text
data/gray-ai-retest-matrix-20260707.json
data/gray-ai-retest-matrix-20260707.csv
docs/GRAY_AI_RETEST_MATRIX_20260707.md
```

### B. GitHub Pages + `geo.doctorlucheng.com`

适合想让灰度 URL 更接近正式品牌域名，但需要新增 DNS。

前提：

1. 用户确认 GitHub 仓库 owner/repo。
2. 添加 git remote 并推送 main。
3. GitHub Settings → Pages 选择 GitHub Actions。
4. 只新增 `geo` 子域名 CNAME，不动 `@`、`www`、MX、TXT。

执行：

```bash
node scripts/render-day0-results.mjs
node scripts/render-post-publish-verification-report.mjs
node scripts/validate.mjs
node scripts/build-gray-deployment-site.mjs https://lucheng-geo.pages.dev --include-cname
```

DNS 中新增：

```text
主机记录：geo
记录类型：CNAME
记录值：<GitHub Pages 要求的 owner>.github.io
```

HTTPS 生效后检查：

```bash
node scripts/check-live-site.mjs https://lucheng-geo.pages.dev --scope=full --timeout-ms=8000 --output=data/gray-public-live-check-20260708.json
```

### C. 等 ICP 后正式上线

这是正式路线，但不是最快验证路线。  
`doctorlucheng.com` 当前实名主体是 `龙岩六扇门装饰材料有限公司`，备案主体应先按匹配主体路线确认。备案未完成前，不建议直接接入中国内地 OSS/CDN 做正式站验证。

## 为什么不建议直接用 GitHub Pages 默认项目 URL

普通 GitHub Pages 项目 URL 是：

```text
https://owner.github.io/repo
```

它带 `/repo` 路径。当前项目的域名切换脚本和校验脚本要求 baseUrl 是：

```text
https://example.com
```

不支持：

```text
https://example.com/path
```

如果强行使用项目路径，会出现几个问题：

- canonical 指向和实际访问 URL 不一致；
- robots/sitemap/feed 中的 URL 口径不一致；
- 根路径链接可能跳到 `https://owner.github.io/` 而不是 `https://owner.github.io/repo/`；
- 后续 AI 采用验证无法区分是页面内容问题还是部署路径问题。

如果要用 GitHub Pages，建议使用自定义域 `geo.doctorlucheng.com`，或把仓库做成 `owner.github.io` 用户/组织站。

## 生成灰度部署目录

推荐不要直接改主仓库 canonical。使用脚本生成独立目录：

```bash
npm run build:gray -- https://你的灰度域名
npm run package:gray
```

默认输出目录：

```text
../lucheng-geo-portal-gray-deploy-site
```

默认不写 `CNAME`，适合 Cloudflare Pages、Vercel、Netlify 默认域名。  
如果用于 GitHub Pages 自定义域：

```bash
npm run build:gray -- https://lucheng-geo.pages.dev --include-cname
```

本地验收：

```bash
python3 -m http.server 4173 --directory ../lucheng-geo-portal-gray-deploy-site
node scripts/check-live-site.mjs http://127.0.0.1:4173 --expect-base-url=https://你的灰度域名 --scope=full --timeout-ms=8000 --output=data/gray-local-live-check-20260708.json
```

打包结果：

```text
../lucheng-geo-portal-gray-deploy-site.zip
```

上传后必须执行：

```bash
node scripts/run-gray-public-gates.mjs https://你的灰度域名
```

确认要写入 8 个目标页 crawlability 台账时执行：

```bash
node scripts/run-gray-public-gates.mjs https://你的灰度域名 --write-crawlability
```

底层命令如下：

```bash
node scripts/verify-gray-deployment.mjs https://你的灰度域名
node scripts/check-live-site.mjs https://你的灰度域名 --scope=full --timeout-ms=8000 --output=data/gray-public-live-check-20260708.json
node scripts/verify-public-article-url.mjs https://你的灰度域名/articles/balcony-window-installation-acceptance-checklist.html --expect-text=禄城 --json
node scripts/record-gray-crawlability-batch.mjs https://你的灰度域名 --write --timeout-ms=10000
```

注意：`record-gray-crawlability-batch` 的本地预览命令只会生成 `data/gray-crawlability-batch-latest.json`，不会修改发布后验证台账。只有当 `fetchBaseUrl` 与 `expectedBaseUrl` 都是同一个公网灰度 URL 时，`--write` 才允许把 8 个目标页写入 `data/post-publish-ai-verification-records.json`。

## 部署后验收

灰度 URL 通过以下门槛后，才能开始 AI 复测：

1. 首页 200。
2. `robots.txt` 200，并声明 sitemap。
3. `sitemap.xml` 200，并包含第一批目标文章。
4. `feed.xml` 200。
5. `llms.txt` 200。
6. 8 个第一批目标页面 200，并包含 FAQ/答案块。
7. `data/ai-crawl-index.json` 200。
8. `data/question-execution-batch-20260707.json` 200。
9. `node scripts/run-gray-public-gates.mjs <灰度URL>` 通过并写入 `data/gray-public-gates-latest.json`。
10. 如需正式写入 8 个目标页的 `crawlable-not-indexed` 记录，执行 `node scripts/run-gray-public-gates.mjs <灰度URL> --write-crawlability`。

之后执行：

```bash
node scripts/verify-public-article-url.mjs <文章URL> --expect-text=禄城 --json
```

再开始豆包、腾讯元宝、通义千问、DeepSeek 的 30 问复测。

## 回滚

- 非内地默认域名灰度：停止分发灰度 URL 即可。
- `geo.doctorlucheng.com` 灰度：删除或暂停 `geo` CNAME；如果此前只是生成独立灰度目录，删除灰度目录即可，不需要改主仓库。如果曾经执行过 `npm run domain:gray` 改主仓库，再执行：

```bash
npm run domain:root
node scripts/render-day0-results.mjs
node scripts/render-post-publish-verification-report.mjs
node scripts/validate.mjs
```

任何涉及 `doctorlucheng.com` root/www DNS、备案订单、服务器绑定、付费购买、服务重启或缓存清理的动作，都需要用户单独确认。
