Files
next-tjwater-server/docs/investigation-report-contract.md
T
jiang b45c5c6f46
Generic Container CI/CD / test-build-publish (push) Successful in 4m31s
Server CI/CD v2 / build-test-publish-and-deploy (push) Successful in 4m31s
feat(investigations): refine report authoring and replay flushing
2026-11-14 23:00:15 +08:00

220 lines
16 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 调查报告数据契约
本契约适用于供水事件调查,由 Server 的 `InvestigationReportInput`(写入)和
`InvestigationReport`(读取)定义。Agent 和前端采用同样的字段和约束。
不增加格式版本标签;原字段的类型保持稳定。`revision` 是报告修订号,
`execution_generation` 是调查轮次,两者均不用于选择格式解析器。
## 数据模型
| 字段 | 类型 | 新写入规则 |
| --- | --- | --- |
| title | 非空字符串,最多 80 字符 | 简短中文业务标题,建议 30 字以内,不包含执行轮次和流程版本 |
| current_conclusion | 非空字符串,最多 300 字符 | 首句写当前判断,接关键依据和实际下一步,建议 150 字以内;完整数值放入表格 |
| conclusion_boundary | 非空字符串,最多 240 字符 | 影响判断的证据范围、不确定性和适用限制;不复述执行过程、参数或完整资产清单 |
| evidence_refs | 字符串数组 | 引用该任务中已持久化、不可变的证据编号 |
| recommendations | 字符串数组,每项最多 160 字符 | 具体对象与后续动作;处置建议不等于已执行动作 |
| pending_items | 字符串数组,每项最多 160 字符 | 实际尚未完成或等待外部条件的事项,不从文字推断状态 |
| stage | interim / final | 必填;阶段性报告不能用于结束运行 |
| outcome | concluded / insufficient_data | 必填;业务调查结果,与运行成功/失败独立 |
| stop_reason | 最多 160 字符的非空字符串或 null | 证据不足时必填;已形成结论时必须为 null |
| data_gaps | 缺口对象数组 | 必填;空数组表示已记录且没有缺口 |
| diagram | 调查脉络对象或 null | 可选;给人阅读的 Mermaid 说明,不控制执行或任务状态 |
| ui_blocks | 结果组件数组,最多 8 块、合计 400 KB | 以现有 Result、Section、Table 等组件表达重点与明细,块内引用必须属于报告证据 |
| scada_device_ids | 设备编号数组,最多 1000 项 | 监测明细与展示目标的完整集合,不能因精简摘要删除目标 |
缺口对象除 node_id 外的字段必填:
| 字段 | 类型 | 含义 |
| --- | --- | --- |
| gap_id | 非空字符串 | 报告内唯一的缺口编号 |
| node_id | 非空字符串或 null | 可选的展示关联,不要求有执行计划 |
| missing_data | 非空字符串,最多 4000 字符 | 缺失的业务资料 |
| scope | 非空字符串,最多 4000 字符 | 查询对象、地点及当地时间范围 |
| impact | 非空字符串,最多 4000 字符 | 因此无法回答的调查问题 |
| required_data | 非空字符串,最多 4000 字符 | 新一轮调查需要补齐的具体数据 |
| evidence_refs | 至少一个证据编号 | 实际查询或可信输入记录;必须也出现在报告 evidence_refs 中 |
| blocking | boolean | 是否阻止形成结论 |
禁止未知字段、未知枚举和重复 gap_id。各引用在 Server 中校验。
查询失败、权限配置异常不能作为“没有数据”的证明。
调查脉络对象包含 `title`、`mermaid` 和可选的 `node_refs`(默认空数组)。
`mermaid` 最长 20,000 字符,必须以 `flowchart` 或 `graph` 及方向开头,
不包含 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;
最多 100 条引用。证据必须来自报告 evidence_refs,动作必须属于当前任务。
节点可以说明候选方向与条件关系;图中的分支、状态文字不能证明实际并发、动作执行或现场完成。
可选 status 仅为参考标记:reference(参考步骤)、recorded(已有结果)、needs_input(待补充条件)、
failed(尝试失败)、not_taken(未采用路线)。recorded 不证明业务完成,标记不与任务或工具运行状态绑定。
旧运行状态按[兼容映射](investigation-progress-and-presentation.md)读取,未提供标记时保持中性的参考步骤。
图的颜色、字体和交互由前端统一配置。正文不包含 SVG 或 HTML。
## 业务约束
1. `concluded` 允许 interim/final,stop_reason 为 null,不允许 blocking 缺口。
2. `insufficient_data` 只能是 final,至少一个 blocking 缺口,必须提供 stop_reason;
recommendations 和 pending_items 必须为空,不发起补数据的工单动作。
3. 报告必须来自当前执行轮次、会话和有效租约;执行计划与图示均可缺省。
历史计划或未结束的解释节点不阻止发布与正常收尾。运行状态来自 Server run,
审核和业务结果来自真实动作与回执,图示不参与计算。
4. 尚有待审核、已批准未提交、已提交或结果未知的动作时,不能发布数据不足退出报告。
不自动撤销已有动作,不影响独立现场处置。
5. 数据不足报告保存后,本执行代不再接受新的报告。补齐数据应使用已有 retry 接口
创建新 execution_generation,原报告、证据和回执保持可追溯。
6. 事件调查提议动作前必须已保存本轮 outcome=concluded 的报告。
顺序为阶段性结论、动作提议、最终报告、运行收尾。图示可在报告中关联动作编号。
7. 数据不足时顺序为查询证据、最终报告、运行收尾。
运行正常结束为 succeeded,调查生命周期为 completed;页面显示“已结束·证据不足”,
不显示正常水质、不自动关闭原投诉工单,不等待人工授权或补数据。
8. 数据读取范围由系统配置;本场景的人工审核只针对具体业务动作。
既有数据访问审核接口仅保留兼容其他调用,不作为事件调查的产品入口。
## 历史读取与兼容
旧报告缺少 stage/outcome/stop_reason/data_gaps 时,Server 统一返回 null。
null 表示未记录,不能转换成 concluded、空缺口清单或正常水质。
前端兼容滚动发布期间的缺省/null,未知字段仍严格拒绝;一旦提供 outcome,
其余结构化字段和业务约束必须完整满足。新写入不接受全空的历史格式。
历史导入脚本的 dry-run 继续校验原始记录;缺少结构化结果的历史报告不能直接发布为新调查报告,实写在创建任务前拒绝,避免按旧正文编造结果。
无需改写历史报告或新增数据库表,新增字段保存在原报告 document 中。
上线顺序:先部署能读取可选新字段的前端,再协调更新 Server 新写入契约与 Agent。
在切换写入端前应结束旧 Agent 在途运行,旧写入格式会被明确拒绝,不能静默推断结果。
回退前须保留支持新字段的读取端;不能直接回退到会拒绝新字段的旧前端。
## 接口与错误
所有路径均以 `/api/v1` 开头,保留现有 Bearer 身份与项目范围校验。
| 方法与路径 | 用途 |
| --- | --- |
| GET /operational-tasks/{task_id} | 读取统一的报告模型,旧结构化字段返回 null |
| GET /operational-tasks/{task_id}/reports?limit=20&offset=0 | 按修订号倒序读取历史,返回 items 与 next_offset |
| GET /operational-tasks/{task_id}/reports/{revision} | 读取指定报告快照,任务及项目范围校验 |
| GET /operational-tasks/{task_id}/agent-context?report_revision=1 | selected_report 是所选报告,task 保留当前真实状态;未传则 selected_report 为 null |
| POST /operational-tasks/{task_id}/agent-artifacts | 写入报告和计划;保留 request_id 幂等、run_id 与会话归属校验 |
| POST /operational-tasks/{task_id}/runs/{run_id}/complete | 事件调查校验本轮最终报告后结束运行;检查 expected_revision |
| POST /operational-tasks/{task_id}/actions | 仅本轮已保存 concluded 报告的事件调查允许提议动作 |
| POST /operational-tasks/{task_id}/retry | 创建新调查轮次,不覆盖上一轮报告 |
| 错误码 | HTTP | 含义 |
| --- | --- | --- |
| 请求体校验错误 | 422 | 新报告缺字段、未知枚举、无关键缺口或相互矛盾的字段 |
| REPORT_GAP_EVIDENCE_INVALID | 422 | 缺口依据不在报告的证据集合内 |
| REPORT_NOT_FOUND | 404 | 指定任务中的报告修订不存在 |
| REPORT_ACTION_PENDING | 409 | 缺数退出仍有关联的未决动作 |
| INVESTIGATION_ENDED | 409 | 本轮已经发布缺数退出报告,再写成果需要新轮次 |
| ACTION_CONCLUSION_REQUIRED | 409 | 没有本轮已形成结论的报告,不得生成动作 |
complete 接口保留已有返回方式:不完整成果会把 run 标为 failed,
failure_code 为 ARTIFACT_INCOMPLETE;调用方须读取返回的业务状态,不能只看 HTTP 200。
## 缺数报告示例
以下为 agent-artifacts 请求中 report 字段的完整示例。
`sample-query-empty` 必须是同一任务内已持久化的空查询证据;示例本身不构成真实查询事实。
```json
{
"title": "水质投诉调查报告",
"current_conclusion": "缺少投诉时段的末梢采样,无法确定异常来源。",
"conclusion_boundary": "已核对可用记录,本轮未确认水质异常原因。",
"evidence_refs": ["sample-query-empty"],
"recommendations": [],
"pending_items": [],
"stage": "final",
"outcome": "insufficient_data",
"stop_reason": "关键采样数据缺失,本轮调查结束。",
"data_gaps": [{
"gap_id": "terminal-sample-gap",
"node_id": null,
"missing_data": "投诉时段末梢水样检测结果",
"scope": "投诉小区,2026-09-24 08:00 至 09:00",
"impact": "无法判断异常来自供水管网还是用户端。",
"required_data": "该地点和时段的采样检测记录",
"evidence_refs": ["sample-query-empty"],
"blocking": true
}]
}
```
## 验收
- 新写入缺字段、不一致结果、无证据的关键缺口、未知业务证据或动作引用均被拒绝。
- 关键数据不足保存报告并正常结束;无运行失败、无待人工通知、无后续动作。
- 阶段性报告不能冒充最终报告;旧代结论不能授权新代动作。
- 已有未决动作阻止矛盾的缺数退出;重试幂等,不重复生成报告。
- 新轮次保留旧报告历史标识,不能显示成当前轮次已结束。
- 桌面及 320/375px 展示结果、缺口、证据,审批区不出现数据授权入口。
- 新发布拒绝超长摘要、正文执行字段、完整技术编号、原始时间表达和未支持的格式标记;
相同历史报告仍可读取,结构化证据引用与带偏移的采样时间保持不变。
- 生成结果结论在前、明细入表,明确单位、时间和各自覆盖范围;
候选、现场反馈、单帧复核与长期监测保持各自含义,进展和图示不与当前事实冲突。
## 发布、阅读与协作
执行中尚未形成结论的正文和 Mermaid 使用独立的 `progress` 快照按需整理,
在路线调整、重要结果或报告归纳时更新即可,不要求逐步更新或及时同步。
见 [调查进展与实时展示](investigation-progress-and-presentation.md)。
报告的 interim/final 与 concluded/insufficient_data 结果契约保持不变。
每次发布保留 `operational.report.published` 同步事件。首次 final、阶段报告转 final、
新轮次 final 或判断/边界/依据/建议/缺口实质变化时,生成 `report_updated` 通知,
其中 `report_reference = {execution_generation, revision}`。纯图示修订不生成额外成果提醒。
新提醒取代同任务之前的成果提醒;读取相应报告后按用户确认已读。
前端在调查列表显示“新报告”,这类提醒不进入“待办与告警”。
正在阅读的报告和图示固定在所选修订,收到更新后显示“查看新报告”,不自动替换正文。
当前待审核动作单独读取最新真实状态,即使用户正在阅读旧报告也不会审批旧版本。
协作请求 `task_context` 可携带 report_revision、evidence_id、gap_id;轮次和报告修订号由
Agent 服务根据 Server 返回的快照生成 `data-task_context`,随回答流和历史消息持久化。
该引用说明回答依据,不授予访问权限,也不成为执行约束。