# 风险规则可解释流程判断改造 TODO

## 使用规则

- 每个 TODO 对应 `CONCEPT.md` 的目标、能力或验收点。
- 只有真实完成并通过相应验证后，才能把 `[ ]` 改成 `[x]`。
- 如果实现中发现需求变化，先更新 `CONCEPT.md`，再调整本 TODO。
- 后端和构建验证默认在 Docker 容器 `x-financial-main` 的 `/app` 下执行。

## 1. 调研与边界

- [x] [CONCEPT: 背景与问题] 梳理当前风险规则生成链路，记录 `risk_rule_generation.py` 到 `risk_rule_template_executor.py` 的真实调用关系。证据：`CONCEPT.md` 后端设计与本轮落地结果记录生成、DSL validator、执行器、流程图、仿真测试链路。
- [x] [CONCEPT: 前端设计] 梳理详情页、新建弹窗、测试弹窗当前字段来源，记录 `AuditRuleDialogs.vue`、`AuditJsonRiskRuleDetail.vue`、`RiskRuleTestDialog.vue` 的改造点。证据：`CONCEPT.md` 本轮落地结果列出三个组件及对应职责，`risk-rule-detail-experience.test.mjs` 覆盖关键接线。
- [x] [CONCEPT: 数据设计] 确认 `AgentAssetRead`、版本内容、`config_json` 中已有字段，确定 `semantic_plan`、`flow_model`、`flow_diagram_svg` 的落点。证据：`AgentAssetRead` 返回 `latest_test_summary`，版本 JSON metadata 保存 `semantic_plan`/`flow_model`/`flow_diagram_svg`，生成测试覆盖。
- [x] [CONCEPT: 非目标] 明确本期不做流程图编辑器，不增加拖拽、缩放、节点编辑能力。证据：`RiskRuleFlowDiagram.vue` 只渲染静态 SVG/文字说明，无编辑、拖拽、缩放入口；前端回归测试断言不存在 zoom 按钮。

## 2. 语义计划与 DSL 契约

- [x] [CONCEPT: C2] 定义 `semantic_plan` schema，包含规则意图、适用范围、字段本体映射、判断步骤、例外条件和风险动作。证据：`risk_rule_explainability.py` 产出 `semantic_plan`，`test_risk_rule_explainability.py` 已验证。
- [x] [CONCEPT: C3] 定义 JSON DSL schema，补齐城市、日期、金额、附件、语义说明等通用算子。证据：`risk_rule_dsl_validator.py` 定义受控 DSL 校验，`risk_rule_generation_interpreter.py` 补充 `numeric_compare`，`risk_rule_template_executor.py` 支持日期、字段集合、附件存在性、文本例外和数值比较算子。
- [x] [CONCEPT: C3] 增加 DSL validator，禁止复杂字段判断退化为“风险关键词匹配”。证据：`validate_risk_rule_draft` 会将城市一致性关键词规则改写为结构化比较，将预算金额关键词规则改写为 `composite_rule_v1`，`test_risk_rule_dsl_validator.py` 覆盖。
- [x] [CONCEPT: C3] 为差旅城市不一致、住宿日期越界、预算阈值、重复发票各准备一条 DSL 样例。证据：新增 `risk_rule_dsl_examples.py`，并通过 `test_risk_rule_dsl_examples.py` 覆盖四类样例的 validator 与执行器命中/未命中回归。
- [x] [CONCEPT: C2] 字段展示统一为 `中文[英文]` 格式，并复用字段本体解释。证据：`risk_rule_explainability.py` 的 `semantic_plan.required_fields.display` 使用字段本体生成 `label[key]`。

## 3. Hermes 生成链路

- [x] [CONCEPT: 总体链路] 调整 `risk_rule_generation_prompt.py`，要求 Hermes 先输出 `semantic_plan`，再输出 DSL。证据：提示词 `required_json_shape` 改为 `{ semantic_plan, dsl }`，`test_prompt_requires_semantic_plan_then_dsl` 验证。
- [x] [CONCEPT: C2] 在提示词中明确：城市、日期、金额、票据关系必须用结构化比较，不允许用关键词替代。证据：`risk_rule_generation_prompt.py` 补充 `numeric_compare` 和预算金额不得关键词匹配的 guardrail。
- [x] [CONCEPT: 后端设计] 在 `risk_rule_generation_semantics.py` 或解释层补齐语义计划解析与错误返回。证据：`risk_rule_generation_semantic_plan.py` 解析 `{ semantic_plan, dsl }` 包装并保留 `metadata.model_semantic_plan`；后台生成失败写入 `generation_error` 和 `last_operation=generation_failed`，容器内 `test_risk_rule_generation_failure.py` 与语义计划测试通过。
- [x] [CONCEPT: 后端设计] 在 `risk_rule_generation_interpreter.py` 中从 `semantic_plan` 生成标准 DSL。证据：新增 `build_dsl_from_semantic_plan`，当 Hermes 仅返回 `semantic_plan` 时生成 `composite_rule_v1` 草稿，再由 DSL validator 基于字段本体规范成受控条件；`test_semantic_plan_only_response_can_generate_standard_dsl` 通过。
- [x] [CONCEPT: 指标与验收] 增加复杂差旅规则生成测试，确认判断依据不是关键词匹配。证据：`test_generate_complex_travel_route_rule_uses_formula_not_keyword_match` 验证复杂差旅规则生成后为结构化城市一致性规则，且 `condition_summary` 不含“风险关键词”；容器内 `test_risk_rule_generation.py` 通过。

