Skip to main content

Pattern E — 独立 docs 仓架构 spec

日期:2026-05-25 作者:Claude(per 用户 5/25 拍板) 状态:spec only(实施前必经用户批准,per 全局 CLAUDE.md「架构级别设计铁律」) 替代:Pattern A(各产品仓 docs/wiki/ + submodule + cross-repo PAT dispatch)


目录


0. 用户原话与触发

「我认为 docs 应该是独立仓库,你觉得呢?否则私人仓库和共有仓库,dispatch 的稳定性和标准都是不确定的。其他项目接入是否也是更容易出现问题?」 —— 用户 2026-05-25

触发背景

5/24 Phase B 实施 Pattern A 后发现的实际摩擦:

  • 私有仓 → public wiki-portal 的 dispatch token 需 fine-grained PAT 90 天过期(WIKI_PORTAL_DISPATCH_TOKEN
  • 主仓 workflow 与代码 CI 混合(.github/workflows/wiki-dispatch.yml
  • 新项目接入需主仓 owner 加 workflow + secret(摩擦大)
  • 私有 vs 公开仓 dispatch 标准不一致

当前实际状态(5/25 仓内检查):

  • wiki-webdocs/attune/docs/lawcontrol/docs/pluginhub/ 等子目录是 直接 markdown 文件(不是 submodule)
  • .gitmodules
  • wiki-dispatch.yml workflow(仅 wiki-deploy.yml — push wiki-web 自身触发 build+deploy)
  • 即 Pattern A 设计文档化、但尚未在 wiki-web 仓真正落地为 submodule 拓扑

→ Pattern E 是在 Pattern A 物理 submodule 化之前就完成的架构调整,免去后续推倒重做。


R1 真验结论(必读)

问题:docs 仓 push 后用 secrets.GITHUB_TOKENrepository_dispatch 触发 wiki-portal CI,能否绕过 fine-grained PAT 90 天过期?

答案:不能。GITHUB_TOKEN 严格只能操作自己所在仓。跨仓 repository_dispatch 必须 PAT 或 GitHub App installation token。

证据(GitHub 官方文档 , 2026-05-25 抓取):

  1. docs.github.com/en/actions/security-for-github-actions/security-guides/automatic-token-authentication 全文示例均以 ${{ github.repository }} 为 target —— 即自己所在仓。明文:"If you need a token that requires permissions that aren't available in the GITHUB_TOKEN, create a GitHub App and generate an installation access token within your workflow. Alternatively, you can create a personal access token, store it as a secret in your repository."
  2. GITHUB_TOKEN 已知设计约束:GitHub Actions 出于防工作流递归触发的安全考虑,GITHUB_TOKEN 触发的事件(push / repository_dispatch / workflow_dispatch)不会触发任何新的 workflow run。即使在同仓,GITHUB_TOKENPOST /repos/{owner}/{repo}/dispatches 也不会触发 on: repository_dispatch workflow(GitHub 官方限制)。
  3. 跨仓GITHUB_TOKENaudience 严格绑定本仓,对其他仓的 API 调用直接 401/403。

Pattern E 因此必须保留某种跨仓凭证,候选:

凭证类型优点缺点
A. 用户 fine-grained PAT(90 天过期)简单、单一来源过期需手动续
B. 用户 classic PAT(无过期)不过期权限粒度差、安全风险高
C. GitHub App + installation token(无过期,仓粒度授权)安全 + 不过期 + 仓粒度初次配置复杂(App 创建 + 安装 + JWT 流)
D. organization-level PAT(org 内共享)全 org docs 仓单凭证仍 90 天过期(fine-grained)/ 权限管理粒度粗

Pattern E 推荐 C(GitHub App)作为最终形态D(org-level fine-grained PAT)作为过渡形态

→ Pattern E 的核心收益不再是"零 PAT"(这是不可达目标),而是:

  1. 统一标准 — 公开 docs 仓 + 同一种 dispatch 模式(不再 private / public 仓两套)
  2. 降低接入摩擦 — 新项目接入只需创建 docs 仓、加 GitHub App 安装,不需主仓 owner 协调
  3. 解耦 docs maintainer 与 code maintainer — 文档贡献者可单独有 docs 仓 write 权
  4. docs 历史与代码历史分离 — git filter-repo 不影响主仓

1. 目标定位

1.1 解决的核心痛点

痛点Pattern A 现状Pattern E 目标
dispatch 凭证一致性私有 attune / attune-pro 各需独立 PAT;公开 KVM 又是一套全部公开 docs 仓 + 统一 GitHub App(或 org PAT)
接入摩擦新项目需主仓加 workflow + secret + .gitmodules + sidebar新项目独立 docs 仓 + 1 行 .gitmodules + 1 文件 sidebar
docs vs code 维护混乱主仓 PR 同时改代码 + docs,CI 跑全套测试docs 仓 PR 只跑 markdown lint,主仓代码 PR 不带 docs
history 噪声docs/wiki/ 大量历史进主仓 git logdocs 历史独立,主仓 git log 干净
docs 权限隔离docs 贡献者必须有主仓 write仅需 docs 仓 write

1.2 与产品 positioning 对齐

  • wiki-portal 仍中立门户(Pattern A 已确立的 multi-tenant 设计不变)
  • content-driven(不依赖产品 release 版本)
  • GitHub-native 单一来源(无外部 CMS,per cloud ARCHITECTURE.md D6)
  • 零数据库(Docusaurus 静态站,per Pattern A)

1.3 不解决的范畴

  • 不替代 README / DEVELOP / RELEASE.md(仍在主仓内)
  • 不替代主仓 docs/ 内非 wiki 内容(INSTALL / TESTING / VERSIONING / ADR / specs — 这些是开发者文档,docs 仓只装"用户面 wiki"内容)
  • 不替代 product launch website(official-web 走自己的路径)

2. 范围边界

2.1 做(必须)

  • 新建 5 个 public docs 仓
    • qiurui144/attune-docs(通用 attune wiki:getting-started / chat / sources / wizard / plugins / agents / privacy / faq)
    • qiurui144/attune-pro-docs(Pro plugin 详细文档)
    • qiurui144/attune-enterprise-docs(B2B 律所 / KVM 一体机用户文档)
    • qiurui144/attune-pluginhub-docs(plugin marketplace 文档)
    • qiurui144/kvm-docs(KVM 一体机产品文档)
  • git filter-repo 抽取 现有 wiki-web 仓 docs/attune/ / docs/lawcontrol/ / docs/pluginhub/ / docs/getting-started/ / docs/hardware/ 等到对应 docs 仓,保留 commit 历史
  • wiki-portal 改造
    • 新建 .gitmodules 引用 5 个 docs 仓(pin 到 main HEAD SHA)
    • 移除 wiki-portal 仓内 docs/ 直接 markdown,改为 submodule 挂载点
    • sidebars.ts 改为按 submodule 路径引用
  • 每个 docs 仓加 dispatch workflow:push main → repository_dispatch 触发 wiki-portal
  • 统一凭证模式(推荐 GitHub App,过渡期 org-level fine-grained PAT)

2.2 不做(明确划清)

  • ❌ 不动主仓 docs/ 内非 wiki 内容(INSTALL.md / DEVELOP.md / RELEASE.md / specs/ / adr/)
  • ❌ 不动 wiki-portal wiki-deploy.yml(push wiki-portal 自身触发 build+deploy 不变)
  • ❌ 不动主仓 README.md(仍指向 wiki-portal URL)
  • 不在本 spec 阶段新建任何 GH 仓(per 用户红线)
  • 不动 wiki-portal .gitmodules(本 spec 仅设计,实施在用户批准后)
  • 不删任何主仓 docs/wiki/(同上)

2.3 后续 v.x 才做

  • v0.2:docs 仓 markdown lint + link check CI(独立 workflow)
  • v0.3:docs 仓 PR preview deploy(独立 Netlify / Vercel preview,非生产 wiki-portal)
  • v0.4:i18n(中英 / 多语言分离到 docs 仓内 i18n/ 目录)

3. 架构数据流

3.1 Pattern A 现行(含 5/24 实施计划,尚未落地物理 submodule)

┌─────────────────────────┐
│ attune (private) │ push docs/wiki/**
│ docs/wiki/ ←── PR │─────────┐
└─────────────────────────┘ │
│ dispatch with FINE-GRAINED PAT
│ (WIKI_PORTAL_DISPATCH_TOKEN, 90d expire)

┌─────────────────────────┐ ┌──────────────────────────┐
│ attune-pro (private) │────▶│ wiki-portal (public) │
│ docs/wiki/ │ │ .github/workflows/ │
└─────────────────────────┘ │ wiki-deploy.yml │
│ docs/attune/ ← copy │
┌─────────────────────────┐ │ docs/attune-pro/← copy │
│ kvm (public) │────▶│ docs/kvm/ ← copy │
│ docs/wiki/ │ └──────────────────────────┘
└─────────────────────────┘

摩擦点:3 不同私/公仓 → wiki-portal,每仓独立 PAT,90 天过期。

3.2 Pattern E 目标

┌──────────────────────────┐
│ attune (private, code 仓) │
│ docs/ │ 仅 INSTALL/DEVELOP/specs/adr
│ README.md → wiki URL │
└──────────────────────────┘
↑ 引用(README 中链接 wiki-portal)

┌──────────────────────────┐ push main
│ attune-docs (public) │──────────────┐
│ wiki/getting-started/ │ │
│ wiki/chat.md │ │ repository_dispatch
│ wiki/sources/** │ │ via GitHub App
│ .github/workflows/ │ │ (or org-PAT)
│ dispatch.yml │ │
└──────────────────────────┘ ▼
┌──────────────────────────┐
┌──────────────────────────┐ │ wiki-portal (public) │
│ attune-pro-docs (public) │─────▶│ .gitmodules │
└──────────────────────────┘ │ docs/ │
│ attune/ ← submodule │
┌──────────────────────────┐ │ attune-pro/← submod │
│ kvm-docs (public) │─────▶│ kvm/ ← submodule │
└──────────────────────────┘ │ sidebars.ts │
│ .github/workflows/ │
│ wiki-deploy.yml │
└──────────────────────────┘

▼ build & deploy
wiki.attune.dev

3.3 数据流时序

  1. 文档贡献者 PR 到 attune-docs main
  2. PR merge → attune-docs 仓内 dispatch.yml 触发
  3. dispatch.ymlGitHub App installation tokenorg PATPOST /repos/qiurui144/wiki-portal/dispatches { event_type: "wiki-content-update" }
  4. wiki-portal wiki-deploy.yml 监听 on: repository_dispatch: [wiki-content-update]
  5. workflow 步骤:
    • checkout wiki-portal + submodules(submodules: recursive
    • git submodule update --remote attune-docs 拉最新 attune-docs main
    • npm ci + npm run build
    • SSH 部署到生产
  6. (可选)workflow 自动 commit 新 submodule pin SHA 回 wiki-portal main(避免 submodule pin 漂移)

3.4 DB / cache layer

  • 零 DB(Docusaurus 静态)
  • GitHub raw CDN 不参与(submodule 走 git protocol 拉,本地构建后生成静态文件)
  • build artifact 仍在生产服务器 wiki-web/build/(不变)

4. 模块边界

4.1 5 个 docs 仓内部结构

每个 docs 仓最小化模板

attune-docs/
├── README.md # 仓库说明 + 贡献指引 + 指向 wiki-portal URL
├── LICENSE # CC-BY-4.0 文档许可
├── .github/
│ └── workflows/
│ └── dispatch.yml # push main → dispatch wiki-portal
├── wiki/ # ★ 实际文档(被 wiki-portal submodule 挂载到 docs/attune/)
│ ├── index.md
│ ├── getting-started/
│ ├── quickstart.md
│ ├── wizard.md
│ ├── chat.md
│ ├── sources/
│ │ ├── index.md
│ │ ├── local-files.md
│ │ ├── webdav.md
│ │ ├── email.md
│ │ └── rss.md
│ ├── llm-setup.md
│ ├── plugins.md
│ ├── agents.md
│ ├── architecture.md
│ ├── privacy.md
│ ├── benchmarks.md
│ └── faq.md
└── tests/
└── markdown-lint.yml # 可选 lint CI

4.2 wiki-portal 仓改造点

wiki-portal/
├── .gitmodules # ★ 新增
│ [submodule "docs/attune"]
│ path = docs/attune
│ url = https://github.com/qiurui144/attune-docs.git
│ branch = main
│ (... 5 个 submodule 条目)
├── docs/ # ← 所有子目录改为 submodule
│ ├── attune/ # → attune-docs/wiki/
│ ├── attune-pro/ # → attune-pro-docs/wiki/
│ ├── attune-enterprise/ # → attune-enterprise-docs/wiki/
│ ├── pluginhub/ # → attune-pluginhub-docs/wiki/
│ └── kvm/ # → kvm-docs/wiki/
├── sidebars.ts # ★ 改:路径引用 docs/<submodule>/wiki/<file>
└── .github/workflows/
├── wiki-deploy.yml # ★ 改:add submodule checkout + remote update + on: repository_dispatch
└── wiki-content-update.yml # ★ 新增:on: repository_dispatch handler

注意:submodule mount path 不直接挂在 docs/attune/,而是 docs/attune/ 是 submodule root,其下的 wiki/ 子目录是 Docusaurus 读取的实际文档。这样可以让 docs 仓本身有 README + LICENSE 而不污染 wiki content。

但这意味着 sidebars.ts 引用路径变成 attune/wiki/indexattune/wiki/quickstart或者用 Docusaurus path 配置把 docs plugin 指向 docs/attune/wiki 而不是 docs/。本 spec 倾向后者:

// docusaurus.config.ts
plugins: [
[
'@docusaurus/plugin-content-docs',
{
id: 'attune',
path: 'docs/attune/wiki',
routeBasePath: 'attune',
sidebarPath: './sidebars/attune.ts',
},
],
// 重复 5 次(attune / attune-pro / enterprise / pluginhub / kvm)
],

这样 sidebar 路径回归正常(indexquickstart),不带 wiki/ 前缀。

4.3 各主仓改造点

attune/ # 不动 docs/INSTALL / docs/specs / docs/adr
└── docs/
├── INSTALL.md # 留在主仓(开发者文档)
├── DEVELOP.md # 留在主仓
├── VERSIONING.md # 留在主仓
├── adr/ # 留在主仓
└── superpowers/ # 留在主仓(spec / plan)

# 删除:
# docs/wiki/ → 全部抽到 attune-docs
# docs/attune-*.md(用户面)→ 抽到 attune-docs

README.md # 在 "User Documentation" 章节链接 https://wiki.attune.dev

5. API 契约

5.1 docs 仓 → wiki-portal dispatch payload

HTTPPOST https://api.github.com/repos/qiurui144/wiki-portal/dispatches

Headers

Authorization: Bearer <github-app-installation-token | org-pat>
Accept: application/vnd.github+json
X-GitHub-Api-Version: 2022-11-28

Body

{
"event_type": "wiki-content-update",
"client_payload": {
"source_repo": "qiurui144/attune-docs",
"source_sha": "abc1234...",
"source_ref": "refs/heads/main",
"triggered_at": "2026-05-25T10:00:00Z"
}
}

wiki-portal wiki-content-update.yml

name: Wiki content update from docs repo

on:
repository_dispatch:
types: [wiki-content-update]

jobs:
update-submodule-and-deploy:
runs-on: ubuntu-latest
permissions:
contents: write # to commit submodule pin
actions: write
steps:
- name: Checkout wiki-portal with submodules
uses: actions/checkout@v4
with:
submodules: recursive
fetch-depth: 0
token: ${{ secrets.SUBMODULE_TOKEN }} # PAT or App token to read submodules

- name: Determine source submodule
run: |
echo "SOURCE_REPO=${{ github.event.client_payload.source_repo }}" >> $GITHUB_ENV
# 映射 qiurui144/attune-docs → docs/attune
case "${{ github.event.client_payload.source_repo }}" in
*/attune-docs) echo "SUBMODULE_PATH=docs/attune" >> $GITHUB_ENV ;;
*/attune-pro-docs) echo "SUBMODULE_PATH=docs/attune-pro" >> $GITHUB_ENV ;;
*/attune-enterprise-docs) echo "SUBMODULE_PATH=docs/attune-enterprise" >> $GITHUB_ENV ;;
*/attune-pluginhub-docs) echo "SUBMODULE_PATH=docs/pluginhub" >> $GITHUB_ENV ;;
*/kvm-docs) echo "SUBMODULE_PATH=docs/kvm" >> $GITHUB_ENV ;;
*) echo "Unknown source repo"; exit 1 ;;
esac

