Files
ai-contract-platform/project-docs/V2-P1-04.2-combined-playbook-candidates-2026-08-23.md
T
yuqei 1d85329a6a
Build and Test Quality Gate / Contract Web typecheck and build (pull_request) Successful in 9m12s
Build and Test Quality Gate / Isolated Alibaba and Tencent KMS gateway (pull_request) Failing after 4m53s
Build and Test Quality Gate / Python tests and Contract API migration (pull_request) Failing after 24m55s
Security Quality Gate / npm audit, Bandit, pip-audit, detect-secrets (pull_request) Failing after 8m42s
feat: deliver governed contract platform and async AI tasks
2026-08-26 12:53:47 +08:00

9.7 KiB
Raw Blame History

V2 P1-04.2 多规则 Playbook 组合候选实施与隔离 UAT 报告

日期:2026-08-23
状态:已完成,自动化、迁移、生产构建和双账号 Chrome UAT 均通过。

1. 目标与结论

本轮把 P1-04.1 的“单条规则候选版本”扩展为“一个审查快照内的多规则组合候选”,支持:

  • 对每条有兜底文本的规则逐条选择“采用”或“跳过”。
  • 跳过时强制填写原因,形成可追溯业务决定。
  • 将所有采用项按快照优先级顺序合并为一个候选合同版本。
  • 在同一个差异界面审阅组合正文和逐条决定。
  • 主动撤销候选版本,再调整选择重新生成。
  • 未经明确确认不更新当前正文;撤销、冲突均不覆盖当前正文。

验收结论:通过,可进入受控企业试点。

2. 产品状态机与业务规则

审查成功 + 多条规则有兜底文本
              |
              v
逐条决定 apply / skip(skip 必须有原因)
              |
              v
生成组合候选 candidate --------> 当前正文不变
       |              |
       |              +--------> withdrawn,当前正文不变,可重新生成
       |
       +-----------------------> conflict,停止采用并保留证据
       |
       | 审阅组合差异 + 勾选确认 + 候选 SHA-256
       v
adopted ------------------------> 候选正文成为当前正文
                                  原正文、撤销候选和逐条决定继续保留

核心约束:

  1. 请求必须覆盖快照中全部可用兜底规则,不能遗漏,也不能提交快照外规则。
  2. 至少采用一条规则;全部跳过不生成无意义候选版本。
  3. 跳过原因至少 2 个字符,并写入候选台账、审查命中结果和审计证据。
  4. 同一快照同一时刻最多保留一个待审阅候选;采用或撤销后才能重新生成。
  5. 合并顺序使用不可变快照中的规则优先级,不读取后来变化的在线规则。
  6. 生成和采用阶段均校验租户、合同状态、快照摘要、来源正文哈希、候选正文哈希和候选版本来源。
  7. 文件审查继续保持只读取证,不能自动改写上传附件。

3. 后端实施

3.1 领域模型与数据表

新增组合候选请求、逐条决定、候选项、候选聚合和撤销请求模型。新增 playbook_combined_candidates 表,保存:

  • 租户、合同、审查任务、快照 ID 和快照摘要;
  • candidate / adopted / withdrawn / conflict 状态;
  • 原正文和候选正文 SHA-256;
  • 候选合同版本 ID;
  • 已采用规则、跳过规则及原因、逐条替换次数与每步正文哈希;
  • 创建、采用、撤销的人员与时间;
  • 租户级幂等键和安全元数据。

数据库迁移为 20260823_0053,已在现有 PostgreSQL 和全新 SQLite 数据库从 0 到 head 验证。

3.2 事务与安全边界

  • 生成时锁定合同,验证成功审查、快照摘要、正文漂移和候选唯一性。
  • 禁用条款按快照记录的命中表述精确替换;其他规则按企业兜底区块追加。
  • 只新增候选合同版本,不更新 contracts.body_content。
  • 采用时再次锁定合同和候选,验证显式确认、候选哈希、版本来源和当前正文漂移。
  • 采用成功后一次性更新当前正文、版本生命周期和审查规则命中状态。
  • 撤销只更新候选与版本生命周期,不删除版本、不修改当前正文。
  • 组合候选读写全部按租户隔离;审批人等只读角色可以查看,但不能生成、撤销或采用。

3.3 API 与审计

新增接口:

  • GET /api/v1/contracts/{contract_id}/playbook-candidates
  • POST /api/v1/contracts/{contract_id}/playbook-candidates
  • POST /api/v1/contracts/{contract_id}/playbook-candidates/{candidate_id}/adopt
  • POST /api/v1/contracts/{contract_id}/playbook-candidates/{candidate_id}/withdraw

新增审计事件:

  • playbook_combined_candidate_created
  • playbook_combined_candidate_adopted
  • playbook_combined_candidate_withdrawn
  • playbook_combined_candidate_conflict

OpenAPI 已补齐全部路径、请求、响应和审计枚举,引用完整性检查为 0 个缺失引用。

4. 前端实施

  • 合同详情页在同一审查快照下展示“组合候选决策”。
  • 每条规则都有独立采用/跳过选择;选择跳过后即时显示原因输入框。
  • 缺少跳过原因或没有任何采用项时,生成按钮保持禁用。
  • 生成成功后自动打开组合差异,顶部明确显示采用数、跳过数和“当前正文尚未修改”。
  • 差异下方再次展示逐条决定,避免用户只看正文而忽略跳过项。
  • 确认采用按钮默认禁用,必须勾选“已审阅组合差异与逐条决定”。
  • 待审阅候选可填写撤销原因并撤销;撤销后保留历史版本并恢复逐条选择界面。
  • 只读审批人可打开差异,但不会渲染生成、撤销、确认或采用控件。
  • 版本面板新增组合候选生命周期标签:候选待审阅、已确认采用、已撤销、冲突已停止。
  • P1-04.1 历史单规则候选继续按原流程显示,不要求迁移或重做。

