Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

文档站运行手册

状态:已实现

最后复核:2026-08-16

关联:Issue #5、PR #7、Issue #6

长期讨论:GitHub Discussions

当前边界

Issue #5 已建立本地 HTML 与 CI 构建。Issue #6 已把真实 mdBook 文档部署到 Cloudflare Pages 并绑定自定义域名。doc.trading-engine.caas.xyz 已通过未登录 302 验证由 Access 保护,但 pages.dev production/hash 入口仍可公开读取,因此整个站点不是私有站点。

Cloudflare Pages 项目初始化

初始化器只读取 1Password Vault hft-mm-engine-dev 中 Item cloudflare-pages-deploy 的三个初始字段:

  • api_token:仅限目标 Account 的 Cloudflare Pages / Edit。
  • account_id:Cloudflare Account ID。
  • project_name:Pages 项目名。

本地运行固定使用 1Password CLI 2.34.1;版本不一致时初始化器在读取配置前失败关闭。

用户不需要填写 pages_project_id、pages_hostname、production_branch、pages_domains 或 initialized_at。初始化器从 Cloudflare canonical project 自动取得这些非秘密元数据,并只回填上述字段。

默认命令只生成只读计划:

python3 tools/cloudflare_pages_init.py plan

确认计划中的 Account ID、Project Name 和动作后,显式执行:

python3 tools/cloudflare_pages_init.py apply

行为约束:

  • 查询到现有项目时复用,不重复创建。
  • 只有 Cloudflare 明确返回 Project not found 时,apply 才创建项目;权限、网络、限流或未知错误全部失败关闭。
  • 创建前先确认 1Password 不含陈旧项目元数据;写回后重新读取并核对 Cloudflare canonical project 与全部归属字段。
  • HTTP 客户端拒绝所有重定向,避免把 Authorization header 转发给其他 origin。
  • 核心执行入口只接受精确的 plan 或 apply,任何拼写错误都不能触发副作用。
  • 已回填值与 Cloudflare 不一致时报告 drift 并停止,不静默覆盖。
  • 再次执行相同 apply 必须得到 no-op。
  • 输出只包含非秘密项目元数据和动作,不输出 API Token、Authorization header 或完整 1Password Item。
  • 初始化执行阶段的成功和失败均输出带已知非秘密上下文、时间、耗时、动作及错误分类的单行脱敏 JSON,作为可保存的审计记录。
  • 初始化器不绑定域名、不修改 DNS/Access、不轮换 Token,也不部署文档。

2026-08-16 初始化验收

  • plan 确认目标项目不存在,计划动作为 create。
  • apply 创建 Pages 项目 trading-engine,Cloudflare canonical hostname 为 trading-engine-4wl.pages.dev。
  • 初始化器将非秘密项目元数据回填至既有 1Password Item。
  • 紧接着再次运行 plan 与 apply,两者均返回 no-op,没有重复创建或写入。
  • 使用固定 Wrangler 4.123.0 向 production branch main 部署了无敏感内容占位页;deployment hash 为 edcbe490。
  • 未登录探针确认 production 与该 hash deployment 均可直接返回占位正文,说明现有 Access 配置尚未实际覆盖这些入口;真实文档因此没有上传。
  • 用户选定自定义域名 doc.trading-engine.caas.xyz,并已定向写入 1Password 的 custom_hostname 字段;Pages association、DNS 与 TLS 已生效。
  • 一次本地 operator 探针的异常输出暴露了旧 Cloudflare API Token;用户已撤销并轮换,初始化器对新 Token 的只读 plan 返回 no-op。
  • 自定义域名未登录请求返回 Cloudflare Access 登录跳转;trading-engine-4wl.pages.dev 与 hash deployment 仍直接返回 HTTP 200,占位正文可公开读取。
  • Access bootstrap Token 可读取计划,但创建 Application 返回 403 / 1010;没有通过该 Token 创建或修改任何 Access 对象。
  • 用户于 2026-08-16 明确授权跳过剩余 pages.dev Access 权限问题并公开部署真实文档。该决定使 pages.dev 成为已知公开旁路;noindex 等响应头不是访问控制。

