feat(ai): add tenant-safe hierarchical expense learning

This commit is contained in:
caoxiaozhu
2026-07-16 14:30:41 +08:00
parent 6bdf65bc24
commit ee88a36baf
65 changed files with 6909 additions and 232 deletions

View File

@@ -0,0 +1,7 @@
## 修复记录
- 2026-07-16 13:42:57 CST在分层记忆回归测试中发现AI 新建非 `default` 租户费用申请后会立即调用 `submit_claim()`,但此时尚未建立租户化 Expense Case Link提交服务重新查询单据时按 Case Link 执行租户过滤,因此刚创建的申请返回不可见并报“未找到可提交的申请单”。
- 2026-07-16 13:42:57 CST`UserAgentApplicationSlotMixin._create_expense_application_record()` 完成 Claim `flush` 后、进入草稿或提交分支前,使用当前认证租户同步建立 Expense Case 与 Claim Link使新建记录、租户归属和后续提交保持在同一数据库事务失败时仍由既有外层回滚不留下半成品 Case 或 Link。
- 2026-07-16 13:42:57 CST按项目规范执行 `git fetch --all --prune`、上下游状态与提交差异检查;当前分支相对 `origin/main` ahead 13未发现新的上游提交本地 ahead 包含最近的费用闭环、个人记忆、零录入票据和权威预审阶段提交。
- 2026-07-16 13:42:57 CST在 Docker 容器 `local-x-financial-linux` 内运行原失败用例、分层记忆服务与组织记忆接口测试,结果 `9 passed`;验证非默认租户申请可完成预览提交并生成学习回执,组织记忆生命周期和租户隔离未受影响。
- 影响:修复 AI 助手、Steward 和 Orchestrator 共用申请创建链路在非默认租户下无法直接提交的问题;默认租户与既有草稿事件继续复用同一 Case不改变确定性预审、预算和审批规则。

View File

@@ -0,0 +1,8 @@
## 修复记录
- 2026-07-16 14:29:13 CST组织记忆创建在“检查 active → 新建 generation”之间存在竞态后到请求可能静默压制并发产生的新版本创建、更新的幂等键也没有绑定请求内容撤销操作则无法在响应丢失后安全重试。
- 2026-07-16 14:29:13 CST为企业/部门记忆增加租户与作用域级事务锁、幂等请求锁、请求 payload 指纹和数据库唯一约束;创建、更新、撤销现在都满足“同键同内容重放、同键不同内容 409”新 generation 激活前严格核对预期 active 集合。锁协调职责拆到 `organization_memory_locks.py`,主服务从接近 800 行降至 761 行。
- 2026-07-16 14:29:13 CST加固 `20260716_0009` 迁移active 唯一索引只约束企业/部门作用域DDL 前先检测重复 active 并 fail-fast避免个人学习记忆换代受到影响非 PostgreSQL 在任何结构变更前明确拒绝,避免 SQLite 留下半迁移列。
- 2026-07-16 14:29:13 CST执行 `git fetch --all --prune`、工作区状态和上下游提交差异检查;`origin/main` 没有新增提交,当前分支 ahead 13最近本地检查点为权威提交前预审、持久化零录入票据和个人申请记忆本次未改写这些提交。
- 2026-07-16 14:29:13 CST全部验证在 `local-x-financial-linux` 内执行并设置 60 秒超时。分层与组织记忆回归 44 项、迁移/模型/租户组合 70 项通过;前端记忆与申请链路 18 项通过Vite 生产构建通过,变更 Python 文件 Ruff F/I 与 compileall 通过。一次性 tmpfs PostgreSQL 17 完整迁移循环 9 项通过,临时容器自动清理,开发数据库未修改。
- 影响:管理员并发维护组织记忆时不再发生静默覆盖,网络重试不会产生重复版本或把不同请求伪装成成功;个人记忆状态机保持原有最小样本与换代语义,迁移遇到脏数据时在写 DDL 前停止并给出明确错误。

View File

@@ -0,0 +1,9 @@
## 修复记录
- 2026-07-16 14:29:13 CST历史风险观测、few-shot 样本、Qdrant 向量和规则生成链路原先缺少完整租户、场景及制度版本边界Hermes 全局扫描还可能把不同租户的 Claim 放进同一风险图,历史检索结果若直接公开也可能泄露样本 ID、费用单号或人工评语。
- 2026-07-16 14:29:13 CST风险观测与 few-shot 关系数据改为租户复合唯一,风险接口、反馈、查询和 Hermes 图构建按认证租户隔离Qdrant 写入与检索显式携带 tenant、scene、policy_ref、rule_version使用稳定向量 ID并清理旧向量命中后再由关系库校验租户、状态和版本。风险规则生成与再生成从认证用户透传租户缺失租户时禁用历史注入而不回落到 default。
- 2026-07-16 14:29:13 CST报销预审新增只读 `historical_case_evidence`,检索或向量服务异常时降级为空证据。公开协议和 AI 助手只返回固定的“历史已确认/历史误报,仅供复核”标签与脱敏摘要,不返回 sample ID、claim_no、人工评论或历史结论原文历史证据不参与 review ID、确定性 findings、passed、blocking count、预算复核或审批路由计算。
- 2026-07-16 14:29:13 CST加固 `20260716_0008` 迁移:`RiskObservation.claim_id` 明确改为旧 Claim 表的 view-only 软引用,使空库与旧表采用路径的 Head 结构一致;降级若发现非默认租户或非空 policy/rule 版本数据则在 DDL 前 fail-fast禁止静默丢失隔离和版本信息非 PostgreSQL 在变更前明确拒绝。
- 2026-07-16 14:29:13 CST执行 `git fetch --all --prune`、工作区状态和上下游提交差异检查;`origin/main` 没有新增提交,当前分支 ahead 13最近本地检查点为权威提交前预审、持久化零录入票据和个人申请记忆本次未改写这些提交。
- 2026-07-16 14:29:13 CST全部验证在 `local-x-financial-linux` 内执行并设置 60 秒超时。历史案例、风险观测、风险图、预审和规则生成组合 90 项,报销接口与费用服务 137 项,补充 Golden/规则历史注入 28 项通过;迁移/模型/租户组合 70 项通过Ruff F/I、compileall 和 `git diff --check` 通过。一次性 tmpfs PostgreSQL 17 完整迁移循环 9 项通过,临时容器自动清理,开发数据库未修改。
- 影响:同名用户、相同样本键或相似向量不能跨租户读取、覆盖或进入 Prompt历史案例开始帮助预审与复核但只以脱敏、可降级、非决策证据存在不会扩大 AI 自动放行或审批权限。