fix(report): project ordinary reports onto public prose only

This commit is contained in:
jesse-ux
2026-09-22 12:13:53 +08:00
parent 337d820076
commit dd4141a030
17 changed files with 1401 additions and 48 deletions
@@ -0,0 +1,44 @@
# 进度 · 普通用户报告公开内容分层(2026-09-22)
基线:`origin/staging` `10baeb2fa865743c428806e115ac92ca9d92fb71`。分支 `codex/report-public-content-20260922`。未推送。
聊天消息行仍然不渲染 `techniqueTruth``workflowReceipt`、证据徽章和单条下载按钮(`chat-message-row.tsx` 无这些符号;`consultation-report-export.test.ts` 的「assistant answer does not expose internal report controls」仍在)。漏洞在导出和报告 API。
## 投影
- 新增 `frontend/src/lib/report-public-projection.ts`。文档类型是显式参数:`chat_export``personal_report_detail``ordinary_markdown_download``professional_reference`。不根据路由名决定可见性。
- 普通 allowlist`title``prose``conclusion``action``limitation``chart_fence``engine_svg`
- 内部字段不序列化:`technique_truth``workflow_route``workflow_status``precise_timing``missing_layers`、评分/权重/执行账本、内部 URL、secret、模型调试、raw tool response、job/attempt/provider。
- 限制改写成白话,不带内部键。没有这些信号时不补限制段。
## 接入
- `consultationReportMarkdown` 只走聊天导出投影。
- `resolveReportRead``longformMarkdown` 与返回给浏览器的 `reportDocument` 走投影。持久化行不改。
- `classifyReportEnvelope` 在详情阅读前再投影一次,旧响应也不能直接上屏。
- 普通下载读 `GET /api/reports/:id`,并用 `ordinaryReportDownloadMarkdown` 投影后再去掉 `jyotish-chart` 围栏。不再请求 professional-reference。
- 列表 `card_summary` 走同一段公开正文投影。
- professional-reference 仍是独立入口,响应 `documentKind``professional_reference`。本轮没有单独专业权限,正文 fail-safe 到普通投影,避免只靠接口名字放行内部字段。
## 断言变化
| 测试 | 原值 | 新值 | 原因 |
| --- | --- | --- | --- |
| `consultation-report-export.test.ts`「exports latest consultation answer…」 | 匹配 `technique_truth: partial``workflow_route: career``precise_timing: blocked``missing_layers: MEVG``未闭环内容不得包装成确定预测` | 仍匹配标题和「先看阶段」;匹配白话限制;不匹配上述内部键、`MEVG``career``Claim boundary` | 这些内部字段不再是普通导出的预期结果 |
| `personal-report-entry.test.ts`「legacy consultation Markdown export…」 | 匹配 `workflow_route: career``precise_timing: blocked` | 匹配「先看阶段」和「这次说不到具体哪一天」;不匹配 `workflow_route``precise_timing``technique_truth``MEVG` | 同一导出合同,不能继续把泄漏当回归锁 |
| `personal-report-entry.test.ts`「ready reports expose Markdown export…」 | `longformDownloadSource` 匹配 `professional-reference` | 不匹配 `professional-reference`;匹配 `projectOrdinaryReportMarkdown``GET /api/reports/:id` | 普通下载不得再把专业参考当 fallback |
| `professional-report-reference-route.test.ts`「cached appendix returns markdown…」 | `{ format: "markdown", markdown: "# Professional reference" }` | 增加 `documentKind: "professional_reference"`markdown 仍是该句 | 响应必须显式标成专业参考;这条夹具没有内部字段,正文保持原样 |
`personal-report-longform-md.test.ts` 的 XSS / 表格 / `skipHtml` 断言未改。报告归属与 ready 检查的测试名未改,`{ ok: true }` 回放文档不是报告形状,原样返回。
## 验证
- `frontend``.\node_modules\.bin\tsc --noEmit` 退出码 0。
- `npm run lint`0 error119 条既有 warning(未改;新投影文件无 warning)。
- 定向 `npx tsx --test``report-public-projection` 9、`consultation-report-export` 2、`personal-report-entry` 20、`personal-report-longform-md` 7、`personal-report-view` 23、`report-chart-block` 8、`professional-report-reference-route` 4、`personal-report-api` 58,全部 fail 0。
- 未跑全量 `npm test``next build`
- 无登录态,浏览器导出未验收:`docs/testing/report-public-content-20260922.md`
## Bug
BUG-999resolved(本地候选,未部署)。相关记录 BUG-011、BUG-058、BUG-188。聊天层隐藏仍在,本条记导出/API 洞,不把旧记录改成复发。