2026-08-16 真实文档部署验收

  • 使用固定 Wrangler 4.123.0 从提交 e2e01cb2e75f89307c7a7c77f99521a999728096 的 book/ 部署 53 个静态文件。
  • 首次真实文档 deployment hash 为 56332f8e。
  • production 与 hash URL 均返回 HTTP 200,并包含文档首页标记;它们不经过 Access。
  • 自定义域名 doc.trading-engine.caas.xyz 的未登录请求返回 Cloudflare Access 登录跳转,正文未泄露给该请求。
  • production 与 hash URL 均返回 X-Robots-Tag: noindex, noarchive、Cache-Control: no-store、X-Content-Type-Options: nosniff 和 X-Frame-Options: DENY。
  • 尚未执行授权用户登录后的首页、导航、搜索和 SVG 外部验收;用户通过自定义域名完成人工 review。

本地阅读

仓库固定使用 mdBook v0.5.4 官方预编译二进制,不通过升级项目 Rust 工具链安装 mdBook。当前 Apple Silicon Mac 的最小安装方式:

mkdir -p .tools
curl --fail --location --output .tools/mdbook-v0.5.4.tar.gz \
  https://github.com/rust-lang/mdBook/releases/download/v0.5.4/mdbook-v0.5.4-aarch64-apple-darwin.tar.gz
echo "03e8a6d8b13a2971e0b3280affd03b388373c1485e26f73407c3a76b0b1838df  .tools/mdbook-v0.5.4.tar.gz" \
  | shasum -a 256 --check
tar -xzf .tools/mdbook-v0.5.4.tar.gz -C .tools

构建或启动本地阅读服务:

python3 tools/validate_docs.py
.tools/mdbook build
node tests/test_cjk_search.mjs
.tools/mdbook serve --open

静态入口是 book/index.html。book/ 和 .tools/ 均为本地生成内容,不提交 Git。

cjk-search.js 只补充 mdBook 内置 elasticlunr 的中文单字/双字 token,不引入搜索服务、第三方依赖或自定义主题。回归检查使用 mdBook 实际生成的索引格式验证“文档治理”“治理”“文档”和英文查询。

CI 产物

PR 上的 docs job 使用固定版本并校验 SHA256 后构建文档,上传保留 7 天的私有 GitHub Actions artifact。它只用于渲染检查,不是发布地址;当前 main 构建也不会自动部署 Cloudflare。

人工审阅

  • 阅读者在 mdBook 中检查导航、搜索、中文、代码块、表格和 SVG。
  • 审查者回到对应 GitHub PR 逐行评论并提交 Review。
  • 跨版本问题从仓库 Discussions 根入口发起;当前沿用 GitHub 自动创建的默认分类,采纳结论必须经 Issue/PR 回写文档。
  • Cloudflare Access 只控制其覆盖入口的文档站阅读权。GitHub 私有仓库权限单独控制 PR、编辑和 Discussion;两者不会自动同步。

恢复全私有部署的前置条件

私有部署的原始验收标准仍要求所有 Pages host 在未登录环境无法读取正文;noindex 不能替代 Access。当前用户已经显式接受公开 pages.dev 旁路并授权部署,因此本次发布只能声明为“自定义域名受 Access 保护、Pages 原生入口公开”,不得描述为全私有站点。若以后恢复私有目标,必须保护 production/hash/wildcard 三类 pages.dev 入口并重新执行未登录验收。

如长期讨论数量增长,可在 Issue #6 开始前由仓库管理员把默认开放分类重命名为“文档讨论”;这只是可选的信息架构调整,不阻塞当前文档门禁,也不得删除仍在使用的分类。