feat(investigations): refine report authoring and replay flushing
Generic Container CI/CD / test-build-publish (push) Successful in 4m31s
Server CI/CD v2 / build-test-publish-and-deploy (push) Successful in 4m31s

This commit is contained in:
2026-11-14 23:00:15 +08:00
parent 2e4f6cb93b
commit b45c5c6f46
27 changed files with 1125 additions and 94 deletions
@@ -32,7 +32,9 @@ Server 将阅读进展、业务报告和浏览器展示请求分别保存。运
}
```
示例中的编号由实际任务和资产替换。正文最长 20,000 字符,`graph_update` 可省略。
示例中的编号由实际任务和资产替换。新发布的 `summary` 最多 300 字符,建议 120 字以内,
只说明本轮新增发现、当前依赖和下一步;使用中文业务语言与当地时间,不复制报告或执行参数。
详细结果和引用留在图节点、证据与报告明细中,历史正文仍按原值读取。`graph_update` 可省略。
图示沿用 [调查报告契约](investigation-report-contract.md) 的 Mermaid 安全限制。
节点标记可省略或为 null,均显示为参考步骤;新增量更新只接受以下五种:
@@ -107,6 +109,33 @@ Server 校验当前 run、绑定会话、有效租约和幂等身份,记录 `o
响应为 `recorded/event_seq/run_id/execution_generation`,表示展示请求已保存,
不表示浏览器已显示或现场动作已执行。
### 展示表达与阅读
实时展示与正式报告共用中文业务表达和时间要求,字段沿用现有结构:
| 字段 | 表达职责 | 长度 |
| --- | --- | --- |
| purpose | 为什么核查这些对象;不复述动作名称、当前发现或完整报告 | 建议 60 字以内,最多 160 字符 |
| narration.stage | 本步所属业务阶段,前端显示中文阶段名称 | 使用既有枚举 |
| narration.summary | 本步已有证据支持的关键发现,区分观测、候选、模型与现场反馈 | 建议 80 字以内,最多 160 字符 |
| narration.next_step | 实际下一步或等待条件;无后续时省略 | 建议 60 字以内,最多 120 字符 |
| narration.evidence_refs | 该发现引用的实际证据,不作为正文展示 | 保持现有引用校验 |
已有明确分析结果时提供 `narration`;纯视角调整或清除操作不编造发现。
目的、发现和后续分别组织,不重复粘贴同一段文字。同一核查目的的批量图表可以复用有依据的
相同讲解,保留合并阅读能力;不同发现分别保存,不为合并而抹去结论差异。
讲解、目的和图表、覆盖层的可见标签均采用纯文本,省略执行字段、版本号、技术状态码、
完整 UUID、证据哈希、时区名称、偏移和 ISO 时间戳。必要设备编号、单位与历史日期保留;
标题交代对象、指标或预计范围,算法参数留在证据明细。结构化采样时刻、设备标识、数值、
几何和证据引用保持原值,不因文字整理改变分析范围。
Server 的新请求模型、Agent 原生工具及宿主入口校验这些文字规则;历史读取模型保持兼容。
前端在当前动作说明中突出已保存的发现,再呈现目的和后续,缺少讲解的历史步骤只显示用途,
不推断结论。讲解进入已有滚动阅读区,历史与播放控件留在标题区,长文字不挤出控件。
历史选择固定在所选步骤;自动停留时间考虑实际可见的目的、发现与后续文字,
用户手动选择的停留时间保持优先。上述文字和播放行为不控制后台调查、审批或现场执行。
| command.action | 参数 |
| --- | --- |
| locate_features | layer、feature_ids |
+59 -11
View File
@@ -9,17 +9,19 @@
| 字段 | 类型 | 新写入规则 |
| --- | --- | --- |
| title | 非空字符串 | 报告标题 |
| current_conclusion | 非空字符串 | 当前判断文字;无结论时明确写无法判断,不编造原因 |
| conclusion_boundary | 非空字符串 | 判断范围及限制 |
| title | 非空字符串,最多 80 字符 | 简短中文业务标题,建议 30 字以内,不包含执行轮次和流程版本 |
| current_conclusion | 非空字符串,最多 300 字符 | 首句写当前判断,接关键依据和实际下一步,建议 150 字以内;完整数值放入表格 |
| conclusion_boundary | 非空字符串,最多 240 字符 | 影响判断的证据范围、不确定性和适用限制;不复述执行过程、参数或完整资产清单 |
| evidence_refs | 字符串数组 | 引用该任务中已持久化、不可变的证据编号 |
| recommendations | 字符串数组 | 保持原类型,处置建议不等于已执行动作 |
| pending_items | 字符串数组 | 保持原类型,不从文字推断状态 |
| recommendations | 字符串数组,每项最多 160 字符 | 具体对象与后续动作;处置建议不等于已执行动作 |
| pending_items | 字符串数组,每项最多 160 字符 | 实际尚未完成或等待外部条件的事项,不从文字推断状态 |
| stage | interim / final | 必填;阶段性报告不能用于结束运行 |
| outcome | concluded / insufficient_data | 必填;业务调查结果,与运行成功/失败独立 |
| stop_reason | 非空字符串或 null | 证据不足时必填;已形成结论时必须为 null |
| stop_reason | 最多 160 字符的非空字符串或 null | 证据不足时必填;已形成结论时必须为 null |
| data_gaps | 缺口对象数组 | 必填;空数组表示已记录且没有缺口 |
| diagram | 调查脉络对象或 null | 可选;给人阅读的 Mermaid 说明,不控制执行或任务状态 |
| ui_blocks | 结果组件数组,最多 8 块、合计 400 KB | 以现有 Result、Section、Table 等组件表达重点与明细,块内引用必须属于报告证据 |
| scada_device_ids | 设备编号数组,最多 1000 项 | 监测明细与展示目标的完整集合,不能因精简摘要删除目标 |
缺口对象除 node_id 外的字段必填:
@@ -27,10 +29,10 @@
| --- | --- | --- |
| gap_id | 非空字符串 | 报告内唯一的缺口编号 |
| node_id | 非空字符串或 null | 可选的展示关联,不要求有执行计划 |
| missing_data | 非空字符串 | 缺失数据内容 |
| scope | 非空字符串 | 查询对象、地点及时间范围 |
| impact | 非空字符串 | 因此无法回答的调查问题 |
| required_data | 非空字符串 | 新一轮调查需要补齐的具体数据 |
| missing_data | 非空字符串,最多 4000 字符 | 缺失的业务资料 |
| scope | 非空字符串,最多 4000 字符 | 查询对象、地点及当地时间范围 |
| impact | 非空字符串,最多 4000 字符 | 因此无法回答的调查问题 |
| required_data | 非空字符串,最多 4000 字符 | 新一轮调查需要补齐的具体数据 |
| evidence_refs | 至少一个证据编号 | 实际查询或可信输入记录;必须也出现在报告 evidence_refs 中 |
| blocking | boolean | 是否阻止形成结论 |
@@ -42,6 +44,48 @@
不包含 Markdown 围栏、初始化指令和 click 命令。前端使用 strict 安全级别渲染 SVG。
完整图语法的解析失败只影响图示,正文、依据和审核仍可阅读。
## 报告表达与生成要求
报告面向供水运维人员,按当前判断、关键依据、判断限制、后续安排组织内容。
字段仍按现有模型发布,不将多段报告重新堆入 `current_conclusion` 或 `conclusion_boundary`。
- 结论首句直接回答当前发生了什么、形成什么判断。随后只保留最关键的变化和实际下一步,
正文最多举两个关键对象。评分权重、算法参数、全部测点、阀门和影响对象放入依据明细。
- 多个对象或多组数值比较使用有证据引用的 `ui_blocks.Table`。表格按实际资料选择对象、
指标、时刻、异常值、当前值、基线与结果等列,单位放在列名或单元格;缺值明确写未取得。
全部目标按需分表,不以精简正文为由缩小调查、证据或 SCADA 展示覆盖。
- 使用 `Result` 突出有依据的判断、关键变化或实际待办,使用带业务标题的 `Section` 组织明细。
模型候选或尚待现场核验用 `unconfirmed`,部分完成用 `partial`;`success` 必须有相应通过依据。
现有文字字段按纯文本展示,不写 Markdown 加粗、标题、表格或 HTML,也不引入自定义强调字段。
- 正文、进展、缺口说明和组件可见文字采用中文业务语言。执行字段、技术状态码、流程版本、
完整 UUID 和证据哈希留在结构化引用或执行记录中。必要资产编号、SCADA、DN600、单位、
模型相似度和有业务用途的工单简称可以保留,不能机械删除所有英文或数字。
- 阅读时间先换算为 `Asia/Shanghai`,再以当地日期和时刻显示,例如 `2026-07-16 13:15`。
正文、标题、进展、表格和图表均省略时区名称、偏移及 ISO 原始时间戳。已有 `+08:00`
不重复换算,跨日同步更新日期;查询时间、`sample_times` 和证据时间戳仍保留明确偏移。
事件发生、工单完工、恢复采样和报告生成时间各自标明用途,不能互相代替。
- 区分观测、模型估计、候选和现场反馈。相似度不是发生概率,提交工单不证明现场完工,
单帧复核通过不证明长期稳定;不同来源或阶段的设备数分别说明范围,不能混用分母。
单条流量规则未触发不表示所有流量未变化;不同影响集合不能直接相加。
- 判断边界只保留影响理解的限制。实际资料缺项放入 `data_gaps`;未来常规采样和日常监测
写入建议,不将其包装成当前关键缺口。非阻塞资料缺项不得新增事件闭环条件。
初次调查说明异常、候选及预计影响;等待处置说明已完成事项、实际等待条件和下一步;
恢复报告先说明现场反馈与完工时间、恢复复核时刻与结果,再给出必要限制和后续监测安排。
恢复明细来自本次恢复证据,原异常分析作为历史依据保留,不在摘要中重复全部定位与隔离参数。
`progress.summary` 最多 300 字符,建议 120 字以内,只写本轮新增发现、当前依赖和下一步,
不复制正式报告、不汇报执行字段和流程版本。整理报告时核对脉络图:已解除的等待条件应按
原节点更新业务说明和参考标记,保留失败尝试与原路线,不重复添加相同连线。
这不要求逐步更新图示,也不改变任何运行、审批、等待或闭环判据。
Server 的新写入模型及 Agent 的原生工具、宿主发布入口校验长度、明显执行字段与技术编号、
原始时间表达和无法渲染的格式标记;组件的可见文字同样校验,结构化证据编号与采样时间除外。
校验错误返回具体原因,由 Agent 依据原证据改写后重试,不截断正文、不删除引用或补造缺口。
语义准确性、信息取舍和表格完整性仍需遵循提示词与既有证据、覆盖校验,不能由正则代替。
上述长度和文字规则仅约束新发布,不应用于历史读取或原证据快照;不回写已有报告。
每条 node_ref 包含 `node_id`、`label`、`evidence_refs`、`action_refs`;后两项默认空数组。
node_id 为最多 80 字符的 ASCII 标识符,必须以字母或下划线开头,在本图引用内唯一,
并与 Mermaid 源码中实际节点使用完全相同的 ID;禁止为同一节点另造引用 ID;
@@ -133,7 +177,7 @@ failure_code 为 ARTIFACT_INCOMPLETE;调用方须读取返回的业务状态
"gap_id": "terminal-sample-gap",
"node_id": null,
"missing_data": "投诉时段末梢水样检测结果",
"scope": "投诉小区,2026-09-24 08:00 至 09:00(北京时间)",
"scope": "投诉小区,2026-09-24 08:00 至 09:00",
"impact": "无法判断异常来自供水管网还是用户端。",
"required_data": "该地点和时段的采样检测记录",
"evidence_refs": ["sample-query-empty"],
@@ -150,6 +194,10 @@ failure_code 为 ARTIFACT_INCOMPLETE;调用方须读取返回的业务状态
- 已有未决动作阻止矛盾的缺数退出;重试幂等,不重复生成报告。
- 新轮次保留旧报告历史标识,不能显示成当前轮次已结束。
- 桌面及 320/375px 展示结果、缺口、证据,审批区不出现数据授权入口。
- 新发布拒绝超长摘要、正文执行字段、完整技术编号、原始时间表达和未支持的格式标记;
相同历史报告仍可读取,结构化证据引用与带偏移的采样时间保持不变。
- 生成结果结论在前、明细入表,明确单位、时间和各自覆盖范围;
候选、现场反馈、单帧复核与长期监测保持各自含义,进展和图示不与当前事实冲突。
## 发布、阅读与协作
+1 -1
View File
@@ -12,7 +12,7 @@ Agent 原生工具统一使用 `mcp_tjwater_` 前缀。Server目录共67项:42
| `run_leakage_identification` | SCADA压力约束下的DMA漏损分配估计;需总漏损量依据 | `burst.run` + `scada.view` |
| `run_contaminant_simulation` | 假设源正向传播;可选按全网全时段浓度汇总累计范围、首个超阈值报告时刻与峰值,详见[污染流程](water-pollution-response-workflow.md);与工单并行,不承担反演或安全判定 | `simulation.run` + `scada.view` |
| `analyze_valve_closure` | 给定关阀组合的水力影响 | `simulation.run` + `scada.view` |
| `analyze_flushing` | 指定排放节点和流量的冲洗水力影响;不证明消毒合格 | `simulation.run` + `scada.view` |
| `analyze_flushing` | 指定排放点、流量与互斥的 `opened_valves` / `closed_valves`,评估独立冲洗水力情景并保存阀态和预计排放量;不证明污染清除或水质合格 | `simulation.run` + `scada.view` |
| `analyze_pressure_regulation` | 给定调泵序列、水箱初始水位的压力影响;不自动优化调度 | `simulation.run` + `scada.view` |
| `optimize_sensor_placement` | 灵敏度或K-means压力监测点建议;不保存正式布点方案 | `optimization.run`,项目成员角色 |
+30 -8
View File
@@ -6,20 +6,26 @@
flowchart TD
detection[有效水质观测命中业务规则] --> task[独立水污染事件调查]
task --> evidence[全量观测及七天同期核验]
evidence --> trace[快速候选溯源]
evidence --> protection[并行提出用户保护与应急供水措施]
evidence --> trace[候选溯源与采样核验]
trace --> node[展示已核验节点]
node --> report[候选源阶段结论]
report --> action[立即提出现场核查采样工单供审批派发]
report --> simulation[污染传播模拟与累计浓度影响范围]
report --> isolation[节点隔离与阀门边界]
simulation --> impact[同一调查补充证据地图与报告]
isolation --> impact
action --> feedback[采样处置复测反馈]
feedback --> review[接续原调查复核]
impact --> review
review --> final[最终报告及事件收尾]
simulation --> source[污染输入控制建议]
source --> isolation[保护用户与隔离边界]
isolation --> treatment[按污染物选择清除方法]
treatment --> flushing[清洁水入口 导流阀门 排放处置与分步冲洗]
action --> feedback[现场操作与采样反馈]
flushing --> feedback
feedback --> review[核对实际水质复测与恢复依据]
review --> decision{复测依据是否支持恢复}
decision -->|否或资料不足| treatment
decision -->|是| final[分区恢复建议与最终报告]
```
图中连线表示业务与展示层次,先期保护、工单审核和独立计算可以并行。阀门操作均为方案,现场动作继续经过原审批与派发;阶段记录不能替代执行回执。首次展示保留处置前传播结果或明确的数据缺口,再展示隔离及清除方案。
## 侦测入口
现有 `ScadaReplayService` 使用冻结的水质设备类型 `quality` / `water_quality` 判别水质规则事件。仪表无效值、缺测产生的 `data_quality` 告警单独处理。水质业务规则命中直接创建污染调查,即使同时运行压力/流量周期诊断,也不被合并成爆管调查。持续规则事件沿用同一任务,规则恢复后接续该任务的新一轮。压力/流量与水质同时异常时各自保留调查。
@@ -46,6 +52,22 @@ flowchart TD
## 展示、反馈与收尾
`water-pollution-event` 1.2.0 将观测核验、候选定位、处置前传播、源头控制、用户隔离、清除冲洗、现场反馈、水质复测和恢复复核分开。每次正式展示保存 `purpose`;有证据的阶段通过 `narration.stage` 记录,新增 `source_control`、`flushing_plan`、`clearance_verification`。历史保存格式继续使用原事件 metadata JSON,不增加数据库列。前端显示阶段和本步目的,逐步回看保留独立画面;同阶段兼容图表仍可合并。
源头控制与保护下游用户分别决策。用已核实的连接和流向判断水力下游,不能按地理方位判断;源头未核实不得声称污染输入已停止。清除方法按污染物及现场条件选择,不统一推荐煮沸、加药或排水。通知保留,工单按执行职责和阶段复用或必要拆分,不能同时要求同一阀门开和关。
### 冲洗模型与阀门方案
`analyze_flushing` 增加可选 `opened_valves`,与 `closed_valves` 互斥且各自去重。明确开阀用于清洁水进入或导流,关阀用于保护用户和约束路径;不改变阀门原调节设定。普通计算和保存冲洗方案使用相同显式阀态。未列阀门沿用当前模型状态,每次计算为独立情景,不能继承上次计算的阀位或浓度场。
每一步操作表保存:目的、前置条件、清洁水源及依据、排放节点与污染水处置去向、完整开关阀清单、计划顺序、流量、持续时间、预计排放量、监测要求、实际执行反馈。清洁进水阀打开不表示用户可以恢复供水。路径只采用已核实资产几何,不用直线伪造流向。
计算返回 `flushing_plan`,包含开关阀、排放节点、流量和 `estimated_discharge_volume_m3`(给定流量乘持续时间)。它仅是水力情景,`water_quality_clearance_verified=false`、`field_execution_verified=false`;估计水量不是实测排放量。当前不模拟停止污染输入后的连续清除衰减,也不验证进水洁净、排放合规或实验室合格。缺少模型或现场依据时报告具体限制,不伪造清除效果。带回放上下文的调查仅新增独立模型冲洗情景:起算不晚于知识截止,始终传入空 SCADA 映射,禁止实时观测回填;原角色、任务、权限及作业所有权校验保留。历史播放读取已保存方案,不重新计算或现场操作。
### 复测与恢复依据
复核记录采样地点、时间、指标、数值、单位、适用判定依据、受影响范围覆盖及结论,区分实际结果和模型预测。工单完成、压力恢复或余氯单项正常不能证明目标污染物已清除。关键复测资料不足或未通过时,Agent 保存 `interim` 并提出具体补测或调整方案;不统一新增固定轮数、时长或阈值。已有足够复测与恢复依据时,展示可恢复区域并发布引用有效现场反馈及复测证据的最终报告。Server 继续校验反馈引用,不自动判定实验室合格,也不授权设备操作或现场复供。
水质图表使用 `chart.scada.metric=quality`,沿用真实单位、三小时当前趋势、前七天同期散点及证据校验;不同指标分图。同单位不同水质指标通过图表纵轴名称区分展示分组。Server、Agent、Frontend 的图表协议同步支持 quality,正式报告仍需引用本轮全量 SCADA 证据。
关联现场任务使用 general 工单。成功创建后保存在 `handling_context.work_orders`,进入 `waiting_work_order`;全部有效工单 completed 后进入 `field_review`,接续 Agent,而非执行爆管压力恢复计算。最终 concluded 报告必须引用全部有效工单最新的 `feedback_evidence_id`,然后由 Server 完成任务并解除关联告警。完工反馈或新版本复测资料会重新进入复核;证据不齐时 Agent 使用现有提问/新动作流程等待事实。该机制校验反馈引用与调查收尾,不自动判断实验室水质合格。