跳到主要内容

SyncEngine 技术协议

1. 协议目标

SyncEngine 协议把“从来源 GitHub 项目同步文档到 publish/**”约束为可实现、可审查、不会覆盖整理内容的三方 diff 过程。

它不是简单目录复制。它必须同时处理:

  • 上游来源变化。
  • publish/** 中人工或智能体整理后的变化。
  • 新增、更新、删除、保留和冲突。
  • Sync PR 的可审查输出。

2. 覆盖产品特性

产品特性覆盖方式
稳定文档发布分支只读取配置声明的 ref,默认 docs-publish
来源配置管理config/sources.yaml 读取来源和目标映射
定时收集 / 手动收集docs-sync.yml 调用
三方 diff 同步使用 A/B/C 三方输入判断动作
同步冲突报告输出 source-changes.json 和 PR summary
Draft PR同步结果只进入 Sync PR,不直接发布
项目映射目录写入配置指定的 publishPath
状态记录更新 source lock 和 source changes

3. 输入

输入来源说明
SourceConfigconfig/sources.yamlrepo、ref、sourcePath、publishPath、include/exclude、deletePolicy、conflictPolicy
A:上次来源基线state/source-lock.json上次成功同步时每个来源文件的 hash、path、source ref
B:当前来源内容GitHub 来源仓库当前 ref/sourcePath 下匹配 include/exclude 的文件
C:当前工作目录publish/**当前控制仓库中的目标目录内容

3.1 SourceConfig 校验

同步前必须先校验全部来源配置。

配置约束:

  • 每个 source.id 必须唯一。
  • 每个 publishPath 必须唯一。
  • 不同 publishPath 不能互为父子目录。
  • publishPath 必须位于 publish/** 下。
  • sourcePath 不能为空,不能指向仓库根目录,除非配置显式允许。
  • include/exclude 变更必须进入 Config PR。

违反约束时,SyncEngine 必须失败退出,不得执行部分同步。

3.2 配置变更影响

配置变更会影响 source-lock 的解释方式,不能被当作普通内容同步。

需要生成 config-impact-report 的变更:

配置变更默认处理
ref 变化重新读取来源,保留旧 lock,生成影响报告
sourcePath 变化按潜在目录迁移处理,要求人工确认
publishPath 变化不自动移动,要求人工确认迁移或重新接入
include/exclude 变化生成新增/排除影响报告
deletePolicy 变化只影响后续删除,不回放历史删除

约束:

  • Config PR 必须展示受影响 source、旧配置、新配置和预估文件影响。
  • publishPath 变化不能直接造成旧目录批量删除,除非 PR 明确声明迁移计划。
  • 配置变更合并后,首次 Sync PR 应标记为 config-impact sync,便于维护者重点审查。

4. 输出

输出路径/载体说明
同步后的文件变更publish/**仅对无冲突变更执行新增、更新、删除
新来源基线state/source-lock.json只记录成功 apply 的来源文件 hash 和 ref;冲突文件保留旧基线
同步变更报告state/source-changes.json记录 added、updated、deleted、unchanged、conflict、delete_conflict
PR summarySync PR body / workflow summary给维护者审查同步影响

5. 状态结构

5.1 source-lock.json

{
"sources": {
"kunora-kgent": {
"repo": "innuama-coder/kunora-kgent",
"ref": "docs-publish",
"commit": "...",
"files": {
"docs/index.md": {
"sourceHash": "...",
"publishPath": "publish/system/components/kunora-kgent/index.md",
"lastSyncedAt": "..."
}
}
}
}
}

5.2 source-changes.json

{
"runId": "...",
"sourceId": "kunora-kgent",
"changes": [
{
"sourcePath": "docs/index.md",
"publishPath": "publish/system/components/kunora-kgent/index.md",
"action": "update",
"reason": "source_changed_publish_unchanged",
"baseHash": "...",
"sourceHash": "...",
"publishHash": "..."
}
],
"conflicts": []
}

6. 三方 diff 规则

A:上次来源B:当前来源C:当前 publish动作说明
不存在存在不存在add新增来源文件
不存在存在存在conflict目标路径已有内容,不能覆盖
存在未变未变unchanged无动作
存在变更未变update用 B 更新 C
存在未变变更keep保留人工/智能体整理内容
存在变更变更conflict上游和 publish 同时修改
存在删除未变delete删除 C
存在删除变更delete_conflict上游删除但 publish 已整理

判断“未变/变更”必须使用内容 hash,不使用文件时间。

6.1 source-lock 更新规则

source-lock.json 只能在同步动作成功 apply 后更新。

动作是否更新 lock规则
add写入 B 的 sourceHash、sourcePath、publishPath
update写入 B 的 sourceHash,C 已被更新为 B
delete从 lock 移除该文件或记录 tombstone
unchanged保持当前 lock
keep来源未变,publish 已整理,保持当前 lock
conflict保留旧 A,冲突报告记录 B hash
delete_conflict保留旧 A,冲突报告记录 B 已删除

约束:

  • conflictdelete_conflict 不能把 lock 推进到 B。
  • 冲突解决后,应由下一次成功 apply 或人工标记解决时更新 lock。
  • source-changes.json 必须保存冲突时的 baseHashsourceHashpublishHash,避免下一轮丢失 A/B/C 对比。

6.2 rename / move 策略

MVP 不做智能 rename/move 检测。

处理规则:

  • 来源路径变化按 delete + add 处理。
  • 若旧 publish 文件相对 A 未变,按删除策略处理旧文件,并新增新文件。
  • 若旧 publish 文件已整理,旧路径产生 delete_conflict,新路径产生 addconflict
  • 发布影响报告必须展示旧 URL 删除和新 URL 新增,避免审查者误判为普通更新。
  • 后续如需保留 URL 或自动识别重命名,必须通过 ADR 扩展 SyncEngine 协议。

7. 删除策略

deletePolicy行为
sync-if-unmodified只有 C 相对 A 未变时才删除
report-only不删除,只报告上游删除
never忽略上游删除

MVP 默认使用 sync-if-unmodified

8. 冲突处理

冲突不自动解决。

冲突输出必须包含:

  • sourceId。
  • sourcePath。
  • publishPath。
  • baseHash。
  • sourceHash。
  • publishHash。
  • conflictType。
  • 建议处理方式。

Sync PR 必须标记冲突数量。存在冲突时,PR 不能被自动标记为可发布。

9. 安全和边界

  • SyncEngine 只能写配置声明的 publishPath
  • SyncEngine 不允许写 docs/llm-wiki/** 设计文档。
  • SyncEngine 不允许直接 push main
  • SyncEngine 不触发正式发布。
  • SyncEngine 不调用 RAGFlow 做内容改写。

10. 验收用例

用例预期
上游新增文件,目标不存在publish/** 新增文件,报告 add
上游更新文件,publish 未改自动更新,报告 update
上游未改,publish 已整理保留 publish,报告 keep
上游和 publish 同时修改不覆盖,报告 conflict
上游删除,publish 未改删除 publish 文件,报告 delete
上游删除,publish 已整理不删除,报告 delete_conflict
include/exclude 排除文件不进入 B,不产生同步动作
对此页面有疑问?

问答功能将在后续接入 Answer API。当前可通过页面底部的反馈链接提交问题。

页面来源草稿
来源项目kunora-wiki
分支docs-publish
路径technology/components/kunora-wiki/product/07-mvp-technical-solution/10-protocol-sync-engine.md