Files
Jyotisha/docs/tasks/TASK-report-public-content-20260922.md
T
2026-09-22 11:19:35 +08:00

85 lines
6.2 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.
# 任务书 · 普通用户报告公开内容分层与导出投影(2026-09-22)
## 0. 基线与先决条件
- 基线 commit:`1bc6a954c597e2817fe72bfedad93119ab19a527`;开工前 fetch 并以最新 `origin/staging` 重核。
- 执行分支:`codex/report-public-content-20260922`;工作树:`.worktrees/report-public-content-20260922`。
- 业务已拍板:普通用户导出的报告隐藏内部技法和工作流字段;只保留用户可读正文、结论和必要限制说明。专业参考若保留,另立明确入口和规则。
- 本单与人物 other 资料无关;不得把报告接入人物切换任务。
- 本单不与人物选择器共享实现文件;如同批执行,先完成服务端 subject binding,再由报告单独接入其 canonical projection,禁止把两种资料真值边界混在同一 helper 中。
## 1. 事故实证
会议反馈:网站生成的报告夹带不该展示的内容,具体字段会上未列清。代码调查确认存在公开合同分裂:
- 普通聊天消息已经按 BUG-011 移除内部证据徽章、Technique Audit、单条回答下载控件。
- `frontend/src/lib/consultation-report-export.ts` 的 `consultationReportMarkdown()` 仍可能序列化 `technique_truth`、`workflow_route`、`workflow_status`、`precise_timing`、`missing_layers`、Claim boundary 等内部字段;现有导出测试仍将其作为预期结果。
- `frontend/src/lib/personal-report-longform-download.ts` 优先使用已有 Markdown,下载前主要去除图盘 fence,没有统一公开内容投影。
- `frontend/src/app/api/reports/[reportId]/professional-reference/route.ts` 会返回已存储的完整 Markdown;接口名是 professional reference,但用户入口可能只是笼统“导出报告”。
- `frontend/src/components/personal-report/personal-report-markdown-view.tsx` 的 HTML/URL/XSS 过滤是结构安全措施,不等于内部字段分类。
相关历史:BUG-011、BUG-058、BUG-086~094、BUG-188。它们已明确内部路由、未执行技法、评分、原始响应和用户敏感内容不得进入普通用户可见层。
## 2. 根因
报告阅读、咨询导出、个人报告下载和 professional-reference 返回的是不同边界:聊天层隐藏了内部字段,但 canonical Markdown/导出/API 没有统一普通用户 allowlist。因此不能只在 React 下载按钮前用正则删除,也不能凭感觉删除会上未定义的内容。
## 3. 决策记录(产品已拍板)
1. 普通用户报告只展示:用户可读正文、结论、行动建议(若业务允许)和必要的限制说明。
2. 普通报告禁止:`technique_truth`、`workflow_route`、`workflow_status`、`precise_timing`、`missing_layers`、内部评分/权重/执行账本、内部 URL、secret、模型调试字段、raw tool response、job/attempt/provider 元数据。
3. 若专业参考仍需展示部分方法证据,必须单独命名、单独入口、单独权限/标识和单独合同;本单不把它混入普通导出。
4. 旧报告不能因缓存或已存 Markdown 绕过新公开规则;优先在服务端 canonical 投影边界统一处理。
## 4. 硬红线
- 不得把普通报告变成内部调试报告;不得把“更专业”当作公开内部执行轨迹的理由。
- 不得只在客户端用脆弱字符串正则作唯一隐私防线。
- 不得破坏 Markdown 的既有 XSS、危险 URL、HTML 和 `jyotish-chart` fence 安全合同。
- 不新增 PDF/Canvas/jsPDF/Playwright/Puppeteer 导出链路,不升级依赖。
- 不修改星盘计算、报告生成算法或人物绑定;只治理公开投影边界。
- 不在 fixture、日志、任务书、BUG 历史中写真实姓名、出生资料、会话原文、凭据、secret。
## 5. 任务分解与验收标准
### T1 · 建立字段级公开投影
- 在服务端/共享 canonical 层新增明确的普通报告投影 helper;字段白名单优先于黑名单。
- 区分聊天导出、个人报告详情、普通 Markdown 下载和专业参考文档类型,不用接口名字猜用户可见级别。
- 内部限制字段若需要保留其产品含义,转成自然语言限制说明,不透出内部 key/value。
验收:每个字段有公开/内部归类;普通报告在同一 synthetic fixture 下只含允许内容;没有字段时不虚构;图盘 fence 规则继续有效。
### T2 · 接入所有普通输出边界
- `consultation-report-export.ts`、`personal-report-longform-download.ts`、报告详情/阅读路径和 API 返回统一使用投影。
- `/professional-reference` 若继续存在,必须显式区分专业参考与普通报告;若本轮不改专业参考,至少阻止它被普通下载路径当作普通报告 fallback。
- 处理旧缓存 Markdown/已存文档:下载和 API 返回不能绕过投影。
验收:页面阅读、下载文件、直接 API 响应与普通公开合同一致;禁止字段不会因缓存命中、旧报告或备用路径复现;专业参考不会被误标为普通报告。
### T3 · 回归与安全测试
覆盖:字段存在/缺失、旧缓存、专业参考路径、图盘 fence、Markdown HTML/script/iframe/object/embed/img、危险 URL、内部 URL/secret/模型字段扫描。保留现有 `consultation-report-export`、`personal-report-longform-md`、报告归属/ready 检查测试名;断言变化写原值/新值/原因。
## 6. 让步顺序
T1 字段合同 > T2 canonical 接入 > T3 回归测试。若专业参考产品边界尚未实现,普通下载必须 fail-safe 使用普通投影,不能以“接口叫 professional-reference”为由透出内部字段。
## 7. 开工前置命令
```bash
git status -sb
git fetch origin --prune
git worktree add -b codex/report-public-content-20260922 .worktrees/report-public-content-20260922 origin/staging
cd .worktrees/report-public-content-20260922/frontend
./node_modules/.bin/tsc --noEmit
npm run lint
npm test
npm run build
```
## 8. 交付记录
同轮写 `docs/tasks/PROGRESS-report-public-content-20260922.md`,更新 `docs/BUG_HISTORY.md`(关联 BUG-011/058/188;若确认新用户可见回归,按开工时最大号连续编号)和必要的 `CHANGELOG.md`。视觉/文案变化同步 `frontend/DESIGN.md` / `frontend/docs/VOICE.md`。没有登录态的浏览器级导出验收写入 `docs/testing/`,不得写成通过。