docs(report): add MD-only first-run failure forensics brief
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016P5RoqzmUQEbeC2qjAkeGr
This commit is contained in:
@@ -0,0 +1,58 @@
|
||||
# 任务书 · MD-only 首跑失败取证与修复(2026-09-07)
|
||||
|
||||
基线:`origin/staging` @ `7cf7705a`(开工 `git fetch` 后以 HEAD 为准)。
|
||||
|
||||
## 事故实证
|
||||
|
||||
- 2026-09-07 05:14 UTC 用户创建 personal_full(5 主题),**MD-only 路径第一次真实运行**:`failed / calculation_unavailable`,`progressPercent=30 / progressPhase=failed`(引擎调用阶段)。报告 id `de2c2efb-9f1e-4cc6-8dc3-72bdfdb3b977`,requestId `d17c27ef-2ceb-4dd8-af4d-12107b4de7e4`。当时部署 `72dd5e9d`(含 BUG-574 修复与 MD-only worker)。
|
||||
- **委托方本地复现排除了代码路径**:最新 staging 代码起本地引擎,按 `buildLongformBirthPayload` 同形 payload(虚构盘 + provisional + candidate_range + packs:["full"] + markdown)POST `/api/professional_report_reference` → **HTTP 200、3.3 秒、315KB**。代码与合同没问题,失败是 **staging 环境特有**。
|
||||
- detail API 未透出附录错误码(观测缺口,本轮补)。
|
||||
|
||||
## 两个可判别嫌疑(任务 0 一条查询定案)
|
||||
|
||||
`generatePersonalReportLongform` 失败时把错误类别写进 `personal_report_longform_appendices.last_error_code`:
|
||||
|
||||
| last_error_code | 含义 | 指向 |
|
||||
|---|---|---|
|
||||
| `upstream_unavailable` / `upstream_busy` | 引擎 HTTP 非 200 | **嫌疑 A:staging api 容器版本滞后**(web 随 deploy 更新,api 容器若未随部署重建,端点行为/参数支持与 web 不配套)或引擎在该输入上 500 |
|
||||
| `generation_failed` | 非 LongformGenerateError(180s `AbortSignal.timeout` 的 TimeoutError 落这里) | **嫌疑 B:staging 上全量 pack 超 180 秒**(外部 VedAstro 网关串行拉满;本地 3.3s 是因外部层快速 blocked) |
|
||||
| `empty_markdown` | 200 但空文 | 引擎版本/参数不配套的另一种表现(同嫌疑 A) |
|
||||
|
||||
## 任务 0(P0,门控)· staging 取证定案
|
||||
|
||||
1. 查 requestId `d17c27ef…` 的 appendix 行:`status / attempt_count / last_error_code`。
|
||||
2. web 容器日志该时段 `[personal-report]` 行;api 容器访问日志有无对应 `POST /api/professional_report_reference` 及其耗时/状态码。
|
||||
3. **api 容器运行版本**:镜像构建时间 / 容器内代码是否含 `professional_report_reference` 最新实现(gaps2 的 `e4d16b75` 级别);对照 deploy 管线是否会重建 api 容器。
|
||||
4. 从 web 容器内对 `api:5200` 手工 POST 同形 payload(虚构盘)计时与状态码。
|
||||
|
||||
PROGRESS 写明定案(A / B / 其他),再进任务 1。
|
||||
|
||||
## 任务 1(P0)· 按定案修复
|
||||
|
||||
- **定案 A(api 容器滞后)**:把 api 容器纳入部署链(或把"api 容器更新步骤"固化进 deploy 流程与 runbook),更新后复测;防复发:health 增加引擎版本/构建指纹字段,web 与 api 版本不配套时可见。
|
||||
- **定案 B(超时)**:不许一上来就调大 180s——先量真实耗时构成(外部网关占比);优先让报告路径的引擎调用带 `defer_optional_external_evidence`(或等价参数)跳过/并行可选外部证据(引擎已有该机制,consultation 前台路径在用),把确定性本地全量控制在可预算时间内;外部层缺席按诚实标签落 blocked 行(gaps2 静默跳过禁令继续适用)。超时值若仍需调整,用实测数据定,写 PROGRESS。
|
||||
- 任何情况下:`calculation_unavailable` 保持 retryable 语义,但确认 job 三次尝试真实发生且每次都调用了引擎(时间戳对齐)。
|
||||
|
||||
## 任务 2(P1)· 观测补口
|
||||
|
||||
- detail API(失败报告)透出 appendix 的 `last_error_code`(错误码级,不含内容),报告页失败态显示可读原因——本轮取证难就难在这个码埋在表里。
|
||||
- worker 引擎调用记录耗时与 HTTP 状态(数值日志)。
|
||||
|
||||
## 任务 3(P0 收尾)· 收官 smoke 重跑
|
||||
|
||||
修复部署后按 `docs/operations/personal-report-staging.md` smoke:列表/详情/创建,创建走到 ready——**这是报告线的最终收官项**:~30s(或实测预算内)ready、详情页 TOC/宽表、导出 .md、0 用量计费结算、新卡片 `card_summary` 显示。
|
||||
|
||||
## 硬红线
|
||||
|
||||
既有全部延续(迁移规范、诚实标签、静默跳过禁令、不改 `.gitea/workflows/**`、不提升 main、`./node_modules/.bin/tsc`、真实用户资料不入库、日志无内容)。**取证要快**——容器 recreate 丢日志的教训已发生过一次。
|
||||
|
||||
## 收尾
|
||||
|
||||
`docs/tasks/PROGRESS-report-longform-e2e-fail-20260907.md`;`docs/BUG_HISTORY.md` 条目(编号对远端);不提升 main。
|
||||
|
||||
## 交付物清单
|
||||
|
||||
1. 任务 0 四项取证与定案
|
||||
2. 按定案的修复 diff + 防复发项(api 版本可见性 或 外部证据 defer + 实测耗时表)
|
||||
3. 观测补口 + 测试
|
||||
4. 收官 smoke 全项记录
|
||||
Reference in New Issue
Block a user