Commit Graph

9 Commits

Author SHA1 Message Date
姚章浩 acf053faf3 feat(release): 建批时冻结 + 验收通过自动批准 —— 把"每份文档 8 步"砍掉两步并去掉两次卡死
背景:发布管理把"逐条核验"的仪式强加给每一份文档。实测一份文档要 9~11 次交互,
且有两处顺序陷阱(冻结后批准 → 建批 422;生成即固化 → 批准被永久钉住)。

P0-1 建批时冻结:
- CreateReleaseBatch 在未指定版本时,自己把当前实时计划冻结成一份**已确认**版本并绑定
  (同一事务;同摘要复用最近版本,planned 或 confirmed 都可复用,因此同一份计划不堆版本)。
- 语义不变:批一旦建立,清单/摘要/验收轮次/目标库绑定全部不可变、回滚按它走;变的只是
  "谁在什么时候按固化键"——从操作员的手动两步变成建批这一下。
- 效果:去掉「生成新版本」「确认冻结」两步;消灭"批准晚于冻结 → 422"这类顺序陷阱;
  前端不再传版本 id,也不再有"所选知识不在冻结清单里"的阻断。
- 计划→清单项的映射抽成 ChangeSetItemsFromPlan 供两处共用,否则两处算出的摘要不同,
  "同一计划复用同一版本"永远不命中。

P0-2 验收通过自动批准:
- 验收三项结论达发布门槛(knowledge_exists/chunks_present=passed,retrieval_hit 与门槛同
  口径)时,由 worker 写入 reviewer_ref='system:auto' 的批准记录,替代"每份文档点一次批准"。
- 策略 TEST_AUTO_REVIEW_POLICY = off | internal(默认,仅对内)| all;值不认识拒绝启动。
  只影响审核这一步:生产授权、双闸与发布前快照门禁不受影响。界面上只读展示当前策略。
- 安全边界(写死在审核 SQL 里):系统只允许写"第一条"审核——人工一旦表过态,机器不得用一条
  更晚的 approved 把人工结论翻回去;人工随时可再审。集成测试去掉该约束即 FAIL(已实测)。
- 自动批准自身的任何失败都不影响验收结论,只上报。

顺带(P1-1 前半,已被 P0-1 取代的部分已删除):
- 写操作失败把服务端 {"error": ...} 的原因带出来,并对已知原因给出下一步(不再只给 HTTP 状态码)。
- 当前的"不在已冻结清单里"标注与就地修复按钮随 P0-1 一起移除(该失败模式已不存在)。

测试:bind_time_freeze_integration_test.go(绑定已确认版本/同计划复用/冻结后不可变/
动作不符仍 NotEligible)、auto_review_integration_test.go(系统只写第一条、人工可再审)、
validate_test.go(对内自动/对外不自动/策略关闭/验收未过不批/自身失败不影响验收)、
auto_review_test.go、config_test 及前端能力解析测试。
实测耗时:本机 Go 全量 26 包通过、前端 178 条通过。
2026-10-10 15:05:20 +08:00
姚章浩 d29e04e647 fix(artifact): 白名单环境漏传 dws 变量导致钉钉取件整体失败
端到端验收实测(2026-10-10):标注后取件以 artifact_fetch_rejected: credentials 终态失败。
根因:artifactfetch runner 给子进程的是白名单环境(防凭据外泄),但没有透传 dws 取件器
必需的 ARTIFACT_DINGTALK_FETCHER/DWS_BIN/DWS_CONFIG_DIR/DWS_HOME/DWS_DISABLE_KEYCHAIN
→ dws 找不到配置目录与文件型 keychain($HOME/.local/share/dws-cli 落空)→ 报未登录 →
映射成 credentials 终态(不可重试)→ 且不会回落老路径。脚本单跑正常,因为绕过了白名单。

- handler.go: childEnv() 显式透传 dws 变量(仅非空值);失败时把 stderr 尾部脱敏后带进错误,
  否则只能看到裸 code 无法定位(本次排查就卡在这)
- 新增 3 个回归测试:环境透传 / 空值不透传 / stderr 上报与敏感内容抑制
- 实测:修复后重新入队 → artifact.fetch completed,产物 sn-753f….docx 4799B(adoc→docx 导出),
  content_objects 记为 docx/verified
2026-10-10 09:57:41 +08:00
姚章浩 1fa35e9870 feat(release): 发布前快照硬门禁 + 云内快照 + ES/OSS 保护
按生产级备份组合落地:

- internal/releasesnapshot:新增门禁包,要求 root 下存在覆盖目标库、未过期
  (默认 24h)、含 wiki_pages.jsonl 与 sha256 的快照;本地文件再校验哈希。
  7 条单测(过期/换库/篡改/缺页/未接线/半成品)。
- 发布器:写目标库之前(Publish/Delete/Rollback 三条路)先过门禁;映射目标
  (源库→目标库,共享真实库)或 policy=always 时必须有快照;门禁未接线
  同样拒绝(fail-closed)。新错误码 release_target_snapshot_missing(不可重试)
  + 页面中文提示。6 条发布器单测。
- worker 配置新增 target_snapshot{root,max_age_hours,policy},校验 policy/
  max_age/绝对路径;compose.release-sim.yaml 只读挂载快照目录。
- scripts/target_kb_snapshot.sh:默认云内执行(与 DB 同 VPC,凭据取自 WeKnora
  容器)+ 默认不导 chunks(44s 出 8 张表);修复 \copy 不能跨行/不能带 WITH、
  ES 计数改用 knowledge_base_id.keyword。
