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
This commit is contained in:
Jesse_Chen
2026-09-23 17:29:44 +08:00
co-authored by Claude Opus 5.5
parent 8c2db6874d
commit 451a58089a
3 changed files with 25 additions and 14 deletions
+1 -1
View File
@@ -171,7 +171,7 @@
| --- | --- | --- | --- | --- |
| `TASK-report-density-20260922.md` | `PROGRESS-report-density-20260922.md` | **报告信息密度与原始附录(BUG-1003~1007)**:与源头仓 PL9 全量报告同资料实测:对照 847,632 字符 / 8,044 表格行,我方 309,357 / 1,478。缺口不在引擎——20 张分盘全表、KP 四表、Ashtakavarga 四类、Shadbala 六分量、Avastha、Sahams、年度都已算得出,但 `personal-report-contract.ts` 的 `REPORT_SECTION_KINDS` **没有表格类型**、`CHART_IDS` 只有 9 种,这些表在产品页报告里没有落脚字段。另测出对外原始附录泄漏 925 种 / 3,797 处工程标识符(`parameter_sensitive` 697、`cmd_full_reading` 68、`PyJHora`/`JHora` 35、`PL9` 页码 59),对照物同项为 0。**产品 2026-09-22 三点拍板**:层 1 按 8 组表 + 分盘扩到 16 张;层 2 原始附录直接给 C 端且先全显示;B 类大运族要显示。**决策记录已写明推翻 BUG-999 的两条红线**(专业参考不得作普通下载 fallback;`parameter_sensitive`/「参数敏感」命中整行剔除)——**仅限附录通道**,普通正文投影不动。硬红线:表格层服务端装配、writer 不得写表;对照物的替代大运族日期与 Shadbala 分量在源头仍未闭环(506 行 date mismatch、`production_tuning_allowed=false`),不得照搬升级。让步顺序与串行依赖(任务 3 → 任务 4 同改契约)见任务书 | **验收未通过**(2026-09-23):任务 1/2/4/5 通过;任务 3 事实表在普通报告里显示 447 个引擎键路径(P1);隐私门新增失败(任务书自身写入真实出生资料 BUG-1008 已清 HEAD,fixture 数值碰撞待登记);当时 BUG-1003~1007、PROGRESS、testing 清单缺失;F3 现已补前两项,testing 新建受工具边界阻塞仍缺。Node 22 前端 0 新增失败、`/` Static、gzip +0.007% | 实现 `bbd96d3b`(原 `f968cb21`,09-23 为清除 BUG-1008 重写历史;已在 staging,未部署);修复单 `TASK-report-density-fix-20260923.md` |
| `TASK-report-density-fix-20260923.md` | `PROGRESS-report-density-20260922.md` | **报告密度验收修复单(BUG-1009/1010 + 补写 1003~1007)**:F1 事实表改成真正的表(逐组规定列,普通报告可见格 0 个引擎键 / 0 个下标 / 最多 2 位小数,`sourcePath` 保留供回查;主运年数不得填出生剩余年数);F2 按既有机制登记 fixture 的数值碰撞(已独立重跑确认是虚构输入);F3 补 Bug 历史 / PROGRESS / 真人清单并更正「未提交推送」;F4 两份清洗规则只留一份(Python 版漏第三方页码);F5 writer 写表拦截补测试与提示;F6 事实表可打印。硬红线:不得弱化隐私扫描、不得强推或重写 staging(历史清除由产品负责人决定);Sade Sati 三轮日期是原任务书错误、不在本单 | **已验收,F1–F6 全部通过**(2026-09-23,`a12f2c0d`):事实表 130 行 / 600 格 0 引擎键 0 下标、主运年数 18、隐私门转绿、两份规则逐字节一致、写表拦截变异测试红→绿;Node 22 前端 3,748 / 26(名单与基线一致)、Python 948/0。剩数据库测试 E2BIG 另开 fix2(BUG-1011) | `a12f2c0d`(门禁 run 6294 红,未部署);真人清单 `docs/testing/report-density-20260922.md` |
| `TASK-report-density-fix2-20260923.md` | — | **快照数据库测试无法启动(BUG-1011)**:测试把 428,557 字节 SQL 作为单个 psql 命令行参数,超过 Linux 131,072 字节上限,门禁上 `spawn E2BIG`,快照行从未在真实 Postgres 跑过。改辅助函数经标准输入传 SQL,不得缩小快照;门禁另有既有红项不在本单 | **待领取** | — |
| `TASK-report-density-fix2-20260923.md` | — | **快照数据库测试无法启动(BUG-1011)——staging 恢复部署前的唯一阻塞**:门禁 run 2857 为 3,762 / 1 fail,唯一失败即此。测试把 428,557 字节 SQL 作为单个 psql 参数,超过 Linux 131,072 上限 → `E2BIG`。**09-23 更正做法**:不得改共享 `psql`/`psqlAs`(29 文件 522 次调用依赖 `-c` 单事务语义,`selectAsAuthenticated` 的事务内 `set_config` 会失效);新增单事务 + 标准输入 + 显式 `maxBuffer` 的专用函数,只给本测试用。修通后若真实断言失败是产品缺陷,不得改断言 | **待领取** | — |
| `TASK-report-sectioned-generation-20260830.md` | `PROGRESS-report-sectioned-20260830.md` | 分章节生成 | 已合入 | 见 PROGRESS |
| `TASK-report-skill-parity-20260901.md` | `PROGRESS-report-skill-parity-20260901.md` | 内容对齐 skill 解读深度 | 已验收 | `90bad10d`、`ef1bd6df` |
| `TASK-report-blocked-repairs-20260902.md` | `PROGRESS-report-blocked-repairs-20260902.md` | 全主题 blocked 修复 | 已验收 | `7faf8555` |
+21 -10
View File
@@ -2,7 +2,9 @@
## 基线 commit
- 被验收实现:`a12f2c0d`(`fix(report): make density facts readable and printable`,已在 `origin/staging`;门禁 run 6294 红,未部署,`/api/health` 仍为 `1bc6a954`)
- **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` 起
## 上一轮修复单验收结论
@@ -37,26 +39,35 @@ P3 各项未修,按原修复单不算未通过:复合状态译成重复短
## 决策记录
- 本单不推翻任何决策。
- 修的是测试辅助函数的传参方式,不是缩小测试数据。**不得用更短的 markdown 或裁剪过的快照来"让它过"**:快照体积正是要验证的东西之一。
- 修的是测试的传参方式,不是缩小测试数据。**共享的 `psql` / `psqlAs` 不改**(见 G1 更正)。**不得用更短的 markdown 或裁剪过的快照来"让它过"**:快照体积正是要验证的东西之一。
## 硬红线
1. 快照内容保持真实全量(fixture 原样)。
2. 不改 `personal_report_sections` 表结构、RPC 或迁移。
3. 改辅助函数后,所有既有数据库测试必须照常通过;不得跳过、不得标 skip。
3. 不得修改 `psql` / `psqlAs` 的行为;所有既有数据库测试必须照常通过;不得跳过、不得标 skip。
4. 不得强推、rebase 或重写 `staging`。
5. 测试总数不得低于 3,748。
5. 测试总数不得低于门禁 run 2857 的 3,762。
## 任务分解
### G1 · SQL 改走标准输入(BUG-1011)
### G1 · 为大脚本新增专用辅助函数(BUG-1011)
`psql` 与 `psqlAs` 改为经标准输入(`execFileSync` 的 `input`)或临时文件(`psql -f`)传 SQL,不再放进 argv。
> **更正(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 并取回结果;
- 在有 Docker 的 Linux 上跑 `npm run test:db --prefix frontend`,快照一例与全部既有数据库测试通过,输出贴进进度记录;
- 若本机仍无法跑 Docker,以门禁 run 的数据库步骤结果为准,把 run 编号与该步通过的测试名写进进度记录。不得写成"本地通过"。
- 新增一条辅助函数测试:经新函数执行一段超过 131,072 字节的 SQL,并取回结果;
- 同一条测试里再验证事务语义:新函数内先 `set_config(…, true)`、下一条语句读 `current_setting(…)`,必须读得到(证明仍是单事务);
- 门禁 run 里 `database-personal-report-sections.test.ts` 与全部既有数据库测试通过,把 run 编号、job 编号与该测试名写进进度记录。本机能跑 Docker 就再贴本机结果;不能跑就只以门禁为准,不得写"本地通过"。
**E2BIG 修好后,这条测试才第一次真正连上 Postgres。** 如果它在真实断言上失败(快照写不进去、重复写入没保留首版、他人能读到),那是**产品缺陷**,不是测试问题:停下来,把失败原文写进 BUG-1011,另报给 Claude,**不得为了过门禁改断言或裁剪快照**。
### G2 · 记录
@@ -68,7 +79,7 @@ P3 各项未修,按原修复单不算未通过:复合状态译成重复短
## 已知且不属于本单的门禁红
staging 门禁自 2026-09-22 起在报告工作之前就一直红。本机与基线共有的前端失败里,除数据库类外还有 `viewport-breakpoint-contract`、`chat-composer-queue`、`chat-panel-scroll-guard`、`model-configuration-security`、`health-deployment`、`staging-backend-workflows`、`identity-auth-integration`、`admin-database`。本单修完后门禁仍可能因这些既有失败保持红色,**需要另开单处理**,不得在本单顺手修。
~~staging 门禁另有既有红项~~ —— 已由 `TASK-staging-gate-red-20260923.md`(`36a73761`,BUG-1012~1014)修复并验收。门禁 run 2857 只剩本单这一条失败;本机因缺 Docker / rsync 失败的那些测试在门禁上全部通过。**本单合入后门禁应当转绿**;若出现别的失败,列出 run 与测试名,不得声称已绿。
## 开工前置命令