From 88e89e10d91a276440218dbb355c79c82cbff8a0 Mon Sep 17 00:00:00 2001 From: Jesse_Chen Date: Wed, 23 Sep 2026 15:42:29 +0800 Subject: [PATCH] docs(tasks): accept the report density fix and brief the database test repair Acceptance of a12f2c0d against TASK-report-density-fix-20260923: F1 to F6 all pass. On the fixture the fact tables are 130 rows across 600 visible cells with no engine key, no array index and no long decimal, and every sourcePath resolves back into the packet. The first major period reads 18 years. Python and TS appendix cleaning are byte-identical. Removing the writer table guard turns four of its six tests red. Under Node 22 the frontend goes from 3,730 tests / 26 failing to 3,748 / 26 with an identical list; the Python quick gate goes from 946 passed / 1 failed to 948 / 0. One thing still fails: the database test for the report snapshot passes a 428,557-byte SQL string to psql as a single argument, past Linux's 131,072 byte limit, so it dies with E2BIG before reaching Postgres. The snapshot row has never run against a real database. Recorded as BUG-1011 with a fix brief. The real-person checklist the executor's tool refused to write is added here. Privacy scan on this tree before push: zero findings. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_017eEAG8HD3mm8gsKXgk8uU8 --- docs/BUG_HISTORY.md | 16 ++++ docs/tasks/README.md | 3 +- .../TASK-report-density-fix2-20260923.md | 84 +++++++++++++++++++ docs/testing/report-density-20260922.md | 35 ++++++++ 4 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 docs/tasks/TASK-report-density-fix2-20260923.md create mode 100644 docs/testing/report-density-20260922.md diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 1cae2087..8ea8e826 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -13425,3 +13425,19 @@ - 相关记录:BUG-1008、BUG-1009;`TASK-report-density-fix-20260923.md` F2 - 复发自:无;既有扫描正确触发,缺的是已核实碰撞的精确登记。 - 修复版本:缺陷引入 `bbd96d3b`;F2 工作树修复待验证,未确认部署。 + +## BUG-1011 | 快照落库的数据库测试把 42 万字节 SQL 当一个命令行参数,Linux 上启动即失败 + +- 状态:investigating(根因已复现,修复待执行;数据库层从未真跑过) +- 首次发现:2026-09-23 +- 最近更新:2026-09-23 +- 影响面:`frontend/tests/database-personal-report-sections.test.ts` 中报告密度快照一例;`backend-quality-gate` 的数据库测试步骤。生产写入走 RPC 请求体,不经命令行,不受影响。 +- 用户现象:无用户界面现象。门禁在含该测试的提交上变红;报告快照行在真实 Postgres 里的写入、幂等与越权隔离从未被验证。 +- 触发条件:在 Linux 上以 Docker 跑 `npm run test:db`(即门禁环境)。 +- 根因:`tests/helpers/postgres-fixture.ts` 的 `psql` / `psqlAs` 用 `psql -Atc ` 把整段 SQL 作为单个 argv 元素传给 `docker compose exec`。该测试把整份快照(含 374,097 字节的附录 Markdown)内联进 SQL,单个参数 428,557 字节,超过 Linux 单参数上限 `MAX_ARG_STRLEN` 131,072 字节。验收时用同一段 SQL 以同样方式调用 `/bin/true`,稳定得到 `spawn E2BIG`。执行方两轮都因 Docker 地址池耗尽未跑数据库测试,验收机无 Docker,因此一直没暴露。 +- 修复:待执行,见 `TASK-report-density-fix2-20260923.md`。 +- 验证:待执行。 +- 防复发:数据库测试辅助函数不得把 SQL 放进命令行参数,一律经标准输入或文件传入;新增一条断言覆盖超过 131,072 字节的 SQL。 +- 相关记录:BUG-1005、BUG-1009 +- 复发自:无 +- 修复版本:— diff --git a/docs/tasks/README.md b/docs/tasks/README.md index 0b23b868..54e269c4 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -170,7 +170,8 @@ | 任务书 | 进度 | 主题 | 状态 | 落点 | | --- | --- | --- | --- | --- | | `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/F2/F4/F5 分工实施,F6 与独立验收由主会话负责;F3 已补 Bug / 进度 / API 断言三栏,真人清单新建被工具拒绝,文件仍缺。隐私专项因禁读保护文件尚未全绿;未写浏览器或部署通过 | `codex/report-density-fix-20260923`,基线 `0d37bec15`;BUG-1008 原样保留 | +| `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-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` | diff --git a/docs/tasks/TASK-report-density-fix2-20260923.md b/docs/tasks/TASK-report-density-fix2-20260923.md new file mode 100644 index 00000000..0ec54f64 --- /dev/null +++ b/docs/tasks/TASK-report-density-fix2-20260923.md @@ -0,0 +1,84 @@ +# TASK-report-density-fix2-20260923 · 报告快照数据库测试无法启动 + +## 基线 commit + +- 被验收实现:`a12f2c0d`(`fix(report): make density facts readable and printable`,已在 `origin/staging`;门禁 run 6294 红,未部署,`/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 都很短,从未碰到上限。 + +## 决策记录 + +- 本单不推翻任何决策。 +- 修的是测试辅助函数的传参方式,不是缩小测试数据。**不得用更短的 markdown 或裁剪过的快照来"让它过"**:快照体积正是要验证的东西之一。 + +## 硬红线 + +1. 快照内容保持真实全量(fixture 原样)。 +2. 不改 `personal_report_sections` 表结构、RPC 或迁移。 +3. 改辅助函数后,所有既有数据库测试必须照常通过;不得跳过、不得标 skip。 +4. 不得强推、rebase 或重写 `staging`。 +5. 测试总数不得低于 3,748。 + +## 任务分解 + +### G1 · SQL 改走标准输入(BUG-1011) + +`psql` 与 `psqlAs` 改为经标准输入(`execFileSync` 的 `input`)或临时文件(`psql -f`)传 SQL,不再放进 argv。 + +**验收标准**: +- 新增一条辅助函数测试:执行一段超过 131,072 字节的 SQL 并取回结果; +- 在有 Docker 的 Linux 上跑 `npm run test:db --prefix frontend`,快照一例与全部既有数据库测试通过,输出贴进进度记录; +- 若本机仍无法跑 Docker,以门禁 run 的数据库步骤结果为准,把 run 编号与该步通过的测试名写进进度记录。不得写成"本地通过"。 + +### G2 · 记录 + +`docs/BUG_HISTORY.md` 中 BUG-1011 按结果更新;进度记录追加本单一节。 + +## 让步顺序 + +只有 G1、G2 两项,都必须做。 + +## 已知且不属于本单的门禁红 + +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`。本单修完后门禁仍可能因这些既有失败保持红色,**需要另开单处理**,不得在本单顺手修。 + +## 开工前置命令 + +```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 记录)。开工时核对最大号。 diff --git a/docs/testing/report-density-20260922.md b/docs/testing/report-density-20260922.md new file mode 100644 index 00000000..f42cdb29 --- /dev/null +++ b/docs/testing/report-density-20260922.md @@ -0,0 +1,35 @@ +# 报告密度:真人浏览器清单 + +对应任务书 `TASK-report-density-20260922.md` 与修复单 `TASK-report-density-fix-20260923.md`(BUG-1003~1007、1009、1010)。 + +自动化已验到这里为止(Claude 2026-09-23,实现 `a12f2c0d`):Node 22 前端 3,748 条测试,失败名单与基线逐条一致;事实表在 fixture 上 130 行、600 个可见格里没有引擎键名、数组下标或多位小数;首页仍是静态页。**下面每一条都需要登录态和真浏览器,没有做过,不能写成通过。** + +前提:staging 已部署到含 `a12f2c0d` 的版本(看 `https://staging.jyotisha.chat/api/health` 的 `deployment.gitCommit`)。用受控测试账号;用虚构或公开名人的出生资料,**不要用真实个人资料**。必须是部署之后**新生成**的报告,旧报告不会补出事实表。 + +## 报告页 + +- [ ] 打开 `/reports/`,正文照常,底部多出「分盘核对」和「计算数据核对表」两段。 +- [ ] 「分盘核对」里的盘一张张排开、不互相压住;向下滚动不卡顿、不闪回顶部。 +- [ ] 「计算数据核对表」默认收起。逐个点开 8 组:Vimshottari 主运、SAV 八分力、Shadbala 六分量、功能吉凶、Avastha 行星状态、附属星点与特殊上升点、Sade Sati 阶段框架、年度盘。 +- [ ] 每张表的表头是中文列名;表格里看不到带下划线的英文字段名(形如 `sign_idx`)、方括号编号(形如 `[0]`)或一长串小数。 +- [ ] Vimshottari 主运表里,每段的「年数」是整段长度(例如 18、16、19),不是 0.72 这类零头;出生时剩余年数写在表头下的说明里。 +- [ ] 当前主运、当前分运那一行的「当前」是「是」,其余是「否」。 +- [ ] Sade Sati 表只有上升 / 高峰 / 下降三个阶段和星座,说明里写着没有三轮起止日期。这是已知缺口,不算错。 +- [ ] 手机宽度(约 390px)下,宽表只在表格区域内横向滑动,整页不横向滚动。 + +## 两个下载 + +- [ ] 点「导出报告(.md)」,下载的文件和改动前一样:只有正文,没有事实表,也没有 `parameter_sensitive`、`PyJHora`、`PL9` 这类词。 +- [ ] 点「下载原始附录」,得到一份很长的 Markdown(几千行,上千行表格)。在文件里搜 `parameter_sensitive`、`PyJHora`、`JHora`、`PL9`、`cmd_full_reading`、`第 `+数字+` 页`,全部搜不到;表格里的英文字段名(如 `sign_cn`)保留,这是设计。 +- [ ] 原始附录结尾有「辅助时间轴适用性」表,每个大运族一行,写明适用或不适用的原因。 +- [ ] 对一份部署**之前**生成的旧报告点「下载原始附录」,应提示暂无原始附录或给出旧版附录,不应报错白屏。 + +## 打印 + +- [ ] 在「计算数据核对表」全部收起的状态下点「打印」,打印预览里 8 组表全部展开、表头每页都在、一行不被拆到两页。 +- [ ] 关掉打印预览后,页面上的表恢复成打印前的收起 / 展开状态。 +- [ ] 另存为 PDF,翻到事实表部分,确认 Vimshottari、SAV、BAV、Shadbala 四张表完整。 + +## 记录方式 + +每条写「通过 / 不通过 / 没法测」,不通过的截图(截图里不要带出生资料),附报告生成时间。结果交给 Claude 回填到 `docs/tasks/PROGRESS-report-density-20260922.md`。