## 4. 流程模型与 SVG

- [x] [CONCEPT: C4] 定义 `flow_model` schema，包含 nodes、edges、字段引用、分支标签和风险节点。证据：`risk_rule_explainability.py` 产出 `flow_model`，生成测试验证 nodes/source/metadata 同步。
- [x] [CONCEPT: C4] 修改 `risk_rule_flow_diagram.py`，改为从 DSL 或 `flow_model` 生成 SVG。证据：新增 `build_risk_rule_flow_diagram_spec`，优先从 `flow_model.nodes` 生成图形 spec，缺失时回退 `params.conditions`；`test_flow_diagram_spec_prefers_flow_model_nodes` 通过。
- [x] [CONCEPT: C4] 保持 Style 7 / OpenAI Official 风格：白底、细边框、低饱和、风险节点单点强调。证据：`RiskRuleFlowDiagramRenderer` 输出白底、细边框、低饱和风险色，既有 `test_risk_rule_generation.py` 校验高风险红色、无旧绿色和无阴影滤镜。
- [x] [CONCEPT: 算法与公式] 实现流程复杂度控制，节点过多时压缩主流程。证据：`_condition_lines_from_flow_nodes` 将超过 4 个判断节点压缩为摘要，`test_flow_diagram_spec_compresses_too_many_decision_nodes` 覆盖。
- [x] [CONCEPT: C4] 为老规则缺少 `flow_model` 的情况保留默认静态图兜底。证据：`build_risk_rule_flow_diagram_spec` 在 `flow_model` 缺失时使用 DSL/metadata 生成 spec，`test_flow_diagram_spec_falls_back_to_dsl_when_flow_model_missing` 通过。

## 5. 执行器 trace 与仿真测试

- [x] [CONCEPT: C5] 修改 `RiskRuleTemplateExecutor`，输出每个判断节点的 trace。证据：新增 `evaluate_with_trace`，仿真测试返回 `trace.steps` 和 `path_node_ids`。
- [x] [CONCEPT: C5] 仿真测试统一在“用户点击运行”后处理附件和文本，不允许上传后立即判断。证据：`RiskRuleTestDialog.vue` 的 `handleFileChange` 只把附件加入待发送列表，`sendMessage` 才调用 `recognizeTemporaryFiles` 与 `simulateRiskRuleTest`；容器内 `npm run build` 通过。
- [x] [CONCEPT: C5] 测试结果中展示 OCR 原始字段、Hermes 规范化字段、执行器实际输入字段。证据：`AgentAssetRiskRuleSimulationRead` 新增 `ocr_raw_fields`、`hermes_normalized_fields`、`executor_input_fields`，`RiskRuleTestDialog.vue` 展示字段流水线；容器内 `test_risk_rule_explainability.py` 与 `test_risk_rule_generation.py` 通过。
- [x] [CONCEPT: C5] 测试弹窗展示命中路径、未命中原因和最终风险动作。证据：`RiskRuleTestDialog.vue` 展示“执行路径”，`riskRuleTestDialogDisplay.js` 格式化 trace。
- [x] [CONCEPT: C5] trace 中的 `node_id` 必须能映射到流程图节点。证据：`flow_model` 使用条件 id 作为节点 id，`risk_rule_execution_trace.py` 输出同名 `node_id`。

## 6. 规则修改与版本化

