# Agent 资产多租户隔离与安全规则编辑 开发 TODO

更新时间：2026-07-17

关联方案：[CONCEPT.md](./CONCEPT.md)

## 使用规则

- 任务边界、信任模型、数据归属和上线约束以 CONCEPT 对应章节为准。
- `[x]` 只表示已有代码或容器验证证据；生产环境尚未验证的项目保持 `[ ]`。
- 所有后端测试必须在 `local-x-financial-linux` 容器内执行，单命令最长 60 秒。

## 1. 调研与边界

- [x] [CONCEPT: 背景与问题] 盘点 AgentAsset、版本、审核、测试、反馈、发布和规则表编辑中的无租户/弱租户查询。证据：repository、service、endpoint 和 release 全链路调用扫描。
- [x] [CONCEPT: 目标与非目标] 冻结“企业资产可写 + 平台资产只读 + 企业覆盖平台”的双层模型。证据：`AgentAssetAccessScope` 与两企业同编码测试。
- [x] [CONCEPT: 权限与信任边界] 冻结可信租户只来自登录会话、客户端 tenant/actor/reviewer 不能覆盖事实。证据：认证依赖、稳定主体函数和伪造头测试。

## 2. 契约与设计

- [x] [CONCEPT: 数据] 为 Asset、Version、Review、TestRun、Feedback 定义 `tenant_id + scope`、约束和索引。证据：模型与 `20260717_0026`。
- [x] [CONCEPT: 资产解析顺序] 定义企业同编码资产优先、平台资产回退的确定性加载顺序。证据：scoped repository 和 runtime loader 测试。
- [x] [CONCEPT: ONLYOFFICE 状态机] 定义 `active → processing → consumed|failed`，以及过期、撤销和重放拒绝。证据：Session 模型、迁移与 callback 测试。
- [x] [CONCEPT: 风险场景测试] 定义显式 `target_tenant_id` 与 TestRun 证据企业，不允许默认或全局样本。证据：scenario schema/service 测试。

## 3. 后端实现

- [x] [CONCEPT: 后端职责] 所有 AgentAsset 列表、详情和 code 查询接入结构化可见谓词。证据：`agent_asset.py` repository 与 `agent_assets.py`。
- [x] [CONCEPT: 权限与信任边界] 资产写入、版本和审核接入 RuleEditor/RuleReviewer/平台管理员依赖。证据：AgentAsset 和风险规则 endpoints。
- [x] [CONCEPT: 权限与信任边界] 用 `employee:{id}` 或归一化 `username:{name}` 替代请求 actor/reviewer。证据：`stable_user_principal()` 与审计断言。
- [x] [CONCEPT: 后端职责] 发布门禁、评审、监控、召回、遥测、调度和处置标签均接入租户作用域。证据：8 个 release 定向测试文件。
- [x] [CONCEPT: 后端职责] foundation/bootstrap 只查平台 seed，避免修改同编码企业资产。证据：foundation helper 拆分与回归测试。
- [x] [CONCEPT: 后端职责] 风险运行时按企业优先、平台回退加载规则，禁止跨企业版本。证据：expense runtime/loader 改造。
- [x] [CONCEPT: 风险场景测试] 场景请求校验目标企业，并将 `ExpenseClaim.tenant_id` 作为 SQL 第一层谓词。证据：真实样本场景与 TestRun 断言。
- [x] [CONCEPT: ONLYOFFICE 状态机] 新增持久化 content/callback token、原子 claim 和终态处理。证据：`agent_asset_onlyoffice_security.py`。
- [x] [CONCEPT: 权限与信任边界] content/callback 按会话重建 machine scope，拒绝跨企业、跨资产、跨版本和平台只读回写。证据：ONLYOFFICE 安全测试。
- [x] [CONCEPT: 降级与回滚策略] 复用安全下载器，拒绝错误 origin、非公网 DNS、重定向、超限及异常 OOXML。证据：下载器单测与 callback 回归。
- [x] [CONCEPT: 数据] 新增 `20260717_0026`，完成旧平台数据回填、约束、索引和有事实 downgrade 保护。证据：迁移文件与 PostgreSQL 探针。

## 4. 代码结构

- [x] [CONCEPT: 后端职责] 将访问策略、ONLYOFFICE 安全和序列化从大型 AgentAsset service 中拆出。证据：新增小职责模块，核心文件均低于 800 行。
- [x] [CONCEPT: 后端职责] 将风险规则字段推断/草稿对齐从生成主服务抽到独立模块。证据：`risk_rule_generation.py` 619 行、`risk_rule_generation_fields.py` 272 行。
- [x] [CONCEPT: 后端职责] foundation 按资产 helper、seed、topup、财务规则和电子员工任务拆分。证据：拆分模块与 28 项定向回归。

## 5. 前端契约

- [x] [CONCEPT: 前端契约] 后端 DTO 已返回 `tenantId/scope`，客户端可识别平台只读资产。证据：schema 与 AgentAsset API 回归。
- [x] [CONCEPT: 前端契约] ONLYOFFICE 配置按权限返回 view/edit，平台资产仅平台管理员可编辑。证据：config 单测与平台回写拒绝测试。
- [x] [CONCEPT: 目标与非目标] 本切片不做 Agent 资产管理页面视觉重构。证据：CONCEPT 非目标。

## 6. 测试与验证

- [x] [CONCEPT: 测试方案] 完成租户可见性、企业覆盖平台、无上下文平台只读、跨租户 404、目标企业场景和稳定身份测试。证据：`test_agent_asset_tenant_security.py`。
- [x] [CONCEPT: 测试方案] 完成发布门禁、监控、召回、运行时、调度、遥测及 ONLYOFFICE callback 汇总回归。证据：容器内 58 项通过。
- [x] [CONCEPT: 测试方案] 完成 AgentAsset service 与 foundation 兼容回归。证据：容器内 28 项通过、4 项无关差旅计算器用例主动排除。
- [x] [CONCEPT: 测试方案] 完成风险生成、修订和 golden evaluator 回归。证据：容器内 49 项通过，2 项旧发布门禁口径由对应切片处理。
- [x] [CONCEPT: 测试方案] 完成费用风险租户接线回归。证据：13 项通过；2 项旧测试使用未保存 claim，已记录为共享测试夹具问题。
- [x] [CONCEPT: 测试方案] 完成一次性 PostgreSQL 迁移验证。证据：旧数据升级、同编码多企业、非法约束、跨租户 FK、有事实 downgrade 拒绝，以及 `base → head`、`head → 0025 → head` 均通过。
- [x] [CONCEPT: 指标与验收] 相关文件 Ruff 通过、py_compile 通过、ORM mapper 84 张表完成配置、`git diff --check` 通过。

## 7. 文档与上线

- [x] [CONCEPT: 本轮实现记录] 完成 CONCEPT、分阶段 TODO 和安全 bug 修复日志。证据：本目录及 `dev-logs/bugs/agent-asset-tenant-isolation-and-onlyoffice-security.md`。
- [x] [CONCEPT: 风险与开放问题] 记录无 tenant 旧调用、未保存 claim 测试、旧发布 aggregate 口径和企业间受控复制边界。证据：CONCEPT 风险章节。
- [ ] [CONCEPT: 降级与回滚策略] 上线前确认 ONLYOFFICE 下载 origin 在应用容器内解析为公网地址并使用可信 TLS。证据要求：生产白名单配置、容器 DNS/TLS 与实际编辑回写验证。
- [ ] [CONCEPT: 降级与回滚策略] 上线前在备份副本执行 `0025 → head`，确认不存在无法归属的历史记录，并演练有事实情况下的受控回滚流程。
