Files
ai-contract-platform/project-docs/V2-P1-04.1-reviewable-playbook-fallback-versions-2026-08-23.md
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

8.2 KiB
Raw Permalink Blame History

V2 P1-04.1 可审阅 Playbook 兜底合同新版本实施与 UAT 报告

日期:2026-08-23
状态:已完成,隔离 UAT 通过。

1. 目标与验收结论

P1-04.1 的目标是把企业 Playbook 兜底从“直接修改正文”升级为“生成候选版本、审阅差异、明确采用”,确保系统不会在用户没有确认的情况下静默覆盖当前合同正文。

验收结论:通过。

  • 一键生成的是独立候选版本,不会修改 contracts.body_content。
  • 候选版本自动打开原文/新文差异审阅界面。
  • “确认采用为当前正文”默认禁用,用户必须勾选明确确认。
  • 采用请求必须同时携带 confirmed=true 和已审阅的候选正文 SHA-256。
  • 当前正文、合同状态或候选摘要发生变化时,系统停止采用并转人工处理。
  • 采用成功后原正文仍保留为历史版本,可继续查看、比较和取证。

2. 两阶段状态机

审查快照命中规则
       |
       v
生成候选版本 candidate --------> 当前合同正文保持不变
       |
       | 用户打开差异、勾选确认、提交候选哈希
       v
显式采用 adopted --------------> 候选正文成为当前正文
       |
       +------------------------> 原正文继续保留在版本历史

任一状态/正文/哈希冲突 --------> conflict + 审计证据 + 人工接管

兼容既有数据:历史 succeeded 执行记录继续按已采用处理,不要求回写迁移。

3. 产品与交互改造

3.1 生成候选

  • 原“应用企业兜底文本”按钮改为“生成可审阅新版本”。
  • 一次点击完成规则快照校验、候选正文生成、候选版本落库和审计记录。
  • 生成成功后立即展示红绿差异,并明确提示“当前正文尚未修改”。
  • 关闭差异对话框后,页面显示“候选版本待审阅 / 原正文未修改”。

3.2 明确采用

  • 差异对话框同时显示原正文和候选版本的删除/新增内容。
  • 采用按钮默认禁用;只有勾选“我已审阅原正文与候选版本差异”后才可点击。
  • 用户可选择“暂不采用”,候选版本保留,当前正文不变。
  • 采用后显示“兜底版本已采用”,下一步引导为“重新发起审查验证企业兜底文本”。

3.3 版本历史

  • 候选未采用时标记“候选待审阅”。
  • 采用后标记“已确认采用”。
  • 版本列表保留原版本与候选版本,可分别查看正文并与当前版本比较。
  • 候选生成或采用后,版本面板通过页面事件立即刷新,无需用户手动刷新页面。

4. 后端安全边界

4.1 生成阶段

  • 锁定当前租户的合同记录。
  • 校验审查任务成功、快照 ID、快照摘要、规则版本和来源正文哈希。
  • 校验合同处于 draft、reviewing 或 rejected。
  • 生成 playbook_fallback_candidate 版本与执行台账,不更新当前合同正文。
  • 写入 playbook_fallback_candidate_created 审计事件,记录原文与候选正文哈希。

4.2 采用阶段

  • 新接口:POST /api/v1/contracts/{contract_id}/playbook-fallbacks/{execution_id}/adopt。
  • 仅具备合同编辑权限的账号可以调用。
  • 请求必须提交 64 位候选正文 SHA-256 和字面值为 true 的确认字段。
  • 在数据库事务中锁定合同和候选执行记录。
  • 再次校验租户、合同状态、当前正文哈希、候选版本来源和候选正文哈希。
  • 全部通过后才更新当前正文,并把候选版本标记为已采用。
  • 写入 playbook_fallback_adopted 审计事件和采用人、采用时间。

4.3 冲突与幂等

  • 候选生成使用租户级幂等键,重复请求不会重复创建版本。
  • 已采用候选再次提交采用请求时安全重放,不重复修改正文。
  • 候选生成后如果有人编辑了当前正文,采用操作返回 conflict,当前正文保持编辑后的内容。
  • 冲突记录包含 requires_manual_handoff=true、当前正文哈希和期望正文哈希。
  • 文件审查仍保持只读,不自动改写原始附件。