- [x] [CONCEPT: C6] 未上线规则支持编辑标题、费用领域、附件要求和自然语言描述。证据：新增 `AgentAssetRiskRuleRevisionService.update_unpublished_draft` 与 `PATCH /agent-assets/{asset_id}/risk-rules/draft`，容器内 `test_risk_rule_revision_endpoints.py` 覆盖返回字段。
- [x] [CONCEPT: C6] 已上线规则新增“创建修订版本”，不直接覆盖 active 版本。证据：新增 `AgentAssetRiskRuleRevisionService.create_revision_draft` 与 `POST /agent-assets/{asset_id}/risk-rules/revisions`，测试验证 `published_version` 保持不变且 `working_version` 进入修订版本。
- [x] [CONCEPT: C6] 修订版本保存后重新生成 DSL、流程图、风险评分和业务说明。证据：新增 `AgentAssetRiskRuleRegenerationService` 与 `POST /agent-assets/{asset_id}/risk-rules/regenerate`，草稿/修订草稿都会重新生成 JSON DSL、`flow_diagram_svg`、风险评分和版本 Markdown；容器内 `test_regenerate_revision_draft_keeps_active_document_unchanged` 通过。
- [x] [CONCEPT: C6] 发布修订版本时归档旧版本，并记录修改人、修改原因和测试报告。证据：新增 `AgentAssetRiskRulePublishMixin`，发布修订时将旧 `rule_document` 写入 `revision_history.previous_rule_document`，切换新 JSON 文件并写入 `last_operation=publish_revision`；容器内 `test_publish_regenerated_revision_replaces_online_document` 通过。
- [x] [CONCEPT: C6] 普通用户误判/漏判反馈进入规则反馈记录，不直接修改规则。证据：新增 `agent_asset_rule_feedback` 模型、`POST/GET /agent-assets/{asset_id}/risk-rules/feedback`、前端服务方法；容器内 `test_risk_rule_feedback.py`、规则回归和 `npm run build` 通过。

## 7. 常见费控规则模板库

- [x] [CONCEPT: C1] 增加“从常见规则模板创建”入口。证据：`AuditRuleDialogs.vue` 新建风险规则弹窗新增常见规则模板选择，选择后预填标题、附件要求、业务环节、费用领域和自然语言。
- [x] [CONCEPT: C1] 模板按预算、票据、差旅、招待、采购/AP、企业卡、通用分组。证据：新增 `risk_rule_template_catalog.py`，`GET /agent-assets/risk-rules/templates` 返回 7 个分组；容器内 `test_risk_rule_template_catalog.py` 通过。
- [x] [CONCEPT: C3] 每个模板提供默认自然语言、字段清单、附件要求和 DSL 样例。证据：模板接口返回 `natural_language`、`fields`、`requires_attachment`、`dsl_example`；容器内测试逐个调用 DSL validator 验证通过。
- [x] [CONCEPT: 非目标] 模板不得绕过通用生成链路，不写定制校准器。证据：前端模板只预填 `riskRuleCreateForm`，提交仍走 `generateRiskRuleAsset`；无新增定制校准器，容器内 `npm run build` 通过。

## 8. 前端详情与交互

- [x] [CONCEPT: 前端设计] 详情页 topbar 展示规则标题、状态、风险分数、风险等级、上线/启用状态。证据：`auditViewDetailTopBar.js` 为风险规则详情输出风险分、风险等级、规则状态、上线状态、启用状态 KPI；容器内 `npm run build` 通过。
- [x] [CONCEPT: C4] 判断流程区域改成左侧文字流程解释、右侧流程图。证据：`RiskRuleFlowDiagram.vue` 使用左侧 `risk-rule-flow-explainer` 和右侧 `risk-rule-flow-visual` 的两栏布局；容器内 `npm run build` 通过。
- [x] [CONCEPT: C4] 流程图标题固定为“流程图”，高度与“流程解释”标题对齐。证据：`RiskRuleFlowDiagram.vue` 使用统一 `risk-rule-section-title`，右侧标题固定为“流程图”；容器内 `npm run build` 通过。
- [x] [CONCEPT: C5] 测试弹窗展示字段识别结果、规范化字段、判断路径和测试报告。证据：`RiskRuleTestDialog.vue` 展示字段流水线、执行路径和右侧测试报告摘要；容器内 `cd /app/web && npm run build` 通过。
- [x] [CONCEPT: C6] 已上线规则详情展示“创建修订版本”，草稿规则展示“编辑规则”。证据：`AuditView.vue` 底部动作区按规则状态展示按钮，`AuditRuleDialogs.vue` 提供编辑/修订弹窗，`useAuditRiskRuleActions.js` 调用草稿编辑与修订接口；容器内 `cd /app/web && npm run build` 通过。
- [x] [CONCEPT: 指标与验收] 列表和详情状态刷新不能造成页面闪烁。证据：`useAuditAssetData.loadSelectedAssetDetail` 增加 `{ silent: true }` 静默刷新，规则保存、送审、审核、上线、回退和版本操作均改为静默刷新；容器内 `npm run build` 通过。

## 9. 后端接口与权限