5. 隔离 Chrome UAT 证据

5.1 环境与对象

  • 租户:uat-playbook-20260823(Playbook 隔离 UAT)
  • 法务/租户管理员:uat.legal.20260823@example.test
  • 独立审批人:uat.approver.20260823@example.test
  • 合同:contract-a9323e1ded7f
  • 审查任务:review-c347f26a88e0
  • 快照:playbook-snapshot-c347f26a88e0
  • 快照摘要:b885f2c7008c793e022e0ba80a0f34580bd81a1a4cf931f665082c45ab265035
  • 规则一:approval-rule-711b817a3ac4,UAT 禁止默认转委托,v1
  • 规则二:approval-rule-a09af1c22f5e,UAT 禁止双重争议路径,v1

5.2 首个候选:采用一条、跳过一条、撤销

  • 候选:playbook-candidate-2388b453492b
  • 版本:version-256c0b9be4c6,版本号 3
  • 决定:采用规则一;跳过规则二。
  • 跳过原因:等待业务确认争议解决路径
  • 组合差异只展示规则一的替换,逐条决定同时展示一条采用和一条跳过。
  • 生成后正文预览仍显示原文,证明没有静默覆盖。
  • 撤销原因:UAT 验证逐条选择后重新组合
  • 最终状态:候选 withdrawn,版本标签“已撤销”,当前正文仍不变。

5.3 第二个候选:采用两条、跨角色审阅、明确采用

  • 候选:playbook-candidate-d85b0bc88b37
  • 版本:version-84cec7225d4c,版本号 4
  • 决定:两条规则均采用,每条精确替换 1 次。
  • 审批人账号可以打开组合差异并看到两条采用决定,但没有编辑、撤销、确认勾选或采用按钮。
  • 法务账号打开同一候选,勾选明确确认后采用。
  • 最终状态:候选 adopted,版本标签“已确认采用”。
  • 当前正文包含两条企业兜底文本,不再包含两条原禁用表述。
  • 版本历史同时保留版本 1、P1-04.1 的版本 2、已撤销版本 3 和已采用版本 4。
  • 合同审计记录完整包含两次创建、一次撤销和一次采用事件。

5.4 失败恢复附带验证

UAT 首次发起新审查时,常驻 Review Worker 尚未重启加载最新审计事件类型,读取上一阶段的候选采用审计后退出。任务被明确标记失败,随后通过页面“重新排队”恢复并成功完成,retry_count=1。这同时验证了既有 P0-07 失败重试链路。

发布要求:包含审计事件类型或领域模型变更时,Contract API 与 Review Worker 必须作为同一发布单元滚动重启,不能只热更新 Web/API 源码。

6. 自动化、契约、迁移与构建结果

  • 后端核心回归:99 项通过。
  • 新增覆盖:多规则采用/跳过、跳过原因、候选不改正文、主动撤销、重新生成、显式确认、采用、版本生命周期、跨租户 404、审批人写操作 403。
  • 前端测试:37 项通过。
  • TypeScript tsc --noEmit:通过。
  • Python compileall:通过。
  • OpenAPI YAML 解析与 $ref 完整性:通过,64 条路径、97 个 schema、0 个缺失引用。
  • PostgreSQL:20260823_0053 (head)。
  • 全新 SQLite:从 0 到 20260823_0053 完整迁移通过。
  • Next.js 生产构建:通过,114 个页面路由完成构建。
  • git diff --check:通过;仅存在仓库既有的 Windows 行尾转换提示。

非阻断告警:测试环境仍有 Starlette TestClient 上游弃用提示,以及 Windows .pytest_cache 已存在导致的缓存写入提示,不影响测试结果或运行功能。

7. 当前运行状态

  • Web:http://127.0.0.1:3000,监听中。
  • Contract API:http://127.0.0.1:8100,启用 Web 代理鉴权,监听中。
  • AI API:http://127.0.0.1:8101,监听中。
  • Review Worker:运行中。
  • Chrome:保留在法务账号的合同 contract-a9323e1ded7f 采用后验收页。

8. 已知限制与 P1-04.3 建议

  1. 精确片段替换会原样保留命中片段前后的标点;如果规则管理员在兜底文本中重复填写句号,组合结果可能出现连续标点。下一步应在规则发布前增加“样本文本试替换”和标点边界预警,但不应在采用阶段静默改写法务配置文本。
  2. 当前差异采用逐行展示,长段落内的多个短替换仍会显示整行变化。下一步可增加段内词级高亮,同时继续保留完整正文哈希取证。
  3. 当前组合候选以一个审查快照为边界。下一步可增加规则依赖/互斥校验、合并冲突矩阵和管理员规则发布前 dry-run。
  4. 建议把“API 与 Worker 同版本重启”“0053 迁移完成”“99 项后端回归”“双角色只读/编辑隔离”纳入 P1-04.2 发布门禁。

建议下一阶段进入 P1-04.3:规则发布前样本文本试运行、标点和上下文边界预警、规则依赖/互斥关系、组合冲突解释与词级差异高亮。