feat(platform): close AI expense value loop
Add tenant-safe value, telemetry, connector, commercial, and production-readiness foundations.
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
## 修复记录
|
||||
|
||||
- 13:08:修复 AgentAsset 全局读写、跨租户子记录注入、风险样本串租户、审核身份伪造和 ONLYOFFICE 匿名/可重放回调问题。
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、`git status -sb`、`git log HEAD..@{u}` 和 `git log @{u}..HEAD`;`origin/main` 无新提交,本地 `main` ahead 17,工作区包含多智能体并行未提交变更且未被清理或覆盖。
|
||||
- 本地 ahead 摘要:`242d68c3` 审批任务与豁免、`28b834ed` 审批动作幂等回放、`4940ebc4` 风险处置流程、`ee88a36b` 租户安全分层学习、`6bdf65bc` 权威预审、`ae3f02c3` 零录入票据关联、`54754b55` 个人报销记忆、`211f85d9` 已验证申请工作流、`5b246307` 申请预览决策、`a662cfe6` AI 反馈账本、`5ed34c2b` 历史申请回填、`11275e4b` 迁移 ownership 安全、`1347366b` 时间线与草稿事件安全、`22669a90` 统一费用时间线、`a616b30c` AI 申请事务、`653eda05` 不透明会话、`661990b2` 费用案例事务事件。
|
||||
- 修改:为 AgentAsset、Version、Review、TestRun 和 RuleFeedback 增加结构化 `tenant_id + scope`;所有资产、发布、监控、召回、遥测、调度、foundation 和风险运行时查询接入企业/平台作用域;同编码按企业优先、平台回退解析,跨企业资源统一不可见,平台资产仅平台管理员可写。
|
||||
- 修改:真实风险场景强制显式目标企业并先按 `ExpenseClaim.tenant_id` 过滤;测试证据归目标企业;版本、审核和规则表变更主体改为登录会话中的稳定 employee/username 标识,客户端 actor/reviewer 不能覆盖审计事实。
|
||||
- 修改:新增 DB-backed ONLYOFFICE content/callback 会话和 `active → processing → consumed|failed` 原子状态机;token 绑定租户、资源、资产、document key/version/fingerprint、权限、actor、audience、时间和 JTI;平台只读、跨资产、旧版本、错 key、过期和重放回调均拒绝。
|
||||
- 修改:回调复用安全下载器,限制配置 origin,校验 DNS 全部地址并固定已验证公网 IP,拒绝重定向、超限、错误 MIME、危险 ZIP 和异常 OOXML;新增 `20260717_0026` 迁移并对无法归属的旧数据和有企业事实的 downgrade fail-closed。
|
||||
- 操作:拆出 AgentAsset access/serialization/ONLYOFFICE security 与风险规则字段推断模块;将核心文件控制在 800 行以内;补齐功能 CONCEPT/TODO 和迁移、权限、安全回归测试。
|
||||
- 验证:容器内发布/监控/召回/运行时/调度/遥测/租户安全/ONLYOFFICE 汇总 58 项通过;AgentAsset service/foundation 28 项通过;风险生成/修订/golden 49 项通过;相关文件 Ruff、py_compile、ORM mapper(84 张表)和 `git diff --check` 均通过。
|
||||
- 验证:一次性 PostgreSQL 探针完成旧平台数据升级、同编码多企业、scope/check、跨租户复合外键和有事实 downgrade 保护;新库 `base → head(0028)` 与 `head → 0025 → head` 均成功,AgentAsset 与 Knowledge ONLYOFFICE 会话表正常创建。
|
||||
- 影响:企业只能读取本企业和平台只读资产,无法观察或修改其他企业的资产、版本、审核和测试证据;规则测试不会抽取其他企业费用;审计身份不可由请求伪造;文档回写失败时保持原文件不变,也不会向任意或内部地址发起下载。
|
||||
@@ -0,0 +1,10 @@
|
||||
## 修复记录
|
||||
|
||||
- 13:40:修复 0026 Agent 资产租户安全迁移在真实历史建表路径下无法完整回退的问题。
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、`git status -sb`、`git rev-parse --abbrev-ref --symbolic-full-name @{u}`、`git log HEAD..@{u}` 和 `git log @{u}..HEAD`;`origin/main` 无新提交,本地 `main` ahead 17,工作区包含多智能体并行变更,未合并、覆盖或提交。
|
||||
- 本地 ahead 摘要:17 个提交覆盖审批任务与幂等回放(`242d68c3`、`28b834ed`、`4940ebc4`)、租户安全费用学习/预审/票据关联/申请记忆与反馈(`ee88a36b`、`6bdf65bc`、`ae3f02c3`、`54754b55`、`211f85d9`、`5b246307`、`a662cfe6`)、历史回填与迁移安全(`5ed34c2b`、`11275e4b`)、费用时间线与事务(`1347366b`、`22669a90`、`a616b30c`、`661990b2`)及不透明认证会话(`653eda05`)。
|
||||
- 根因:空库先经过 0026 时 Agent 资产旧表尚不存在,迁移会按设计跳过这些表;之后旧表由当前模型补建,PostgreSQL 为列级租户外键生成 `*_tenant_id_fkey`,而 0026 回退硬编码删除 `fk_*_tenant`,首个 `agent_asset_rule_feedback` 约束不存在即中断。
|
||||
- 修改:`20260717_0026_agent_asset_tenant_security.py` 新增带 PostgreSQL 标识符引用的约束安全删除器,0026 回退对它负责的复合外键、租户外键、范围检查和唯一约束统一使用 `DROP CONSTRAINT IF EXISTS`;升级路径与最终升级约束保持不变,模型自动命名的列级外键仍随租户列删除安全清理。
|
||||
- 操作:在 `financial-internal` 网络启动独立 `postgres:16-alpine` 一次性数据库,使用应用容器和项目 venv 执行真实 Alembic 循环;验证结束后停止探针,并确认 `--rm` 已删除容器。
|
||||
- 验证:相关 Ruff 检查通过;PostgreSQL-only 迁移防误用测试 42 项通过;一次性 PostgreSQL 上的完整迁移循环 1 项通过(7.00 秒),覆盖空库升级至 0028、回退至 0008、再次升级、完整回退至 base、最终再次升级至 0028,同时验证约束存在与缺失两种删除路径。
|
||||
- 影响:真实历史路径与当前模型补建路径都能安全回退 0026;缺少迁移命名约束时不再失败,已有约束仍被正常移除,且不会改变 head 升级结构。
|
||||
@@ -0,0 +1,8 @@
|
||||
## 修复记录
|
||||
|
||||
- 13:25:记录 bug 修复:未配置商业计量器时独立 SQLite Session 回滚调用方事务。
|
||||
- Git 提交检查:执行 `git fetch --all --prune` 后,`HEAD..origin/main` 无新提交;本地 `main` ahead 17 个既有提交,依次为 `242d68c3` 审批任务与豁免、`28b834ed` 审批幂等响应、`4940ebc4` 风险处置、`ee88a36b` 分层费用学习、`6bdf65bc` 权威预审、`ae3f02c3` 票据零入口归集、`54754b55` 个人申请记忆、`211f85d9` 申请流程统一、`5b246307` 预览决策、`a662cfe6` 反馈账本、`5ed34c2b` 历史费用 Case 回填、`11275e4b` migration ownership、`1347366b` 时间线与草稿事件、`22669a90` 费用时间线、`a616b30c` AI 申请提交事务、`653eda05` bearer session、`661990b2` 费用 Case 事务事件;这些提交均早于本轮且未改写。
|
||||
- 修改:`commercial_direct_operation.py` 增加调用方 `lookup_session` 的只读未配置短路,OCR、RuntimeChat、金融连接器和附件 observer 均显式传入当前 Session。这样没有计量器时不再创建第二个 Session,也不会在 SQLite `StaticPool` 共用连接上意外 rollback 已 flush 的费用明细。
|
||||
- 操作:先用附件归集回归复现 `expense_claim_items expected to update 1 row; 0 were matched`,再将未配置判断前移到调用方 Session;保留真正配置计量器时的独立事务预占与结算。
|
||||
- 验证:容器内附件归集与票据夹 `31 passed`;商业资源边界 `9 passed`;报销端点与连接器组合 `38 passed`;相关 Ruff 通过。
|
||||
- 影响:未启用商业计量的开发、测试和兼容租户不再因为商业探测破坏调用方事务;生产 PostgreSQL 的独立商业事务语义保持不变。
|
||||
@@ -0,0 +1,8 @@
|
||||
## 修复记录
|
||||
|
||||
- 13:25:记录 bug 修复:业务回滚释放预占后相同请求无法安全重试。
|
||||
- Git 提交检查:执行 `git fetch --all --prune` 后,`HEAD..origin/main` 无新提交;本地 `main` ahead 17 个既有提交,依次为 `242d68c3` 审批任务与豁免、`28b834ed` 审批幂等响应、`4940ebc4` 风险处置、`ee88a36b` 分层费用学习、`6bdf65bc` 权威预审、`ae3f02c3` 票据零入口归集、`54754b55` 个人申请记忆、`211f85d9` 申请流程统一、`5b246307` 预览决策、`a662cfe6` 反馈账本、`5ed34c2b` 历史费用 Case 回填、`11275e4b` migration ownership、`1347366b` 时间线与草稿事件、`22669a90` 费用时间线、`a616b30c` AI 申请提交事务、`653eda05` bearer session、`661990b2` 费用 Case 事务事件;这些提交均早于本轮且未改写。
|
||||
- 修改:`commercial_runtime_reservations.py` 在相同指纹、相同订阅/权益/账期下允许 `released → reserved`,重开时重新锁定合同、校验 meter 快照并执行硬配额判断;跨账期重试继续失败关闭。
|
||||
- 操作:补充 Direct operation 的 not-sent 后重试测试,并把金融连接器“业务 rollback 后同一外部事件重试并提交”加入资源边界回归。
|
||||
- 验证:容器内 Direct + 商业资源组合 `22 passed`,商业资源边界 `9 passed`;回滚阶段无 usage,重试提交后仅一个 usage 且预占终态为 committed。
|
||||
- 影响:数据库瞬时失败或显式回滚不再把同一幂等业务请求永久卡在 released;重试仍受当前硬配额和账期约束,不会绕过额度。
|
||||
@@ -0,0 +1,13 @@
|
||||
# 员工导入与成员资格部分提交
|
||||
|
||||
日期:2026-07-17
|
||||
文档路径:document/development/2026-07-17/dev-logs/bugs/employee-import-membership-transaction.md
|
||||
|
||||
## 修复记录
|
||||
- 14:07:记录 bug 修复:员工导入与成员资格部分提交。(bug-log:242d68c3)
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、状态、upstream 和双向日志检查;`origin/main` 无新提交,本地 `main` ahead 17。ahead 摘要:17 个提交覆盖审批/风险处置、租户安全费用学习、权威预审、票据关联、个人记忆、历史回填、迁移安全、费用事件事务和不透明认证会话;本轮未改写这些提交。
|
||||
- 根因:`EmployeeImportCoordinator._apply_import_rows()` 在写员工和上级关系后先 commit,`EmployeeService.import_employees()` 才补 `TenantMembership` 并第二次 commit;成员资格失败时接口报错,但员工已永久落库。
|
||||
- 修改:协调器只 flush 员工、角色、组织、上级和变更日志,不再拥有 commit;外层服务仅在成功结果后补齐租户成员资格,并对两部分执行一次统一 commit,任一异常统一 rollback。
|
||||
- 操作:新增成员资格同步注入失败测试,导入新员工后故意抛错并验证员工记录不存在;校验失败结果不触发成员资格或无意义提交。
|
||||
- 验证:容器内员工服务、导入、认证和行为画像 35 项通过;差旅计算器 5 项通过;目标 Ruff、format check、compileall、代码体积门禁和 `git diff --check` 通过。
|
||||
- 影响:员工批量导入现在满足“全部员工数据与认证成员资格一起成功或一起失败”,不会出现接口失败但部分账号已经创建/修改的状态。
|
||||
@@ -0,0 +1,11 @@
|
||||
## 修复记录
|
||||
|
||||
- 13:19:修复用户会话结算测试身份错配、缓存命中后旧部门不再归一化,以及 Excel 导入清空上级时误清空员工租户的问题。
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、`git status -sb`、`git log HEAD..@{u}` 和 `git log @{u}..HEAD`;`origin/main` 无新提交,本地 `main` ahead 17,工作区仍包含多智能体并行变更,未做清理、覆盖或提交。
|
||||
- 本地 ahead 摘要:17 个提交覆盖审批任务与幂等回放(`242d68c3`、`28b834ed`、`4940ebc4`)、租户安全费用学习/预审/票据关联/申请记忆与反馈(`ee88a36b` 至 `a662cfe6`)、历史回填与迁移安全(`5ed34c2b`、`11275e4b`)、费用时间线/事务(`1347366b`、`22669a90`、`a616b30c`、`661990b2`)及不透明认证会话(`653eda05`)。
|
||||
- 修改:会话结算正向用例改用会话真实所有者认证,保留服务端 username ownership 校验;新增其他用户不能关闭该会话的反向测试,避免用放宽授权掩盖 `durationMs=0`。
|
||||
- 修改:目录建表/种子初始化继续按 bind 与租户缓存,但缓存命中时仍以租户过滤查询旧部门编码并持久化映射到规范部门;不再因初始化缓存永久跳过外部同步产生的旧编码。
|
||||
- 修改:Employee 与 OrganizationUnit 的复合租户关系只把 `organization_unit_id`、`manager_id` 标记为 SQLAlchemy 可同步外键,`tenant_id` 只参与关联过滤;清空部门或上级不会再把员工租户写成 `NULL`,数据库复合外键仍阻止跨租户关联。
|
||||
- 测试:补充会话所有权反例、导入后 `tenant_id/manager_id` 持久化断言,以及旧部门归一化后租户与数据库组织归属断言。
|
||||
- 验证:容器内三个原失败点与新增反例 4 项通过;员工服务、Excel 导入、行为画像/会话和认证会话相关回归 31 项通过;ORM mapper 确认关系同步列仅为 `organization_unit_id/manager_id`;相关文件 Ruff 与 `git diff --check` 均通过。
|
||||
- 影响:会话时长能在正确登录主体下正常结算,其他用户仍不能关闭该会话;旧组织编码会持续收敛到标准部门;员工导入或资料更新清空上级/部门时不会破坏不可为空的租户归属。
|
||||
@@ -0,0 +1,13 @@
|
||||
# 报销审批身份解析跨租户串读
|
||||
|
||||
日期:2026-07-17
|
||||
文档路径:document/development/2026-07-17/dev-logs/bugs/expense-claim-approver-tenant-isolation.md
|
||||
|
||||
## 修复记录
|
||||
- 13:48:记录 bug 修复:报销审批身份解析跨租户串读。(bug-log:242d68c3)
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、`git status -sb`、upstream 解析及双向日志检查;`origin/main` 无新提交,本地 `main` ahead 17。ahead 摘要:`242d68c3/28b834ed/4940ebc4` 为审批任务、不可变回放和风险处置,`ee88a36b/6bdf65bc/ae3f02c3/54754b55/211f85d9/5b246307/a662cfe6` 为租户安全费用学习、预审、票据关联、个人记忆和申请反馈,`5ed34c2b/11275e4b` 为历史回填与迁移安全,`1347366b/22669a90/a616b30c/661990b2` 为费用时间线及事务,`653eda05` 为不透明会话;本轮未改写这些提交。
|
||||
- 修改:`expense_claim_access_policy.py` 的当前员工、申请人、直属领导、部门预算负责人和财务负责人解析全部先绑定认证用户或报销单的结构化 `tenant_id`;员工、组织和下属子查询增加租户首层谓词,避免相同姓名、邮箱前缀、部门或角色在另一企业命中。
|
||||
- 修改:把身份候选、申请人回填和唯一姓名判断拆入 `expense_claim_employee_resolver.py`,保持公开策略 API 不变,并将访问策略主文件降到 701 行;无可信租户、跨租户关联或结构化归属冲突统一失败关闭。
|
||||
- 操作:同步补齐审批任务、风险并发、层级记忆和报销测试夹具的显式企业归属;没有放宽生产授权,也没有用默认企业兼容掩盖跨租户错误。
|
||||
- 验证:容器内 `test_expense_claim_service.py` 121 项通过,访问策略文件大小与租户作用域定向 10 项通过;审批任务、PostgreSQL 并发与全量后端分片均通过,fresh PostgreSQL 专项最终 `87 passed / 0 skipped / 0 failed`;新 Python 文件 Ruff 和 `git diff --check` 通过。
|
||||
- 影响:审批队列、审批人快照、退回/通过权限和历史回填不会再因另一企业存在同名员工或同名部门而串租户;多租户环境下报销审批保持可解释且失败关闭。
|
||||
@@ -0,0 +1,8 @@
|
||||
## 修复记录
|
||||
|
||||
- 13:33:记录 bug 修复:财务驾驶舱租户安全测试仍按旧 Case Link 契约构造报销单。
|
||||
- Git 提交检查:`git fetch --all --prune` 后未发现 upstream 新提交;本地相对 `origin/main` ahead 17 个既有提交,分别为 `242d68c3` 审批任务工作流、`28b834ed` 不可变响应重放、`4940ebc4` 风险处置工作流、`ee88a36b` 租户安全分层费用学习、`6bdf65bc` 权威预审、`ae3f02c3` 零录入票据关联、`54754b55` 个人申请记忆、`211f85d9` 申请工作流统一、`5b246307` 申请预览决策、`a662cfe6` 反馈账本、`5ed34c2b` 历史 Expense Case 回填、`11275e4b` 迁移所有权安全、`1347366b` 时间线与草稿事件安全、`22669a90` 统一事件时间线、`a616b30c` AI 申请事务统一、`653eda05` 不透明 bearer 会话、`661990b2` 事务化 Expense Case 事件;本次未改写这些提交。
|
||||
- 修改:`test_finance_dashboard_tenant_security.py` 的 Claim 构造器显式接收并写入 `tenant_id`,租户夹具不再只依赖历史 `ExpenseCaseLink`;新增“结构化 Claim 租户与旧 Link 不一致时以 Claim 为准”的隔离回归。
|
||||
- 操作:先在容器内单跑复现 3 个失败,确认不是测试顺序或全局 monkeypatch 污染,再执行最小夹具修复并串行复跑财务、连接器与 Hermes 相邻测试组。
|
||||
- 验证:单文件 `8 passed`;排序相邻组 `67 passed, 4 skipped`;目标文件 Ruff 检查与 `git diff --check` 均通过。
|
||||
- 影响:财务驾驶舱测试与新的结构化租户模型保持一致,同时固定了旧关联索引不能移动报销单租户归属的安全边界;生产 fail-close 与首条 SQL 租户过滤没有放宽。
|
||||
@@ -0,0 +1,13 @@
|
||||
# 财务连接器运行事件计数与固定时钟偏差
|
||||
|
||||
日期:2026-07-17
|
||||
文档路径:document/development/2026-07-17/dev-logs/bugs/financial-connector-operational-counting-clock.md
|
||||
|
||||
## 修复记录
|
||||
|
||||
- 11:39:记录 bug 修复:财务连接器相同载荷的不同运行尝试被永久合并,固定时钟场景的接收时间偏离观测窗口。
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`;upstream `origin/main` 无新提交;本地 ahead 17 条,包含 `242d68c3 feat(approval): add task workflow and waiver decisions`、`28b834ed fix(approval): replay immutable action responses`、`4940ebc4 feat(approval): add safe risk disposition workflow`、`ee88a36b feat(ai): add tenant-safe hierarchical expense learning` 等共享工作区既有提交,本次未改写这些提交。
|
||||
- 修改:`financial_connector_operational_events.py` 把规范化 UTC 发生时间纳入运行事实幂等命名空间,使同一 candidate 的补偿重试保持单条、不同 HTTP 尝试分别计数;`financial_connector_ingestion.py` 让注入的可信 `now_epoch` 同时驱动接收时间和配置健康时间;`financial_connector_observability.py` 统一把数据库时间规范为 UTC,避免 SQLite/驱动返回 naive datetime 时窗口结果不稳定。
|
||||
- 操作:补充运行事实服务、HTTP 冲突、可信认证归属、敏感原值不落库和 PostgreSQL 并发探针;所有 Python、pytest、Ruff 与迁移操作均在 `local-x-financial-linux` 容器中执行,PostgreSQL 验证使用新建的一次性 `disposable-probe` 容器,没有连接项目配置中的外部数据库。
|
||||
- 验证:容器内连接器与迁移前置定向 `115 passed`,全新 PostgreSQL 17 完整迁移循环 `51 passed`,连接器并发 `4 passed`,后继 0023 并发 `7 passed`;相关 Ruff 和 `git diff --check` 通过。
|
||||
- 影响:可观测性不会再把多次真实重放压成一次,也不会因测试/模拟可信时钟与实际系统日期不同而漏掉事件;同一补偿 candidate 仍由数据库唯一约束保证幂等。
|
||||
@@ -0,0 +1,8 @@
|
||||
## 修复记录
|
||||
|
||||
- 13:15:修复本体参考目录、员工画像、Hermes 扫描/看板/提醒、财务报告和内部 Orchestrator 的跨租户读取与错误归属风险。
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、`git status -sb`、`git log HEAD..@{u}` 和 `git log @{u}..HEAD`;`origin/main` 无新增提交,本地 `main` ahead 17。ahead 摘要:`242d68c3/28b834ed/4940ebc4` 审批与风险处置,`ee88a36b/54754b55/211f85d9/5b246307/a662cfe6` AI 费用学习与申请流程,`6bdf65bc/ae3f02c3/5ed34c2b/1347366b/22669a90/a616b30c/661990b2` 费用预审、费用事件与时间线,`11275e4b` migration ownership,`653eda05` opaque bearer session;本轮未改写这些提交。
|
||||
- 修改:本体解析在模型前创建租户化 Agent Run,并对员工、组织、费用、应收、应付和项目目录首 SQL 过滤;员工画像新增租户字段、复合员工外键和本人/直属领导/财务/高管/管理员访问矩阵;Hermes 风险、画像、线索、提醒和看板逐租户运行;财务报告按企业配置收件人、内容、路径和幂等账本;内部 Orchestrator 缺失、停用、不存在或冲突租户时在建 Run 前拒绝。
|
||||
- 操作:新增 `20260717_0028` 迁移和租户财务报告配置/运行表;upgrade/downgrade 在任何 DDL 前拒绝非 PostgreSQL;完成 fresh、旧结构回填、回滚重升及复合外键 PostgreSQL 探针,验证后停止并自动清理一次性探针容器。
|
||||
- 验证:容器内新增安全/提醒测试 9 项、旧本体与 Orchestrator 88 项、Hermes/看板/财务报告 8 项、画像/鉴权/关联草稿 25 项通过;Alembic 静态回归 61 项通过、1 项因未提供外部 PostgreSQL DSN 跳过;相关文件 Ruff check/format check 和 `git diff --check` 通过。
|
||||
- 影响:企业 A 的模型提示词、员工画像、风险扫描、提醒、看板、报告附件和邮件收件人不再包含企业 B 数据;无可信租户的内部任务不能生成不可归属记录;历史无双租户快照的 Run 不会被企业看板错误统计。
|
||||
@@ -0,0 +1,8 @@
|
||||
## 修复记录
|
||||
|
||||
- 12:45:修复知识文件、元数据与 LightRAG/Qdrant 全局共享导致的跨租户串读和覆盖风险。
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、`git status -sb`、`git log HEAD..@{u}` 和 `git log @{u}..HEAD`;upstream 无新提交,本地 `main` ahead 17,包含 `242d68c3`、`28b834ed`、`4940ebc4`、`ee88a36b`、`11275e4b`、`653eda05` 等既有审批、AI、迁移与鉴权提交,本次未改写或合并这些提交。
|
||||
- 修改:新增 tenant/platform 存储作用域,把文件、`.index.json`、`.lightrag`、运行时缓存和 Qdrant workspace 分区;旧全局制度无损复制到平台只读层;知识 API、同步、Orchestrator 查询和后台索引统一从认证用户或数据库 Agent Run 获取可信 tenant。
|
||||
- 操作:按职责拆出 scope、index state 和 RAG scoring 小模块;删除知识文件工具中已废弃的弱 ONLYOFFICE token 代码;所有命令在 Docker 容器 `local-x-financial-linux` 的 `/app` 下运行,未提交、未推送、未删除旧知识资料。
|
||||
- 验证:容器内租户隔离 6 项、既有知识回归 31 项和相关 Agent Run/鉴权 20 项通过;目标 Ruff 与 compileall 通过。
|
||||
- 影响:租户只能看到和操作自己的知识数据,并可读取平台只读制度;RAG 本地状态、缓存和向量 workspace 不再跨企业复用,缺 tenant 时统一 fail-closed。
|
||||
@@ -0,0 +1,8 @@
|
||||
## 修复记录
|
||||
|
||||
- 12:45:修复匿名 ONLYOFFICE 回调可重放、可跨资源覆盖并可借下载 URL 发起 SSRF 的高风险问题。
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、`git status -sb`、`git log HEAD..@{u}` 和 `git log @{u}..HEAD`;upstream 无新提交,本地 `main` ahead 17,既有提交未被改写。
|
||||
- 修改:新增 DB-backed 一次性会话与 `20260717_0027` 迁移;token 绑定租户、资源、文档、key、版本、权限、audience、过期时间和 JTI;预览禁止写入,编辑回调原子 claim 后只能消费一次;下载器拒绝错误 origin、私网/回环/链路本地解析、DNS 重绑定、重定向、超限、错误 MIME 和异常 OOXML。
|
||||
- 操作:把 content/callback 解析与网络下载从主 KnowledgeService 拆出;content token 保持短时,callback session 默认 4 小时;失败会话记录受控原因且原文件保持不变。
|
||||
- 验证:容器内 ONLYOFFICE 租户安全 8 项通过,覆盖平台只读、错 key 不 claim、过期、成功单次回写、重放、SSRF、IP pinning、大小/MIME/OOXML;迁移/preflight/ownership 163 项通过、1 项静态套件因未配置测试 DSN 跳过;共享 PostgreSQL 探针另完成 `base → 0028` 与 `0028 → 0025 → 0028`,Knowledge/AgentAsset 会话表均正常落库。
|
||||
- 影响:未签名、过期、跨租户、跨文档、旧版本、只读和重放回调均不能覆盖文件;文档服务下载失败时安全拒绝,不向内部网络或任意 URL 发请求。
|
||||
@@ -0,0 +1,8 @@
|
||||
## 修复记录
|
||||
|
||||
- 12:45:修复知识索引调度器使用默认租户、后台线程信任传入上下文导致任务错误归属的问题。
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、`git status -sb`、`git log HEAD..@{u}` 和 `git log @{u}..HEAD`;upstream 无新提交,本地 `main` ahead 17,既有提交未被改写。
|
||||
- 修改:调度器查询租户注册表并逐个处理 `status=active` 的租户;无活跃租户时跳过;内部 Hermes 身份显式携带 tenant;索引 worker 从数据库 Agent Run 的 route/ontology 重新取得并比对 tenant,拒绝缺失或冲突上下文。
|
||||
- 操作:同步任务、活跃任务复用、stale 状态回收和 ingest 状态写入均绑定当前 tenant,不再构造无作用域 KnowledgeService。
|
||||
- 验证:容器内 active/suspended 调度隔离、Agent Run tenant 冲突、知识同步和既有知识组合测试通过;扫描全部 `KnowledgeService`/`KnowledgeRagService` 调用点,生产代码仅保留显式 tenant 或显式 platform 构造。
|
||||
- 影响:定时知识任务不会再落入默认企业或把一个租户的文档写进另一个租户的索引;后台参数被篡改或丢失时任务 fail-closed。
|
||||
@@ -0,0 +1,12 @@
|
||||
# 后台报销与 Steward 可信租户上下文缺失
|
||||
|
||||
日期:2026-07-17
|
||||
文档路径:document/development/2026-07-17/dev-logs/bugs/steward-linked-reimbursement-tenant-context.md
|
||||
|
||||
## 修复记录
|
||||
- 02:09:记录 bug 修复:后台报销与 Steward 可信租户上下文缺失。(bug-log:242d68c3)
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`;upstream `origin/main` 无新提交;本地 ahead 17 条,包含 `242d68c3 feat(approval): add task workflow and waiver decisions`、`28b834ed fix(approval): replay immutable action responses`、`4940ebc4 feat(approval): add safe risk disposition workflow`、`ee88a36b feat(ai): add tenant-safe hierarchical expense learning` 等共享工作区既有提交,本次未改写这些提交。
|
||||
- 修改:`linked_reimbursement_draft_jobs.py` 将已认证 `current_user` 显式传给 Orchestrator,避免后台 AgentRun 丢失 tenant;`steward.py` 为 plans、slot-decisions、runtime-decisions、plans/stream 注入认证用户,用登录态覆盖 payload 身份字段,并补充会话归属校验和申请候选单租户过滤;对应测试覆盖未认证、空 tenant、伪造 tenant、跨租户会话及候选单隔离。
|
||||
- 操作:所有静态检查和测试均在 Docker 容器 `local-x-financial-linux` 的 `/app` 下执行;没有修改 commercial、迁移、连接器、AI 发布或 Savings 代码,也没有提交或推送。
|
||||
- 验证:容器内定向 pytest 两组共 54 项通过;Ruff 排除目标旧文件既有 E501 长行后全部规则通过。完整 Ruff 仍报告目标旧文件历史 E501,不涉及本次新增安全逻辑。
|
||||
- 影响:后台报销任务不再因漏传登录态落入缺失/default tenant;四类 Steward AI 入口统一要求登录,客户端伪造 tenant、用户或权限字段不能覆盖服务端身份,跨租户会话和申请候选单读取会 fail-closed。
|
||||
@@ -0,0 +1,13 @@
|
||||
# 差旅计算器员工解析跨租户命中
|
||||
|
||||
日期:2026-07-17
|
||||
文档路径:document/development/2026-07-17/dev-logs/bugs/travel-calculator-employee-tenant-isolation.md
|
||||
|
||||
## 修复记录
|
||||
- 14:07:记录 bug 修复:差旅计算器员工解析跨租户命中。(bug-log:242d68c3)
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、状态、upstream 和双向日志检查;`origin/main` 无新提交,本地 `main` ahead 17。ahead 摘要:`242d68c3/28b834ed/4940ebc4` 为审批与风险处置,`ee88a36b` 至 `a662cfe6` 为费用学习/预审/票据/记忆闭环,`5ed34c2b/11275e4b` 为回填和迁移安全,`1347366b/22669a90/a616b30c/661990b2` 为费用事件与事务,`653eda05` 为认证会话;本轮未改写这些提交。
|
||||
- 根因:差旅计算器按邮箱、工号或姓名查员工时没有租户谓词,也忽略认证上下文的 `employee_id/employee_no`;员工身份现为租户内唯一,不同企业可以合法存在相同值,首条命中会把另一企业职级和办公城市带入计算。
|
||||
- 修改:`travel_reimbursement_calculator.py` 先校验可信 `tenant_id`,将 `employee_id` 加入最高优先候选,所有 ID/邮箱/工号/姓名查询都以 `Employee.tenant_id` 为首层条件。
|
||||
- 操作:新增两企业相同邮箱、工号和姓名的反向测试,故意先插入另一企业员工,确认当前登录企业的 employee ID、职级和地点始终胜出。
|
||||
- 验证:容器内差旅计算器 5 项通过;员工服务、导入、认证和行为画像 35 项通过;目标 Ruff、format check、compileall、代码体积门禁和 `git diff --check` 通过。
|
||||
- 影响:差旅住宿、补助和交通估算不会再读取另一企业员工的职级或办公地点;无合法租户时直接失败关闭。
|
||||
@@ -0,0 +1,13 @@
|
||||
# 差旅计算器只读流程触发规则资产提交
|
||||
|
||||
日期:2026-07-17
|
||||
文档路径:document/development/2026-07-17/dev-logs/bugs/travel-calculator-rule-sync-transaction.md
|
||||
|
||||
## 修复记录
|
||||
- 13:48:记录 bug 修复:差旅计算器只读流程触发规则资产提交。(bug-log:242d68c3)
|
||||
- Git 提交检查:已执行 `git fetch --all --prune`、`git status -sb`、upstream 解析及双向日志检查;`origin/main` 无新提交,本地 `main` ahead 17。ahead 摘要:`242d68c3/28b834ed/4940ebc4` 为审批与风险处置,`ee88a36b` 至 `a662cfe6` 为 AI 费用学习和申请闭环,`5ed34c2b/11275e4b` 为历史回填与迁移安全,`1347366b/22669a90/a616b30c/661990b2` 为费用事件与事务,`653eda05` 为认证会话;本轮未改写这些提交。
|
||||
- 根因:差旅计算器为读取规则先调用 `AgentAssetService.list_assets()`,该入口可能执行资产初始化并提交共享 Session,导致外层报销事务被提前提交;同时规则目录未带认证企业,企业覆盖规则可能退回到错误的全局目录。
|
||||
- 修改:`travel_reimbursement_calculator.py` 删除计算路径中的资产同步调用,改为使用当前 Session 和认证用户 `tenant_id` 直接只读加载 `ExpenseRuleRuntimeService` 目录;规则初始化只保留在启动/管理边界,不再混入金额计算事务。
|
||||
- 操作:保留地点、职级、住宿、补助和交通估算算法,仅收紧规则读取的事务与租户边界;测试夹具同步补齐结构化企业身份。
|
||||
- 验证:容器内差旅计算器 4 项金额、地区拒绝和地点归一化回归通过;AgentAsset service/foundation 28 项、报销服务 121 项及后端全量分片通过;相关新文件 Ruff、compileall 和 `git diff --check` 通过。
|
||||
- 影响:用户计算差旅标准时不会意外提交正在编辑的报销单;企业规则按当前登录企业解析,读取失败会明确报错而不会静默使用另一企业或全局可写状态。
|
||||
Reference in New Issue
Block a user