5. 隔离 UAT 证据

5.1 环境与账号

  • 租户:uat-playbook-20260823(Playbook 隔离 UAT)。
  • 法务/租户管理员:uat.legal.20260823@example.test。
  • 独立审批人:uat.approver.20260823@example.test。
  • 两个账号为独立用户,报告不记录密码。

5.2 验收对象

  • 合同:contract-a9323e1ded7f。
  • 标题:UAT P1-04.1 可审阅兜底版本合同。
  • 审查任务:review-045068122a21。
  • 快照:playbook-snapshot-045068122a21。
  • 快照摘要:4b66f02e671ecfbdb7fd42784aa1db2ad4020ca4654e8998530be10c0f273a4e。
  • 执行记录:playbook-fallback-c3c35c792911。
  • 候选版本:version-970c07ed14bd。
  • 最终执行状态:adopted。

5.3 Chrome 可视化验收

  1. 法务账号创建包含“承担全部且无限责任”的合同并完成 AI 审查。
  2. 页面命中租户规则 UAT 禁止无限责任,聚合快照显示 1 条可用兜底。
  3. 点击“生成可审阅新版本”后自动打开差异对话框:
    • 原无限责任表述显示为删除内容;
    • 企业兜底文本显示为新增内容;
    • 页面明确显示“当前正文尚未修改”;
    • 确认采用按钮默认禁用。
  4. 关闭差异对话框后,正文预览仍显示原无限责任表述,证明候选生成没有覆盖正文。
  5. 切换独立审批账号:
    • 可以查看候选待审阅状态和版本证据;
    • 看不到生成、审阅、采用或编辑按钮。
  6. 切回法务账号,打开候选差异并勾选确认,随后采用:
    • 当前正文切换为企业兜底文本;
    • 页面显示“兜底版本已采用”;
    • 下一步提示为重新发起审查。
  7. 版本面板显示版本 1 和版本 2:
    • 版本 2 标记“已确认采用”;
    • 打开版本 1 仍能完整看到原无限责任正文。

6. 主要实现位置

  • 状态与请求模型:yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/enterprise_playbook.py
  • 候选生成与采用事务:yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/sqlalchemy_playbook_fallback_orchestration.py
  • API 路由:yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/api/review.py
  • 数据模型:yuqei-contract-platform/services/contract-api/src/yuqei_contract_api/persistence/models.py
  • 数据库迁移:yuqei-contract-platform/services/contract-api/migrations/versions/20260823_0052_add_playbook_candidate_adoption.py
  • 前端差异与确认:yuqei-contract-platform/apps/contract-web/src/app/contracts/[id]/apply-playbook-fallback-button.tsx
  • 版本证据展示:yuqei-contract-platform/apps/contract-web/src/app/contracts/[id]/contract-version-panel.tsx
  • Web 采用代理:yuqei-contract-platform/apps/contract-web/src/app/api/contract-platform/contracts/[id]/playbook-fallbacks/[executionId]/adopt/route.ts
  • OpenAPI:yuqei-contract-platform/packages/contract-openapi/openapi.yaml

7. 自动化、迁移与构建

  • 后端核心回归:98 项通过。
  • 新增断言覆盖:候选生成不改正文、未确认请求拒绝、候选采用、采用幂等、租户隔离、审批人无编辑权限、生成前漂移冲突、生成后漂移冲突。
  • 前端测试:全部通过。
  • TypeScript 类型检查:通过。
  • Python compileall:通过。
  • OpenAPI YAML 解析:通过。
  • Next.js 生产构建:通过,114 个页面路由完成构建。
  • PostgreSQL 迁移:20260823_0052 (head)。
  • 全新 SQLite 数据库从 0 到 0052 完整迁移:通过。

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

8. 当前运行状态与下一步

  • 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 的采用后验收页面。

建议后续进入 P1-04.2:支持一次审阅多个规则候选、逐条勾选或跳过、组合差异预览,以及候选版本主动撤销;仍应保持“未经明确确认不更新当前正文”的发布门槛。