fix(report): make density facts readable and printable
Independent Staging Quality Gate / validate (push) Failing after 11m4s
Independent Staging Quality Gate / publish (push) Skipped

Unify reader cleanup rules, lock writer table guards, and register the exact fictional timestamp collision. Preserve existing ordinary-report safety contracts and source-data gaps.

Validation: report Node 165/165, final safety 29/29, Python 101/101, Chrome 28/28; both PDFs retain all 130 rows. Full Node 3704 tests with the same 91 baseline failures. Privacy test: 62 passed, 1 failed due to 17 protected-file READ_ERRORs; not a green gate. Build, DB, manual checklist and controlled-login gaps remain documented. User explicitly authorized staging push with these gaps disclosed.

Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
jesse-ux
2026-09-23 15:26:25 +08:00
co-authored by Claude Code
parent 0d37bec15a
commit a12f2c0d26
27 changed files with 1220 additions and 210 deletions
+112
View File
@@ -13296,6 +13296,86 @@
- 复发自:无
- 修复版本:本分支,尚未部署
## BUG-1003 | 对外原始附录带出工程状态词与第三方页码
- 状态:investigating(原实现已合入 staging,本轮清洗一致性修复待验证,未确认部署)
- 首次发现:2026-09-22
- 最近更新:2026-09-23
- 影响面:`/api/professional_report_reference` 的对外 Markdown、报告独立原始附录下载;内部审计与 CLI 不变。
- 用户现象:附录出现内部函数名、工程状态词、第三方引擎名与产品页码。
- 触发条件:原始引擎导出作为读者附录返回,而非普通正文投影。
- 根因:内部审计与读者副本未分开;BUG-999 的普通正文 allowlist 不覆盖附录。初版 Python / TS 两份规则又因 Unicode 单词边界不同漏掉 Python 第三方页码。
- 修复:`bbd96d3b` 增加读者副本清洗;本轮 F4 将 Python / TS 规则收敛为 scripts 下共享 JSON,正则采用相同 ASCII 边界,保留行数、原始字段、英文散文与图盘围栏,不以整行删除代替翻译。
- 验证:本轮主会话报告定向 165/165、Python 定向 101/101 通过,含完整虚构 golden 两端逐字一致、页码归零及行/表/数字/图盘字节保留。前轮相差 36 行的问题已有回归覆盖;完整门和部署仍未通过,详见 PROGRESS。
- 防复发:保留 `test_reader_appendix_language.py` 与前端原始附录清洗 / golden 回归;F4 必须覆盖同一真实引擎虚构 fixture 两侧逐字一致及页码归零。普通正文投影与安全边界不变。
- 相关记录:BUG-999、BUG-1004;`TASK-report-density-fix-20260923.md` F4
- 复发自:BUG-999 同现象族的未覆盖通道,不是撤销普通正文限制。
- 修复版本:原实现 `bbd96d3b`;本轮工作树修复待验证,未确认部署。
## BUG-1004 | 读者没有独立完整原始附录入口
- 状态:investigating(入口已实现,受控浏览器与部署待验)
- 首次发现:2026-09-22
- 最近更新:2026-09-23
- 影响面:报告下载动作、`POST /api/reports/[reportId]/raw-appendix`、新长报告计算快照。
- 用户现象:普通下载只提供净化正文,完整计算表不能作为独立附录取得。
- 触发条件:用户需要核对原始表格,但只有 BUG-999 建立的普通正文下载通道。
- 根因:缺独立附录产物与入口;不能把完整表格塞回普通正文投影作为补救。
- 修复:`bbd96d3b` 新增独立附录路由和下载动作,普通 Markdown 仍走原投影。新计算通过既有 section RPC 持久 snapshot,重试从快照恢复结构化数据;快照行从章节列表及错误聚合排除。旧 Markdown-only 缓存不回填。
- 验证:前轮验收入口与快照读写静态核对通过;`personal-report-density-retry.test.ts` 已含中断、并发、损坏绑定、旧缓存等用例。测试存在不等于本轮通过;登录态下载与重试真人证据仍缺,见 PROGRESS。
- 防复发:`personal-report-raw-appendix.test.ts`、`personal-report-density-retry.test.ts` 与 `report-public-projection.test.ts` 分别守住独立附录、快照恢复和普通下载不变;不能让 snapshot 成为 writer 章节,不能借附录授权放宽 XSS / 危险 URL 合同。
- 相关记录:BUG-999、BUG-1003、BUG-1005
- 复发自:无;为经产品授权新增的独立通道,普通下载限制仍有效。
- 修复版本:`bbd96d3b` 已合入 staging;未确认部署。
## BUG-1005 | 个人报告没有可承载引擎事实表的结构化层
- 状态:investigating(事实层已实现,可读性与打印补修待验)
- 首次发现:2026-09-22
- 最近更新:2026-09-23
- 影响面:报告契约、服务端装配、报告页事实表与 writer 边界。
- 用户现象:引擎已有大运、力量、功能吉凶等表,但报告只有叙述与图盘;初版补表后又把路径清单显示给读者,见 BUG-1009。
- 触发条件:生成包含上述已计算层的个人报告。
- 根因:原报告没有 `factTables`;初版未规定用户列结构,writer 拒绝表格与打印闭合也缺回归覆盖。
- 修复:`bbd96d3b` 增加 8 组服务端事实层,不给 writer 可写字段;保留证据状态。F1 补真正列结构,F5 补 writer 提示与拒绝测试,F6 补全折叠时打印。Sade Sati 只展示源中已有框架,三轮日期计算范围外。
- 验证:本轮报告定向 165/165、Python 定向 101/101 通过;writer 去拦截变异使 4 个拒绝用例全部变红,正常对照仍绿。Chrome 153 隔离真实组件 28/28,全部折叠与混合状态 PDF 各 5 页、各 130/130 行完整,打印后恢复;不是受控登录 E2E。完整构建受 Windows symlink EPERM 阻塞,尚未提交或部署。
- 防复发:`report-fact-tables.test.ts` 真实 golden 与逐行来源回查不可削弱;writer 的 Markdown / HTML 表格或 `factTables` 输出必须 fail closed;打印测试必须从全折叠状态开始并核对打印后恢复。
- 相关记录:BUG-1009、BUG-153、BUG-999;修复单 F1/F5/F6
- 复发自:BUG-153 的打印合同遗漏新增事实表 disclosure;旧静态合同不能证明关闭的 details 进入 PDF。
- 修复版本:原实现 `bbd96d3b`;本轮补修待验证,未确认部署。
## BUG-1006 | 报告契约分盘种类上限不足
- 状态:investigating(16 种契约已实现,本轮构建与真机待验)
- 首次发现:2026-09-22
- 最近更新:2026-09-23
- 影响面:`CHART_IDS`、长报告分盘装配、报告页布局。
- 用户现象:引擎可提供更多分盘,但报告契约只接受 9 种,无法交付约定的 16 张。
- 触发条件:新生成完整个人报告并查看分盘。
- 根因:契约枚举和服务端交付层未承载完整目标分盘集合。
- 修复:`bbd96d3b` 将枚举扩为任务书指定 16 种,装配真实宫位与星体,沿用 BUG-616 grid/card 和 BUG-617 memoized 文章树;旧 v1 枚举兼容保留。
- 验证:前轮验收记录 `/` Static、gzip +0.007%,golden 覆盖 16 盘完整宫位;本轮未重跑,不作为修复版通过。16 张盘不重叠、滚动不重建及旧报告读取待受控浏览器复核。
- 防复发:`report-fact-tables.test.ts` 检查图盘完整性;`personal-report-markdown-view.test.tsx` 中 grid、禁止 float / 负 margin 与文章无滚动态合同仍在,不得只检查是否存在 SVG。
- 相关记录:BUG-616、BUG-617、BUG-1005
- 复发自:无;分盘扩容须持续遵守旧布局与性能防线。
- 修复版本:`bbd96d3b` 已合入 staging;未确认部署。
## BUG-1007 | 辅助大运族缺少读者可理解的适用性说明
- 状态:investigating(新生成路径已实现,回归与真人待验)
- 首次发现:2026-09-22
- 最近更新:2026-09-23
- 影响面:新报告原始附录的辅助时间轴适用性说明。
- 用户现象:辅助大运只剩状态词,不能看出是否适用、缺什么,以及只能交叉核对的边界。
- 触发条件:读取辅助大运族数据,包括引擎已算出但仍限制可断言程度的层。
- 根因:对外附录缺读者语言说明,未把引擎适用性和使用边界一同交付。
- 修复:`bbd96d3b` 对 16 个大运族提供逐族说明,读取引擎 `applicable` 而不自行放宽;标明第二时间轴、不单独生成应期。新快照保存说明,旧 Markdown-only 缓存不补算、不回填。
- 验证:前轮验收记录 16 族各有白话说明、模块不自行判定;本轮清洗变化后的回归与受控下载待验。
- 防复发:真实 golden 的附录 / durable retry 回归须保住适用性与限制;普通正文投影不能接纳这些替代时间轴成为断言,旧缓存缺证据必须如实降级。
- 相关记录:BUG-1003、BUG-1004、BUG-999
- 复发自:无;不把展示授权当作证据等级升级。
- 修复版本:`bbd96d3b` 已合入 staging;未确认部署。
## BUG-1008 | 任务书写入真实个人出生资料并推到 staging
- 状态:mitigated(staging 历史已重写,不再含该资料;旧提交在 Gitea 上仍可按 SHA 匿名访问,待服务器垃圾回收)
@@ -13313,3 +13393,35 @@
- 相关记录:BUG-999
- 复发自:无(与 2026-09-20 的本仓个人案例清除属同一类资料)
- 修复版本:`abf28321`(HEAD 清除);历史重写见上
## BUG-1009 | 普通报告事实表显示引擎字段路径而不是可读列
- 状态:investigating(F1 修复执行中,待定向与独立验收)
- 首次发现:2026-09-23
- 最近更新:2026-09-23
- 影响面:`assembleReportFactTables`、事实表渲染、普通报告可见单元格。
- 用户现象:8 组表为“原始字段 / 数值或状态”两列键值清单;出现 snake_case、数组下标、内部时间字段,主运年数还可能被出生时剩余量替代。
- 触发条件:查看原报告密度实现新增的普通报告事实表。
- 根因:原任务书只要求可追溯,未明确用户列结构;实现把来源路径直接当行名。普通正文的 BUG-999 投影不覆盖这块新增结构化渲染。
- 修复:F1 按修复单逐组改成主运 / 分运 / 小运、SAV / BAV、六分量、功能吉凶、行星状态、特殊点、阶段框架、年度与 Saham 表。来源保留在不可见 `sourcePath`,数字不补算,主运年数与出生剩余量分开。
- 验证:前轮 948 个叶子行的缺陷证据不再作为新表行数合同。本轮真实 golden 的 8 组、11 张实际表、130 行、545 单元格在 Chrome 完整渲染;可见 snake_case、数组下标、超两位小数均为零;Node 回归核对来源路径、原始数值与缺值不补算。首段主运直接取 full_years 显示 18.00,余额 0.72 仅说明;年度源无行星位置,保留空表,不冒用本命数据。构建与登录 E2E 缺口见 PROGRESS,尚未部署。
- 防复发:使用真实引擎虚构 golden,同时测试可见内容与来源追溯;不能只通过“值来自引擎”就宣称面向读者可读,不能削弱 BUG-999 普通正文安全合同。
- 相关记录:BUG-1005、BUG-999;`TASK-report-density-fix-20260923.md` F1
- 复发自:BUG-999 同现象族的新增表格通道,旧正文测试未覆盖。
- 修复版本:缺陷引入 `bbd96d3b`;修复在 `codex/report-density-fix-20260923` 工作树实施,待验证,未确认部署。
## BUG-1010 | 新虚构 fixture 的隐私扫描数值碰撞未登记
- 状态:investigating(F2 按精确数值碰撞机制处理,待本轮验证)
- 首次发现:2026-09-23
- 最近更新:2026-09-23
- 影响面:`tests/test_repo_privacy_markers.py` 与 `frontend/tests/fixtures/report-density-fictional-reader.json`。
- 用户现象:无用户界面现象;质量门隐私扫描命中虚构引擎时间戳的数值片段,阻断发货。
- 触发条件:新增真实引擎虚构 golden 后运行仓库隐私门。
- 根因:时间戳数值与私有标记发生碰撞,但新 fixture 未登记到既有已审阅数值碰撞机制;不是 fixture 包含真实个人资料。任务书真实泄漏另见 BUG-1008,不得混称误报。
- 修复:F2 只登记已审阅的单处数值碰撞,说明来自虚构输入的引擎时间戳;不更改私有标记、扫描规则,也不豁免整份 fixture 或目录。
- 验证:前轮独立重跑已复现该虚构时间戳,本轮没有重跑引擎。主会话转述 F2:精确登记及反例 62 passed / 1 deselected;完整专项用 audit hook 尊重 `pending_packets` 禁读,62 pass / 1 fail(17 个保护文件 READ_ERROR),其余 4,647 文件无命中。完整隐私门未绿,不能标 resolved;不复制碰撞数值或私有 marker。
- 防复发:新增 golden 必须保留虚构来源声明并跑隐私扫描;数值碰撞逐处核实、精确登记,真实泄漏必须分别清除,不能靠扩大 allowlist 隐藏。
- 相关记录:BUG-1008、BUG-1009;`TASK-report-density-fix-20260923.md` F2
- 复发自:无;既有扫描正确触发,缺的是已核实碰撞的精确登记。
- 修复版本:缺陷引入 `bbd96d3b`;F2 工作树修复待验证,未确认部署。