Nginx 使用原始 Host 和端口转发,不修改后端跨站防护。补充无 Fetch Metadata 的 LAN/Tailscale 同源和异源、异端口、转发头伪造回归。 验证:配置回归先因丢失端口失败后通过;HTTP竞态、真实隔离Nginx正反例及完整make verify均通过。部署前真实入口无Metadata为403,同源Metadata对照可过;源库及人工复核无写入。
14 KiB
Changelog
[Unreleased]
Added
-
问答运营按已确认口径显示知识覆盖率、回答正确率及原始分子/分母、排除数量与构成。使用完整筛选范围和当前有效人工优先结论,精确规则命中的未覆盖可进入覆盖分母;部分覆盖不算完全覆盖,待确认/未评估/失效/不计入按对应指标排除,零分母显示“暂无可计算数据”。返回独立规则版本,AI 模型与绩效范围仍未接入。
-
问答详情支持治理侧人工复核及不可变审计:覆盖、正确性、产品分类、问题类型、根因与理由由管理员明确填写,操作人取登录身份;保存后独立读回复核历史。保留源端判断和自动规则,输入变化使旧人工结论失效,已观测的内容回退不自动恢复旧结论;并发修改冲突、重复请求不重复留档。
-
新增覆盖复检历史、已采集输入快照和完整筛选范围质量数量。批量统计只传指纹与规则命中元数据,原文在读取问答/复核时采集,未采集版本明确提示而非伪造空快照;源事务时点阻止延迟旧扫描回退新输入。基础数量与本期经确认新增的质量比例分开显示;不接 AI 模型、不定义绩效分母、不回写 DobotAI 原问答。
-
「使用统计 → 个人月明细」按北京时间自然月及截止时点展示当前应用可见名册的人员用量(包含本源零记录),支持部门含子部门、区域/待核对状态、姓名/完整部门路径和已有提问/零记录筛选。稳定身份关联去重、不可关联问答单列、过期组织版本阻断翻页;源端姓名可缺失并提示重新同步,不按姓名匹配身份。姓名筛选通过有界只读 POST 请求体传递、不进入 URL,原始员工标识不返回浏览器;名册不作为在职/考核分母,当月进度不作为绩效结论。
-
问答运营按稳定身份关联当前治理通讯录,缺失部门/区域补全并保留源快照及目录/区域版本;空列判断包含完整筛选结果,不混合配置已变化的分页。新增完整时间/关键词范围的使用统计,问答计次、名册内人员去重,跨区/未匹配/身份缺失分列,不输出绩效结论;不回写 DobotAI 原表。
-
「问答运营 → 区域使用」支持管理员从网页发起持久化通讯录同步,重复请求重放、进行中操作合并;按服务器固定范围注册后台执行器,未接线或未检测到心跳时不创建新任务。界面显示真实任务状态、不编造百分比;失败保留旧快照与区域规则,同步完成不覆盖未保存草稿。旧执行器丢失租约后不能激活结果,重启接管和已提交快照的续跑使用原任务。
-
新增治理侧通讯录实时桥接,复用既有周报读取能力,向源端读取真实缺失祖先以补齐部门树;不改旧周报脚本、配置或输出。私有 JSON 与受控子进程执行器拒绝不完整数据、模拟同步、公开文件和异常输出,超时清理临时人员文件。同步默认关闭,容器启用仍需批准的既有周报 SDK/配置及兼容 Python 运行时挂载。
-
区域归属表支持长部门路径换行,避免继承全局不换行规则后将生效区域与归属依据列挤出桌面面板。
-
「问答运营 → 区域使用」区域归属配置切片:按稳定部门 ID 搜索和勾选完整路径,预览去重归属人数,保存版本后重新读取;父部门包含子部门、子部门显式配置优先,多部门跨区域人员单独待核对。预览不写入,过期版本和不完整部门树被阻断。基础使用统计见本期新增,不代表绩效验收;翻译及 AI 评估模型接入按用户要求暂缓。
-
新增治理侧组织快照与区域修订迁移、受确认保护的后台导入命令;不修改 DobotAI 原表或钉钉组织结构。
-
「问答运营 → 问答记录」首个开发切片:在现有导航中查看 DobotAI 2.0 钉钉问答,支持半开时间范围、原问题关键词、稳定游标分页和完整详情;按整个筛选结果隐藏空列,反馈聚合不放大问答条数。外语翻译、AI 评估尚未接入,不标为第一阶段完成。
-
治理侧重新检查答案:包含
暂无已发布即未覆盖,引用和源端 covered 不能抵消;未命中仍待评估,源端规则单独保留作对照。独立只读源默认关闭、租户后端固定、管理员会话鉴权,源故障不回退治理主库;安全告警明确保留 TEMP/TLS 尚未整改状态。 -
「版本记录」页(一级入口):只读时间线追踪远端 main 可达的全部提交(含合并提交与已并入 main 的侧分支提交),按提交时间倒序显示标题/正文、
[正式版本] / [开发版本] / [历史提交]徽标、短 SHA、提交内变更记录与[查看提交]/[查看 tag];支持「全部 / 正式 / 开发 / 历史」筛选与游标翻页,窄屏单列。 -
新增只读接口
GET /api/v1/build-info(当前运行产物的构建身份)、GET /api/v1/version-history(快照游标分页,不返回伪造的 total)、POST /api/v1/version-history/sync(仅管理员手动同步,并发同步复用同一作业)。 -
新增迁移
000046_version_history(提交记录 + 同步状态):commit_sha是唯一身份,版本号不是唯一键 —— 两个提交算出同一个开发号时各占一行,用 SHA 区分。 -
「当前运行」只认运行产物注入的完整 SHA 精确匹配:匹配到就标该条;开发构建显式标注"开发构建";拿不到标识就显示"当前运行版本未知",不拿最新 main 或最新 tag 顶替;CI 成功不等于已部署。
Changed
-
「系统设置 → 数据源配置」收敛成两个入口:dws 导入(按当前钉钉账号列出可访问的知识库与钉盘空间)与 PP 导入。AList(已由钉盘文件替代)、静态登记的钉钉知识库、本地手工导入与 PP legacy 都不再出现在这一页;已接入的这类来源用归档下架(
POST /api/v1/source-connections/{id}/archive,管理员、幂等,带写意图头与幂等键):从列表、来源与目录、计划刷新与手动扫描里消失,目录快照、发布记录与审计数据一行不删。恢复用…/restore(保持停用、不自动带回调度),或让 dws 重新登记同一来源 —— 钉钉空间登记是确定性 ID +ON CONFLICT,原地复活同一行、不产生重复。卡片上新增「去掉来源」按钮(管理员,带确认弹窗)。 -
迁移
000047_source_connection_archive:新增archived_at/archived_by与只覆盖未归档行的部分索引;列表、目录、计划刷新、手动扫描四类查询一律排除归档行(漏一条就等于入口没去掉)。 -
「系统设置 → 数据源配置」默认只列 PP 资料与「可加入的来源」:AList 来源(已由钉盘文件替代)与静态登记的钉钉知识库来源(改为按当前钉钉账号发现)不再默认列出,收进「显示 AList/钉钉知识库来源(N)」折叠开关 —— 来源一个都没删,展开后照旧可改刷新周期与启停,「来源与目录」里的内容不变。手动导入来源(本地手工验收)不在这次范围内,照旧显示。
Fixed
-
修复通过带端口的 HTTP 地址访问问答运营时,正常同源操作被误报“拒绝跨站配置请求”:网页代理保留原始 Host 及端口,使缺少 Fetch Metadata 的浏览器也能正确执行 Origin 校验。保留后端跨站、异端口、伪造转发头与缺失操作意图的拒绝保护。
-
登记钉钉知识库失败(HTTP 409
space_registration_conflict)的真实原因与修复:source_connections.name有唯一约束,而早期路径登记的钉钉来源(base_url为空、id 与 dws 现在推导的确定性 id 不同)被归档后仍占着名字槽位 ⇒ 重新登记时 INSERT 撞唯一约束;处理器又把所有存储层错误都翻译成同一个 409,真实原因被吞掉(线上只能看到一个无细节的错误码)。现在:① 同名来源已归档时,把它改名腾位(…(已下架 · <短ID>),归档行不显示、数据与审计一行不动);② 同名来源仍在使用时返回space_name_conflict+ 可行动提示(先「去掉来源」);③ 同一登记键指向别的空间且该行仍在用时返回space_identity_conflict(已归档的行则允许就地改写 —— 这就是"去掉后再用 dws 重新获取");④ 其余内部故障改回 500space_registration_failed,不再伪装成冲突;前端优先显示后端hint,并为这两个新码补了中文说明。 -
前端入口与静态资源的缓存语义("新功能看起来没上线"与"页面偶尔裸奔/空白"的根因):
index.html此前没有缓存头,CDN/浏览器按启发式缓存它 ⇒ 页面会一直停在旧构建上(实测被腾讯云 EdgeOne 卡住:源站已是新包,公网入口仍发旧包)。现在index.html每次回源校验(no-cache, must-revalidate);- 带内容哈希的
/assets/长缓存(immutable),但未命中时先回退到"上一版构建的资源"目录、再 404(deploy/legacy-assets由部署脚本在每次重建前落盘并只读挂载):CDN/浏览器仍持有旧index.html时,它引用的旧 JS/CSS 依旧能取到 ⇒ 不会出现"JS 404 白屏"或"CSS 404 只有文字没样式"; - 明确 404 时不再回退成
index.html(否则浏览器把 HTML 当 JS 执行,报一堆语法错误)。
-
上线前护栏 + 事故复盘:
scripts/deploy-api-web.sh现在先校验.env的键值形状(值里再出现KEY=或键名不合法 ⇒ 拒绝上线),配置校验失败时也会给出"两行粘成一行"的线索。事故:.env最后一行没有结尾换行、又被追加新键 ⇒ 两行粘成一行 ⇒VERSION_HISTORY_GITEA_BASE_URL变成非法值 ⇒ api/worker 按设计拒绝启动、崩溃重启(平台整体不可用)。已修数据、加护栏、加回归用例。 -
「版本记录」页的链接改为抓取与链接分离:抓取仍走配置的(内网)地址,页面上的「查看提交 / 查看 tag」用
VERSION_HISTORY_LINK_ORIGIN(公网 origin)拼 —— 原先两者共用内网地址,内网外的浏览器点开是空白;另外 tag 记录原先不带链接(空href点下去没反应),现在补上链接、没有链接就不渲染该按钮。
Security
- 版本记录同步匿名只读远端仓库(不使用任何凭据),来源限配置里批准的 origin 与固定仓库:拒绝任意 URL、拒绝跨主机重定向,单个响应设大小上限与超时、5xx/429 才有退避重试。
- 提交正文与变更记录一律按纯文本渲染(不产生 HTML/脚本注入面);页面不含打 tag / 发布 / 部署入口;同步动作仅管理员可用,服务端再次判角色。
版本号的唯一来源就是本文件顶部那条已发布版本。 不放
VERSION文件、不把版本写进源码常量。正式版本用注释 tag
vX.Y.Z(由人批准后创建):CI 只核验「tag 的版本 == 它指到那个提交里的 版本记录」,不自动升版本、不打 tag、不发 Release。日常改动写进[Unreleased]; 不要求每个提交都改本文件 —— 有使用者可见的变化才记,其余走提交信息与档案。python3 scripts/version.py --identity # 构建身份:release_version / build_kind / commit_sha / display_version / built_at python3 scripts/check_changelog.py --tags # 结构 + tag 一致性(无正式 tag 不判红)小节只认四类(分类可省略,但不要空栏目):
### Added/### Changed/### Fixed/### Security。 破坏性变化写在### Changed里、以**破坏性**开头,并链接发布文档(见docs/RELEASE_RUNBOOK.md)。过程记录(审查轮次、命令输出、逐条修正明细)不入本文件:归档在
docs/archive/, 未合并事项在docs/BACKLOG.md。版本怎么走(两行就够): · 正式版本 = 下面那条
## [x.y.z] - 日期,是发版事实,由人批准后打注释 tagvX.Y.Z; · 开发版本自动递增 =<正式版本的主.次>.<自那个 tag 以来的提交数>(正式0.1.0之后第 12 个提交 =0.1.12),由scripts/version.py从 git 算出来,不写进本文件 ⇒ 每个提交都有自己的版本号, 但"发布版本"仍然只能由人定(CI 不会自动升版本、不会打 tag)。
[0.1.0] - 2026-10-13
Added
- 唯一权威门禁
make verify:一条命令跑完必需检查并产出结构化报告,本地与 CI 跑同一条命令。 - 静态预览发布前先做同一份完整核对:报告有任何缺项就一个 publish 请求都不发。
Changed
- 依赖升级:
vite7.1.3 → 7.3.7、vitest3.2.4 → 5.0.3(npm audit全量 0 命中)。 - 前端存量格式债记入基线
web/.prettier-baseline.json(79 个文件,只能减,2026-12-31 到期)。
Fixed
- 新分支推送时提交范围恒为空(基准改为远端默认分支)。
- 空工作区下 CI 起不来(工作流首步改为最小 bootstrap)。
- 事件负载缺
total_commits时提交范围解析抛未收敛异常。
Security
- 依赖漏洞例外登记
security/dependency-exceptions.json:缺字段 / 过期 / 批准人是占位值 ⇒ 例外无效。
能力基线(未发布):2026-10-10 的上线能力
这一条不是正式发布版本:当时本仓既没有版本号、也没有变更记录,没有 tag、没有 Release。 它只是把已上线能力补记在此,供此后发版对照;版本号体系从下一个正式版本开始(首个正式版本号由人指定)。
- 来源与目录:列出可选的钉钉知识库 → 勾选 → 变成来源;快照与变更集。
- 发布管理:计划 → 建批 → 锁定 → 授权发布(落 WeKnora 生产)。
- 监控 + 需下架车道:测试库知识逐条下架。
- 钉钉侧:知识库发现 / 注册、取件走 dws;登录与系统设置。
- 运行形态:
knowledge-governance-p1-*—— api / web / worker / release-worker / dingtalk-login / postgres 共 6 个容器;web 发布在:8088。 - 验收口径:
docs/USER_FLOWS_ACCEPTANCE.md(C1~C9)与docs/OPERATIONS_RUNBOOK.md。
⚠️ 上面的端口与容器名前缀是本机运行栈的实测值;换环境要按那边的运行栈改,别无脑照抄。