# TASK-report-density-fix2-20260923 · 报告快照数据库测试无法启动 ## 基线 commit - **2026-09-23 更新**:`origin/staging` = `8c2db687`。门禁 run 2857(`36a73761`)真实日志:3,762 tests / 3,761 pass / **1 fail**,唯一失败即本单测试,报错 `spawnSync docker E2BIG`,位置 `tests/helpers/postgres-fixture.ts` 的 `psqlAs`。**本单是 staging 恢复部署前的唯一阻塞。** - 被验收实现:`a12f2c0d`(`fix(report): make density facts readable and printable`,已在 `origin/staging`;门禁 run 2856 红(初版误写为 6294,那是 Gitea 任务 id),未部署,`/api/health` 仍为 `1bc6a954`) - 修复分支:`codex/report-density-fix2-20260923`,从 `origin/staging` 起 ## 上一轮修复单验收结论 `TASK-report-density-fix-20260923.md` 的 F1–F6 **全部通过**,只剩本单一项。 | 项 | 结论 | 证据 | |---|---|---| | F1 事实表可读 | 通过 | fixture 上 8 组、130 行、600 个可见格:引擎键名 0、数组下标 0、超过 2 位小数 0;130 个 `sourcePath` 全部能在 packet 中取回;主运表首段"年数"为 18.00,出生剩余 0.72 年移入说明;年度盘为空是因为 packet 确实没有年度行星位置,说明如实写"未返回" | | F2 隐私门 | 通过 | 登记只放行那 5 个字符:钉死 fixture 来源、JSON 节点、行号与整行内容;负向测试证明多一处、换输入、换行都会重新报错。本机 `test_repo_privacy_markers.py` 全过 | | F3 记录 | 通过 | BUG-1003~1007、1009、1010 已写,状态如实为 investigating;PROGRESS 含三栏说明;"未提交、推送"已更正。真人清单执行方被工具拒写,已由 Claude 补写 `docs/testing/report-density-20260922.md` | | F4 规则一份 | 通过 | 共用 `scripts/reader_appendix_language.rules.json`;同一份 fixture markdown,Python 与 TS 输出逐字节相同,"第 N 页"为 0,行数不变 | | F5 写表拦截 | 通过 | 去掉拦截后 6 条新测试红 4 条,恢复后全绿;writer 提示词已写明不输出表格 | | F6 打印 | 通过(真浏览器待清单) | 打印前展开全部 `
`、打印后恢复原状态;打印样式避免行跨页 | | 前端 | 通过 | Node 22:基线 3,730 / 26 失败 → 3,748 / 26 失败,名单逐条一致 | | tsc / lint / build | 通过 | 0 错 / 0 error;`/` 仍 `○ Static`;首屏 gzip 623,329(与上一轮相同) | | Python 快速门 | 通过 | 基线 946 passed / 1 failed(隐私)→ 948 passed / 0 failed | | 数据库测试 | **未通过(本单)** | 见下 | P3 各项未修,按原修复单不算未通过:复合状态译成重复短语 318 次、`unclosed_divisional_chart` 等四个状态词仍在附录、`北交点Rahu` 这类中英拼接来自引擎自带字段。 ## 事故实证 `frontend/tests/database-personal-report-sections.test.ts` 的快照一例把整份快照内联进 SQL,经 `tests/helpers/postgres-fixture.ts` 的 `psqlAs` 以 `psql -Atc ` 传入。按测试同样的构造方式生成的 SQL 为 **428,557 字节**,是单个命令行参数;Linux 单参数上限 `MAX_ARG_STRLEN` 为 131,072 字节。验收时把同一段 SQL 以同样方式传给 `/bin/true`,结果 `spawn E2BIG`。 所以这条测试在门禁(Linux + Docker)上启动 psql 之前就失败。快照行在真实 Postgres 里的写入、重复写入保留首版、他人不可读三条性质,**至今没有任何一次真实运行**。执行方两轮都因 Docker 地址池耗尽没跑,验收机没有 Docker。 ## 根因 测试辅助函数把 SQL 放在命令行参数里。以前的数据库测试 SQL 都很短,从未碰到上限。 ## 决策记录 - 本单不推翻任何决策。 - 修的是测试的传参方式,不是缩小测试数据。**共享的 `psql` / `psqlAs` 不改**(见 G1 更正)。**不得用更短的 markdown 或裁剪过的快照来"让它过"**:快照体积正是要验证的东西之一。 ## 硬红线 1. 快照内容保持真实全量(fixture 原样)。 2. 不改 `personal_report_sections` 表结构、RPC 或迁移。 3. 不得修改 `psql` / `psqlAs` 的行为;所有既有数据库测试必须照常通过;不得跳过、不得标 skip。 4. 不得强推、rebase 或重写 `staging`。 5. 测试总数不得低于门禁 run 2857 的 3,762。 ## 任务分解 ### G1 · 为大脚本新增专用辅助函数(BUG-1011) > **更正(Claude,2026-09-23)**:本单初版写"`psql` 与 `psqlAs` 改为经标准输入传 SQL"。**这条作废,不得照做。** 这两个共享辅助函数被 29 个测试文件调用 522 次。`psql -c` 把多语句字符串当**一个隐式事务**执行,改成标准输入后每条语句各自提交,语义就变了。典型受害者是本文件自己的 `selectAsAuthenticated`:它用 `set_config('request.jwt.claim.sub', …, true)` 设定当前用户,第三个参数 `true` 表示只在当前事务内有效。在 `-c` 下这个设置对后面的查询生效;改成逐条提交后,后面的查询会**在没有登录用户的情况下**跑,RLS 断言可能因此通过或失败,但都不再测它该测的东西。另有 5 个文件在 SQL 里显式写了 `begin` / `commit` / `rollback`。 做法: - `psql` / `psqlAs` **一字不改**。 - 在 `tests/helpers/postgres-fixture.ts` 新增一个专用函数(名字自定,例如 `psqlScriptAs(role, password, sql)`),经标准输入传 SQL:`execFileSync` 的 `input: sql`,psql 参数用 `-X -At -v ON_ERROR_STOP=1 --single-transaction -f -`。`--single-transaction` 让整段脚本仍是一个事务,与 `-c` 的语义对齐。 - 该函数显式设置 `maxBuffer`(例如 16 MB)。Node 的 `execFileSync` 默认输出上限只有 1 MB,而本测试读回的快照已有约 43 万字节,体积再涨就会 `ENOBUFS`。读回快照的那次 `psql(select payload …)` 同样改用能设 `maxBuffer` 的方式,或者只读回 `payload` 的哈希并与本地哈希比较。 - 只把本测试里内联快照的那一次调用换成新函数,其余调用不动。 **验收标准**: - 新增一条辅助函数测试:经新函数执行一段超过 131,072 字节的 SQL,并取回结果; - 同一条测试里再验证事务语义:新函数内先 `set_config(…, true)`、下一条语句读 `current_setting(…)`,必须读得到(证明仍是单事务); - 门禁 run 里 `database-personal-report-sections.test.ts` 与全部既有数据库测试通过,把 run 编号、job 编号与该测试名写进进度记录。本机能跑 Docker 就再贴本机结果;不能跑就只以门禁为准,不得写"本地通过"。 **E2BIG 修好后,这条测试才第一次真正连上 Postgres。** 如果它在真实断言上失败(快照写不进去、重复写入没保留首版、他人能读到),那是**产品缺陷**,不是测试问题:停下来,把失败原文写进 BUG-1011,另报给 Claude,**不得为了过门禁改断言或裁剪快照**。 ### G2 · 记录 `docs/BUG_HISTORY.md` 中 BUG-1011 按结果更新;进度记录追加本单一节。 ## 让步顺序 只有 G1、G2 两项,都必须做。 ## 已知且不属于本单的门禁红 ~~staging 门禁另有既有红项~~ —— 已由 `TASK-staging-gate-red-20260923.md`(`36a73761`,BUG-1012~1014)修复并验收。门禁 run 2857 只剩本单这一条失败;本机因缺 Docker / rsync 失败的那些测试在门禁上全部通过。**本单合入后门禁应当转绿**;若出现别的失败,列出 run 与测试名,不得声称已绿。 ## 开工前置命令 ```bash git fetch origin --prune git status -sb git worktree add -b codex/report-density-fix2-20260923 .worktrees/report-density-fix2-20260923 origin/staging docker info # 没有 Docker 就按 G1 最后一条走门禁证据 ``` ## BUG 编号 BUG-1011(已由 Claude 写入 investigating 记录)。开工时核对最大号。