Publish / Display Manifest 技术协议
1. 协议目标
本协议定义 LLM-WIKI 如何把已审批的 publish/** 发布到展示层,并让页面状态、发布影响、索引状态和展示层漂移可追踪。
核心原则:
- Git 中的
publish/**是内容事实源。 - Docusaurus 是展示产物,不是内容事实源。
- RAGFlow 和 Meilisearch 是索引消费方,不是内容事实源。
- 发布、索引和展示必须通过 manifest 对账。
2. 覆盖产品特性
| 产品特性 | 覆盖方式 |
|---|---|
| 发布影响预览 | publish-impact-report.json |
| 展示层漂移检测 | site-manifest.json 与 Git/publish manifest 对账 |
| 页面元信息 | page-manifest.json |
| 页面质量状态 | page manifest + quality events |
| 文档阅读 | Docusaurus 从已审批内容构建 |
| 导航浏览 | 控制面生成 sidebar 和页面路径 |
| 引用回跳 | URL、anchor、chunk metadata |
| 索引更新 | index-manifest.json |
| 回滚能力 | manifest 记录 Git commit 和页面 hash |
3. Manifest 类型
| Manifest | 说明 |
|---|---|
page-manifest.json | 页面来源、状态、质量和关联对象 |
publish-impact-report.json | PR 或发布前后影响页面 |
publish-manifest.json | 本次发布读取的 Git commit、页面集合和内容 hash |
site-manifest.json | Docusaurus 输出 URL、rendered hash 和可访问状态 |
index-manifest.json | RAGFlow / Meilisearch 索引状态 |
4. 发布影响报告
{
"reportId": "...",
"publishRunId": "...",
"baseRef": "main",
"headRef": "docs-release/...",
"changedPages": [
{
"path": "publish/system/components/kunora-kgent/index.md",
"action": "update",
"url": "/system/components/kunora-kgent/",
"sourceProject": "kunora-kgent",
"affectedIndexes": ["ragflow-approved", "meilisearch"],
"relatedIssues": []
}
],
"build": {
"docusaurus": "passed",
"brokenLinks": 0
}
}
规则:
- PR 创建或更新时生成。
- Release PR 必须在 PR body 或 summary 中展示摘要。
- 删除页面必须显式展示 URL 影响。
- 报告不替代 Git diff。
5. Publish Manifest
{
"publishRunId": "...",
"publishedAt": "...",
"gitCommit": "...",
"pages": [
{
"path": "publish/system/components/kunora-kgent/index.md",
"contentHash": "...",
"url": "/system/components/kunora-kgent/",
"qualityStatus": "approved",
"qaVisible": true,
"indexable": true
}
]
}
规则:
- 只从
main的已审批内容生成。 - contentHash 使用规范化后 的 Markdown 内容。
qaVisible=false的页面不能进入正式问答 dataset。- 删除页面必须从 manifest 中移除,并同步给索引删除流程。
6. Site Manifest
{
"publishRunId": "...",
"publishedAt": "...",
"gitCommit": "...",
"pages": [
{
"path": "publish/system/components/kunora-kgent/index.md",
"url": "/system/components/kunora-kgent/",
"sourceHash": "...",
"renderedHash": "...",
"status": "published",
"httpStatus": 200,
"expectedStatus": 200,
"redirectTarget": null,
"cacheValidUntil": null
}
]
}
规则:
- Docusaurus build 后生成。
- 部署后至少对关键 URL 做可访问检查。
sourceHash必须等于 publish manifest 中同页面的contentHash。renderedHash只用于和同 URL 的上一版渲染产物或本次构建产物 manifest 对账,不能直接与 MarkdownsourceHash比较。- 静态站不允许后台手工改受管页面;若托管平台支持手工修改,必须禁用或纳入漂移检测。
7. Index Manifest
{
"publishRunId": "...",
"indexedAt": "...",
"gitCommit": "...",
"targets": {
"ragflow-approved": {
"status": "passed",
"documents": 120
},
"meilisearch": {
"status": "passed",
"documents": 120
}
}
}
规则:
- RAGFlow approved dataset 和 Meilisearch index 都必须记录状态。
- 索引失败不能修改 Git 内容事实。
- 正式问答继续使用上一版可用索引,直到新索引成功。
- 删除页面必须同步删除索引记录。
7.1 发布与索引幂等
每次发布必须生成全局唯一 publishRunId,并贯穿:
publish-impact-report.jsonpublish-manifest.jsonsite-manifest.jsonindex-manifest.json- workflow summary
幂等规则:
| 操作 | 幂等键 | 规则 |
|---|---|---|
| Docusaurus build | publishRunId + gitCommit | 同一 run 重试应覆盖同一构建产物目录 |
| 静态站发布 | publishRunId + gitCommit | 同一 run 重试不得生成多个生产版本记录 |
| RAGFlow upsert | documentId + contentHash | 相同 hash 重试不应产生重复文档 |
| RAGFlow delete | documentId + publishRunId | 删除已完成时重试应视为成功 |
| Meilisearch upsert | documentId + contentHash | 相同文档重试覆盖同一 id |
| Meilisearch delete | documentId + publishRunId | 删除不存在时视为成功 |
状态规则:
- 同一
publishRunId的失败步骤可以重试。 - 新的
publishRunId不能复用旧 run 的半完成状态。 - index manifest 必须记录每个 target 的 status、attempt、startedAt、finishedAt 和 error。
- 只有站点发布和索引目标全部达到要求后,才标记本次发布完成。
8. 漂移检测
对账输入:
publish-manifest.jsonsite-manifest.jsonindex-manifest.json- 当前 Git commit
漂移类型:
| 类型 | 判定 |
|---|---|
site_outdated | site manifest gitCommit 落后于 publish manifest |
page_missing | publish manifest 有页面,site manifest 无 URL |
source_hash_mismatch | site manifest sourceHash 与 publish manifest contentHash 不一致 |
rendered_hash_mismatch | 部署后 renderedHash 与本次构建产物 renderedHash 不一致 |
index_outdated | index manifest gitCommit 落后 |
deleted_page_still_visible | 删除页面超过 cacheWindow 后仍返回非预期状态 |
删除页面策略:
| 字段 | 说明 |
|---|---|
expectedStatus | 删除后期望状态,通常为 404、410 或 301/302 |
redirectTarget | 受控重定向目标,允许删除页面跳转到替代页面 |
cacheValidUntil | CDN 或静态托管缓存允许的最晚过期时间 |
规则:
- 删除页面在
cacheValidUntil前仍可访问,不视为漂移。 - 删除页面如果返回受控 redirect,并且
redirectTarget匹配,不视为漂移。 - 删除页面超过 cache window 后仍返回 200,才报告
deleted_page_still_visible。 - 若产品要求保留历史版本页面,应将该页面标记为历史版本 URL,而不是删除漂移。
漂移处理:
- 生成报告。
- 标记页面质量状态。
- 必要时创建 GitHub Issue。
- 不自动修改 Git 内容。
9. 验收用例
| 用例 | 预期 |
|---|---|
| Release PR 修改页面 | 生成影响报告并写入 PR summary |
| Release PR 删除页面 | 影响报告展示删除 URL 和索引删除影响 |
| 发布成功 | 生成 publish manifest 和 site manifest |
| 索引成功 | index manifest 记录 RAGFlow 和 Meilisearch 状态 |
| 同一 publishRunId 重试索引 | 不产生重复 RAGFlow/Meilisearch 文档 |
| 删除不存在的索引文档 | 幂等视为成功 |
| 静态站缺页 | 漂移检测报告 page_missing |
| Markdown sourceHash 与 publish contentHash 不一致 | 报告 source_hash_mismatch |
| renderedHash 与本次构建产物不一致 | 报告 rendered_hash_mismatch |
| 删除页面在 cache window 内仍可访问 | 不报告漂移 |
| 删除页面受控重定向 | 不报告漂移 |
| 索引失败 | 内容仍已审批,但索引状态为 failed,不标记索引完成 |