- ES:注册 kb_backup 仓库(path.repo),首个快照 36s/4.7GB/0 分片失败,
  SLM kb-hourly(3d)+kb-daily(7d) 已建并执行成功。
- OSS:目标桶开启版本控制(此前未开启)。
- 文档 P6 增补硬门禁与云内执行;真实快照目录上门禁实测:两个绑定库通过、
  未覆盖库拒绝、未接线拒绝。
2026-10-09 10:59:55 +08:00
姚章浩 6440e3f679 feat(release): 发布目标知识库可选(源库 → 目标库映射)
- 迁移 000044:production_kb_bindings + release_item_executions.target_knowledge_base_id
- 系统设置新增「生产知识库绑定(对内/对外)」:从生产 WeKnora 实际列表选库,
  保存时真校验(不存在拒收;生产端不可达只提示并如实回报),仅管理员可改
- 执行计划按绑定解析目标库并冻结进 release_item_executions;空目标直接拒收;
  已发布过的条目保留原目标(重试/回滚回到同一处)
- DocumentBundle.RemapKnowledgeBase:knowledges/chunks/knowledge_tags/wiki_pages/
  wiki_folders 的 knowledge_base_id 与 ES 文档字段改写为目标库,重算表/文档摘要并重新封装
- 契约比对改为「声明的映射对」(KnowledgeBaseMapping),其余字段继续 fail-closed
- 契约检查器 / 目标身份 / 验证器全部走映射后的目标库;对象通道无需改写
- Compose 拆分:数据面接线 compose.release-sim.yaml + 两道门禁 compose.release-gates.yaml
- 测试:RemapKnowledgeBase 全通道/无操作/fail-closed、映射契约、绑定接口、RBAC、真实 PG 集成
2026-10-08 15:41:13 +08:00
姚章浩 40d0c511d6 fix(weknora): 同内容重复上传改为认领而非死信 2026-09-30 10:54:07 +08:00
姚章浩 767684bb1f feat(monitor): 死信中文提示与成功/取消自动退信 2026-09-30 10:54:07 +08:00
姚章浩 b3c9331966 feat(ingest): 源与目录文件名过滤及钉钉文档导出
- filename_filter_rules table (000035) with source-root and per-directory rows
- additive inheritance: source default + every ancestor directory contributes
- filename_is_filtered() SQL predicate applied to catalog browsing, subtree
  counts, change-set diffing, routing fan-out and artifact fetch manifests
- fetch_state 'filtered' (CHECK extended); reconcile cancels/restores fetch
  jobs, retires planned publications and blocks items when rules change
- GET/PUT/DELETE /api/v1/filename-filters (Idempotency-Key, normalized
  extensions) + Settings and Catalog filter editors
- failJobSQL no longer swallows the claimed row when the failure projection
  upserts (fixes spurious 'lease lost' retries)
- DingTalk live fetch: adoc/axls now use the export-job pipeline (HTTP 403
  from file/download fixed), header-signature downloads supported
2026-09-30 10:54:07 +08:00
姚章浩 63f3b2c503 feat(governance): policy-driven ingestion from catalog annotations
Annotation in 来源与目录 is now the only import decision surface:
- migration 000033: catalog_import_intents (durable, rescan-proof per-file
  intent with locator snapshot + fetch lifecycle), source_items.policy_state,
  planned publication state, ui_setting_revisions.ingestion_concurrency
- marking fans a folder decision out to per-file intents, materializes
  versioned items, reuses already-verified local bytes (compare, don't pull),
  and plans one publication per routed KB; blocked retires planned rows
  while live publications stay untouched (需下架 shows in the KB diff)
- artifact.fetch worker lane (scripts/artifact_fetch.py): DingTalk export
  tree/live box API, AList /api/fs/get direct download with SSO-redirect
  fail-closed, PP ledger via locator hash; content-level dedupe on sha256
- 开始处理 promotes planned->pending inside the claim-time concurrency budget
  from system settings; claims enforce it in SQL
- monitor overview rebuilt as knowledge-base diff: planned/needs_removal per
  KB + fetch pipeline summary; frontend lanes 待入库/需下架 replace the
  deprecated snapshot change-set confirmation
- spool: images (png/jpg/gif/bmp/webp) accepted, ppt/pptx rejected in favour
  of PDF twins; DingTalk PPT resolves its converted PDF pair
2026-09-30 10:54:07 +08:00
zheromiku dcdc8d1ddd feat: 知识治理平台(含已验证发布/回滚契约)
全栈知识治理平台首次入库(P1-P10 + 发布链路模拟验证闭环):

- 治理核心:源目录/变更集/人工审核/发布批次/发布执行(fail-closed 闸口)
- 测试通道:WeKnora 测试 KB 上传/轮询/验收;poll 完成时写入
  parser_generation/index_generation,修复 manual/seed 路径发布闸口永久拦截
- 发布适配器 v071(本地 source=测试角色 / 云端 target=生产角色 模拟验证通过):
  * ES 导出/导入 mapping 自适应(.keyword 子字段、可选 tenant_id)
  * OSS locator 支持嵌套 scheme;chunks.seq_id 由目标序列分配
  * bundle 归档同身份重试原子替换;verifier 按 bundle chunk_type 计数
  * 回滚 job payload 支持 prior_execution_id(strict 解码)
- 三通道发布+回滚演练实测:publish 4/4 verified,检索命中,
  rollback 4/4 rolled_back,目标端 PG is_enabled=false、ES is_enabled=false
- 前端 A·Data-console 风格全站统一,120 用例通过
- 门禁:go vet / go test 全包通过,gofmt 干净
2026-09-30 10:54:06 +08:00