- name: Update submodule to latest main
run: |
cd "$SUBMODULE_PATH"
git fetch origin main
git checkout main
git pull --ff-only origin main
cd -
git add "$SUBMODULE_PATH"

- name: Commit submodule pin
run: |
git config user.name "wiki-portal-bot"
git config user.email "wiki-portal-bot@attune.dev"
git commit -m "chore(wiki): bump ${SUBMODULE_PATH} to ${{ github.event.client_payload.source_sha }}" || echo "No change"
git push origin main

# (build & deploy steps same as wiki-deploy.yml)

5.2 docs 仓 dispatch.yml 标准模板

name: Notify wiki-portal

on:
push:
branches: [main]
workflow_dispatch:

jobs:
notify:
runs-on: ubuntu-latest
steps:
- uses: peter-evans/repository-dispatch@v3
with:
# ★ 必须 PAT 或 GitHub App token — GITHUB_TOKEN 不可跨仓(per R1)
token: ${{ secrets.WIKI_PORTAL_DISPATCH_TOKEN }}
repository: qiurui144/wiki-portal
event-type: wiki-content-update
client-payload: |
{
"source_repo": "${{ github.repository }}",
"source_sha": "${{ github.sha }}",
"source_ref": "${{ github.ref }}",
"triggered_at": "${{ github.event.head_commit.timestamp }}"
}

