Files
Jyotisha/docs/tasks/TASK-report-density-fix2-20260923.md
T
Jesse_ChenandClaude Opus 5.5 451a58089a docs(tasks): correct how BUG-1011 must be fixed
Gate run 2857 on 36a73761 ran 3,762 tests with one failure, the report
snapshot database test, so it is the last thing between staging and a deploy.

The brief told the executor to move the shared psql and psqlAs helpers to
stdin. That instruction is withdrawn. The two helpers serve 522 calls across
29 test files, and psql -c runs a multi-statement string as one implicit
transaction. selectAsAuthenticated relies on that: it sets the JWT subject
with set_config(..., true), which lasts only for the current transaction.
Statement-at-a-time execution would run every later RLS query with no user
set, so those tests would stop testing what they claim to test. Five other
files also write their own begin, commit or rollback.

The brief now asks for a separate single-transaction stdin helper with an
explicit maxBuffer, used only by the snapshot test, with a test proving a
transaction-local set_config stays visible. It also says that if the snapshot
test then fails a real assertion, that is a product defect to report, not an
assertion to relax.

Privacy scan on this tree before push: zero findings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8
2026-09-23 17:29:44 +08:00

7.8 KiB
Raw Blame History

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 打印 通过(真浏览器待清单) 打印前展开全部 <details>、打印后恢复原状态;打印样式避免行跨页
前端 通过 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> 传入。按测试同样的构造方式生成的 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 与测试名,不得声称已绿。

开工前置命令

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 记录)。开工时核对最大号。