- [x] [CONCEPT: 接口设计] 实现或调整 `POST /agent-assets/{asset_id}/risk-rules/revisions`。证据：新增独立路由 `agent_asset_risk_rules.py`，容器内 `test_create_risk_rule_revision_endpoint_keeps_active_version` 通过。
- [x] [CONCEPT: 接口设计] 实现或调整 `PATCH /agent-assets/{asset_id}/risk-rules/draft`。证据：新增独立路由 `agent_asset_risk_rules.py`，容器内 `test_update_risk_rule_draft_endpoint_updates_unpublished_rule` 与已上线阻断用例通过。
- [x] [CONCEPT: 接口设计] `POST /agent-assets/{asset_id}/risk-rules/regenerate` 返回生成状态和错误详情。证据：独立路由 `agent_asset_risk_rules.py` 已接入重生成接口，成功返回 `AgentAssetRead.config_json.generation_status`/`revision_draft.generation_status`，接口用例 `test_regenerate_risk_rule_endpoint_returns_updated_detail` 通过。
- [x] [CONCEPT: 接口设计] 仿真测试接口返回 `recognized_fields`、`normalized_fields`、`execution_result`、`trace`。证据：`AgentAssetRiskRuleSimulationRead` 新增 `normalized_fields` 和 `trace`，仿真测试覆盖返回值。
- [x] [CONCEPT: 用户与场景] 普通财务人员只能编辑未上线/修订草稿，admin 才能删除和测试，管理员按现有权限上线/下线。证据：路由依赖使用 `RuleEditorUser`、`RuleReviewerUser`、`PlatformAdminUser` 分层，`test_risk_rule_revision_endpoints.py` 覆盖 finance 新建/测试阻断、manager 删除阻断和 manager 启停入口。
- [x] [CONCEPT: 数据设计] 所有操作写入 `last_operation`，用于详情页“最后操作”展示。证据：生成、后台生成、草稿编辑、创建修订、重新生成、发布/下线、测试确认等风险规则服务均写入 `config_json.last_operation`，前端 `AuditJsonRiskRuleDetail.vue` 展示 `lastOperationLabel`。

## 10. 测试与验证

- [x] [CONCEPT: 测试方案] 后端补充语义计划、DSL validator、执行器 trace、流程图转换单元测试。证据：`test_risk_rule_explainability.py` 覆盖语义计划、flow_model、trace；`test_risk_rule_dsl_validator.py` 覆盖 DSL validator 与 `numeric_compare` 执行；容器内相关测试通过。
- [x] [CONCEPT: 测试方案] 后端补充修订版本接口和发布替换接口测试。证据：`test_risk_rule_revision_service.py` 覆盖草稿编辑、创建修订、修订重生成和发布替换；`test_risk_rule_revision_endpoints.py` 覆盖草稿编辑、创建修订和重生成接口；容器内相关测试通过。
- [x] [CONCEPT: 测试方案] 前端补充详情页流程展示、测试弹窗字段展示、修订版本按钮状态测试。证据：新增 `risk-rule-detail-experience.test.mjs` 覆盖 topbar KPI、左文右图流程、字段流水线和修订按钮；容器内 `node --test tests/risk-rule-detail-experience.test.mjs` 通过。
- [x] [CONCEPT: 容器验证] 在容器执行后端定向测试，单个命令设置 60s 超时。证据：`/tmp/x-financial-server-venv/bin/python -m pytest tests/test_risk_rule_explainability.py -q`、`test_risk_rule_composite_generation.py -q`、`test_risk_rule_generation.py -q` 均通过。
- [x] [CONCEPT: 容器验证] 在容器执行 `cd /app/web && npm run build`。证据：容器 `/app/web` 构建通过。
- [x] [CONCEPT: 指标与验收] 用“武汉到上海票据 + 北京出差 3 天”样例验证城市不一致规则必须命中或给出明确不命中原因。证据：`test_simulation_returns_execution_trace_for_ticket_city_mismatch` 验证命中并返回 trace。
- [x] [CONCEPT: 指标与验收] 用预算阈值、重复发票、住宿日期越界、招待人均超标样例做回归。证据：`risk_rule_dsl_examples.py` 已包含预算阈值、重复发票、住宿日期越界、招待人均超标样例，`test_risk_rule_dsl_examples.py` 在容器内 7 passed。

## 11. 文档收尾

- [x] [CONCEPT: 指标与验收] 开发完成后补充实际接口、文件和测试命令结果。证据：`CONCEPT.md` 新增“本轮落地结果”，列出接口、关键文件和容器验证命令。
- [x] [CONCEPT: 风险与开放问题] 记录暂未解决的字段本体缺口和复杂规则降级策略。证据：`CONCEPT.md` 风险与开放问题补充企业卡、采购/AP、预算字段本体缺口和 DSL validator/dry-run/仿真兜底策略。
- [x] [CONCEPT: 功能一句话] 确认最终实现没有偏离“解释图和执行逻辑一致”的核心目标。证据：`CONCEPT.md` 新增“实现确认”，明确自然语言、字段本体、JSON DSL、流程图、测试 trace 和上线版本围绕同一 DSL。