5.3 凭证存储

推荐 Phase E1 期:org-level fine-grained PAT

  • 名称:WIKI_PORTAL_DISPATCH_TOKEN
  • 权限:repository_dispatch write to qiurui144/wiki-portal
  • 在 GitHub org settings 设为 organization secret,授权给所有 docs 仓
  • 90 天过期 — 加日历提醒,单次操作即续

推荐 Phase E3 期:GitHub App(最终形态)

  • App name: attune-wiki-dispatch
  • App permissions: contents:read + actions:write on target wiki-portal
  • 安装到 qiurui144 / qiurui144-org
  • workflow 用 actions/create-github-app-token@v1 在 job 内换 installation token

6. 扩展点 / 插件接口

6.1 新增第 6 个 docs 仓的流程(标准化)

参考附录 B的详细 5-min 步骤。

6.2 docs 仓模板(qiurui144/docs-template

规划:实施 Phase E1 后立即建一个 qiurui144/docs-template 仓作为后续接入起点:

docs-template/
├── README.md # "Replace 'PROJECT' with your project name"
├── LICENSE
├── .github/workflows/dispatch.yml
└── wiki/
└── index.md

新项目接入 = gh repo create qiurui144/<project>-docs --template qiurui144/docs-template

6.3 wiki-portal 端的扩展锚点

  • docusaurus.config.tsplugins 数组 — 每个 docs 仓 1 个 plugin entry
  • sidebars/<project>.ts — 每个 docs 仓 1 个 sidebar 文件
  • wiki-content-update.yml case 语句 — 加 1 行映射

7. 错误处理 + 边界 case

7.1 错误码

场景exit code处理
docs 仓 push 但 PAT 过期dispatch.yml fail step用户在仓页看到红勾,手动 re-run workflow 或续 PAT
dispatch 成功但 wiki-portal build failwiki-content-update.yml fail step通知 webhook → Slack(待 v0.2 实施);手动 workflow_dispatch 重试
submodule 仓被删除wiki-portal CI submodule update fail显式报错 + 临时把 sidebar 该项注释掉,避免整站 build fail
docs 仓 main 不存在git checkout main fail显式报错;要求 docs 仓必须有 main

7.2 边界 case

  • docs 仓首 commit / main 空:wiki-portal 收 dispatch 后 git pull 拉到空 tree → Docusaurus build 抱怨缺 index.md → 失败。对策:docs-template 强制含 wiki/index.md 占位。
  • submodule pin 漂移(wiki-portal main 的 submodule SHA 与 docs 仓 main HEAD 不一致):wiki-content-update.yml 总是 git pull --ff-only origin main + commit 新 SHA,自动消除漂移。
  • 并发 dispatch(多 docs 仓同时 push):用 GitHub Actions concurrency: { group: wiki-deploy, cancel-in-progress: false } 让队列串行,避免 deploy 冲突。
  • rate limit:GitHub Actions 同仓 workflow 60/h;wiki-portal wiki-content-update.yml 受此限。docs 仓 push 频率 ≪ 60/h,安全。
  • 构建产物为空Verify build output step 已有(per wiki-deploy.yml)— 不变。

7.3 graceful degradation

  • 任一 docs 仓不可用(403 / DELETED) → wiki-portal 仍能 build 其他 4 个 docs(前提:删该 submodule + sidebar 条目)
  • wiki-portal 不可用 → docs 仓 push 不影响主仓 CI,docs 维护人员仍能在 docs 仓内预览 markdown
  • dispatch PAT 过期 → 影响仅 docs 仓 → wiki-portal 的自动触发;手动 workflow_dispatch 仍可触发 wiki-portal wiki-deploy.yml

8. 成本契约

8.1 GitHub 资源

资源Pattern APattern E增量
public 仓数1 (wiki-portal)6 (wiki-portal + 5 docs)+5
private 仓数2-3 (attune / attune-pro 含 docs/wiki/)2-3 (不含 docs/wiki/)0
GH Actions minuteswiki-portal build ~5 min/pushdocs dispatch ~10s + wiki-portal build ~5 min+20s/push (可忽略)
GH secrets1 PAT × N 私仓1 org PAT 共享 / 或 1 GitHub App-N+1
月度估算~10 push/月 × 5 min = 50 min~50 min(GitHub Actions 免费额度 2000 min/月,绰绰有余)

8.2 维护成本

任务Pattern APattern E
PAT 续N 次(每仓独立 PAT)1 次(org 共享 PAT)或 0 次(GitHub App)
新项目接入主仓 owner 协调 + 写 wiki-dispatch workflow + 加 secretdocs 仓 owner 自助
docs PR review主仓 maintainer(混在代码 PR 里)docs maintainer(独立)
sub-team docs 贡献需主仓 write 权仅 docs 仓 write 权

8.3 用户 UI 显示

不适用 —— Pattern E 是基础设施 / CI 层变更,对终端用户透明。wiki-portal URL 不变。


9. 测试矩阵

9.1 真验路径(必须在实施前完成)

测试项方法通过标准
R1 验证(已完成)阅 GitHub 官方 docsGITHUB_TOKEN 不能跨仓 ✓
R2 验证在测试 public 仓用 fine-grained PAT 真触发 wiki-portal dispatchwiki-portal workflow run 成功启动
R3 验证测试 submodule pin commit 回写流程wiki-portal main 自动得到新 SHA commit
R4 验证测试并发 dispatch两次同时 push 触发的 build 串行执行

9.2 实施后测试矩阵

类型case 数工具
golden case(push docs 仓 → wiki 更新)5 / docs 仓 = 25manual workflow trigger + curl check wiki URL
属性测试0N/A(基础设施层无属性)
边界测试5(1) 空 docs 仓首 push (2) submodule 不可达 (3) PAT 过期 (4) 大文件(10 MB markdown)(5) UTF-8 BOM markdown
异常测试3(1) docs 仓被删 (2) wiki-portal main protected (3) sidebar.ts 引用不存在 doc
集成 E2E1完整 push → dispatch → submodule update → build → deploy → wiki URL 验证
回归 fixture每修一个 bug 加 1wiki-portal CI 内 markdown lint + link check

9.3 与 Pattern A 等价性测试

实施 Phase E2 期(并存)必须验证:

  • 同样的 markdown 在 Pattern A submodule(如果实际部署过)和 Pattern E 仓产生完全相同的 wiki URL + 渲染结果
  • sidebar 顺序一致
  • search index 一致

10. 向后兼容 / migration path

10.1 5-phase 迁移计划

Phase E1 (1 day): 仓基础设施
- 新建 5 docs 仓(empty + LICENSE + README)
- 建 qiurui144/docs-template
- 配 org-level fine-grained PAT

Phase E2 (1 day): 内容迁移
- git filter-repo 抽 wiki-web 仓 docs/attune/ → attune-docs/wiki/(保留 commit 历史)
- 同上 docs/lawcontrol/ docs/pluginhub/ docs/getting-started/ docs/hardware/ 等
- 推到对应 docs 仓
- 验证 docs 仓 markdown 可独立预览(npm run start)

Phase E3 (1 day): wiki-portal 改造
- 加 .gitmodules + git submodule add(指向 5 docs 仓 main)
- 改 docusaurus.config.ts 加 5 个 plugin-content-docs 实例
- 改 sidebars.ts → 拆成 sidebars/<project>.ts
- 改 .github/workflows/wiki-deploy.yml 加 submodules: recursive
- 加 .github/workflows/wiki-content-update.yml
- 本地测试 npm run build 通过

Phase E4 (1 day): 旧 docs 仓内容删除
- wiki-portal main 内删 docs/attune/ docs/lawcontrol/ 等直接 markdown(已被 submodule 覆盖)
- 验证 wiki-portal build 仍正常
- 主仓 attune / attune-pro 的 docs/wiki/(若存在)删除
- 主仓 README 加链接到 https://wiki.attune.dev/attune

Phase E5 (0.5 day): 监控 + 文档
- 加 wiki-portal monitoring(GH Actions failure → Slack)
- 写 docs-template/README.md「新项目接入指南」
- 更新 wiki-portal README.md 描述 Pattern E

总工期:4.5 天

10.2 旧 URL 兼容

wiki-portal URL 不变(wiki.attune.dev/attune/getting-started 等),用户视角零迁移。

10.3 主仓 README 链接

主仓 README "Documentation" 节继续指 https://wiki.attune.dev。无变化。

10.4 rollback path

任意 phase 失败 → 回滚到 phase N-1:

  • Phase E2 失败:git filter-repo 备份原始 wiki-web 仓
  • Phase E3 失败:wiki-portal main 不合 PR,docs 仓继续存在(无害)
  • Phase E4 失败:保留旧 docs/ markdown 副本到 phase 完成稳定后再删

11. 风险登记

ID风险概率影响缓解
R1GITHUB_TOKEN 跨仓 dispatch 不可行(已验证)✓ 已确认仍需 PAT 或 GitHub App,Pattern E 的"零 PAT"假设不成立。但其他收益(标准化 / 接入简单 / 维护解耦)仍 valid。
R2git filter-repo 抽 docs/wiki/ 时漏 commit(重命名 / 移动文件历史断裂)filter-repo --path docs/wiki + --path-rename;事后用 git log --follow 验证关键文件历史完整
R3wiki-portal Phase A 设计的 layout(docs// 直接 markdown)已被假定 — 改 submodule 结构需谨慎实测发现 Pattern A 物理 submodule 尚未落地(仓内仍是直接 markdown)→ 可以一次性跳过 Pattern A submodule 阶段,直接走 Pattern E
R4KVM / 其他项目 owner 不接受独立 docs 仓用户主导决策;非用户拥有的项目(lawcontrol 等)可保留 Pattern A 老法
R5docs ↔ code 双 commit 维护成本(feature 改 + docs 改要两个 PR)文档化 contributor flow;高频 changeset 可批量后一次性同步 docs 仓
R6public docs 仓内容泄露内部 code-tied info(如未发布 feature 名 / 私有 endpoint)docs 仓 PR review checklist:禁止引用未发布 feature;wiki-portal CI 加 grep 检查关键词(如 "INTERNAL"、"WIP")
R7qiurui144 org 仓数过多(已 10+)docs 仓全部 public 不算 private 仓配额;命名约定 *-docs 后缀好筛
R8submodule pin 漂移 → wiki-portal 不知道某 docs 仓有新 commitwiki-content-update.yml workflow 自动 git pull --ff-only + commit 新 pin;每 dispatch event 触发一次同步
R9fine-grained PAT 90 天到期忘续加 GitHub App(无过期)作为最终方案;过渡期日历提醒
R10dispatch event 丢失(GH Actions outage / rate limit)docs 仓 README 提供「手动 workflow_dispatch」指引
R115 个 plugin-content-docs 实例增加 wiki-portal build 时间Docusaurus 单 plugin 实例 build 平均 30s → 5 实例 ~2-3 min(仍 < 5 min CI 限)
R12docs 仓 README + LICENSE 与 wiki/ 内 index.md 重复 / 冲突README 描述「这是 wiki 内容源」;index.md 是 wiki 首页 — 用途明确不冲突

附录 A:Pattern A vs Pattern E 对比矩阵

维度Pattern APattern E优胜
凭证管理N 个 PAT(每仓独立)1 个 org PAT 或 1 个 GitHub AppE(-N+1)
凭证过期N × 90d 续期点1 × 90d 或 0(App)E
新项目接入需主仓 ownerdocs 仓 owner 自助E
docs 维护权限与主仓 write 耦合独立E
history 干净度主仓含 docs/wiki/ 历史主仓干净E
docs PR review混在代码 PR独立E
dispatch 稳定性私 / 公 仓两套标准全公开 + 统一E
初次实施复杂度1 仓加 workflow5 仓新建 + filter-repo + wiki-portal 改A(简单)
运维复杂度中(PAT 续期 N 次)低(GitHub App 安装一次)E
storage cost主仓 +docs 体积5 个独立小仓等价
wiki-portal CI 复杂度中(每仓 trigger 不同)低(统一 repository_dispatch handler)E
回滚成本中(需 git filter-repo 反向)A
docs 仓独立运营(如以后单独开源给社区贡献)不可(与代码耦合)E

总评:12 维度中 Pattern E 优胜 9 项,Pattern A 优胜 2 项(初次复杂度 + 回滚),1 等价。

建议采用 Pattern E实施工期 4.5 天


附录 B:新项目 5-min 接入路径(spec 描述)

前提:org-level PAT 已存在 / GitHub App 已安装到 qiurui144。

步骤(以新项目 myproject-docs 为例):

# 1. 用 docs-template 建新 docs 仓(30s)
gh repo create qiurui144/myproject-docs \
--template qiurui144/docs-template \
--public --confirm

# 2. clone + 改 README + 加 wiki/index.md(2 min)
git clone https://github.com/qiurui144/myproject-docs.git
cd myproject-docs
sed -i 's/PROJECT/MyProject/g' README.md wiki/index.md
git add . && git commit -m "init: MyProject wiki" && git push

# 3. wiki-portal 加 submodule(1 min)
cd /path/to/wiki-portal
git submodule add https://github.com/qiurui144/myproject-docs.git docs/myproject
# 编辑 docusaurus.config.ts,加 myproject plugin-content-docs 实例
# 编辑 sidebars/myproject.ts,加 sidebar 定义
# 编辑 .github/workflows/wiki-content-update.yml,加 case */myproject-docs

# 4. wiki-portal commit + push(30s)
git add .
git commit -m "feat(wiki): add myproject docs"
git push origin main

# 5. 验证(1 min)
# - docs 仓 push main → 触发 dispatch
# - wiki-portal 收 dispatch → submodule update → build → deploy
# - 浏览 wiki.attune.dev/myproject/ 看到 index

总耗时:~5 min(不含等 CI build 完成的 ~5 min)。

vs Pattern A 接入:

  • 主仓 owner 加 docs/wiki/ 目录 + workflow + secret + 协调跨权限 = ~20-30 min

实施前最终 checklist

  • 用户书面批准本 spec(per 「架构级别设计铁律」§2.评审流程)
  • 决定凭证模式:org PAT(过渡)vs GitHub App(最终)
  • 决定 docs 仓 LICENSE(CC-BY-4.0 vs MIT vs Apache 2.0)
  • 决定 docs 仓命名约定(<project>-docs ✓ vs <project>-wiki
  • 决定 wiki-portal config 使用单 plugin 多实例 vs 单实例 multi-instance
  • 实施前 R2 / R3 / R4 真验通过

spec 状态:draft → 待用户审 → 批准后 invoke superpowers:writing-plans 出 implementation plan。