diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index bff2b005..7cd93dea 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -17999,8 +17999,8 @@ - 触发条件:打开合盘。排盘接口本身默认仍走完整链,给报告和外部调用留着。 - 根因:合盘这条路由没跟上「只读盘面就关掉外部概览」的约定,也没有合同测试拦住。名额按路径一刀切,不带 skip 的排盘默认不占名额。 - 修复:合盘两次排盘都带上关闭外部概览,两张盘同时排;婚恋分支的两张分盘也同时排。前端里凡是发给排盘接口的请求体,都要带这个开关,由源码合同守着。另加一个默认关闭的开关:打开后,不带 skip 的同步排盘才占一个重计算名额。名额占满时记一行日志,只写被拒的路径和当前占用者的路径、已占秒数,不写请求正文。 -- 验证:`frontend/tests/synastry-chart-skip.test.ts`、`frontend/tests/chart-request-skip-contract.test.ts`、`tests/test_api_chart_subprocess_gate.py`、`tests/test_api_heavy_compute_gate.py`。合盘耗时见 `docs/testing/api-chart-subprocess-gate-ab-20261013.md`。 -- 防复发:源码合同要求 `frontend/src/app/api` 和 `frontend/src/lib` 里发往 `/api/chart` 的请求体带 `skip_vedastro_main_entry_overview: true`。`/api/chart` 仍不在重计算路径名单里。 +- 验证:`frontend/tests/synastry-chart-skip.test.ts`、`frontend/tests/chart-request-skip-contract.test.ts`、`tests/test_api_chart_subprocess_gate.py`、`tests/test_api_heavy_compute_gate.py`。合盘耗时见 `docs/testing/api-chart-subprocess-gate-ab-20261013.md`。`tests/test_supabase_user_data_contract.py` 锁住合盘路由向 `/api/chart` 请求本人和对方两张盘,且两次都带 `skip_vedastro_main_entry_overview: true`。 +- 防复发:源码合同要求 `frontend/src/app/api` 和 `frontend/src/lib` 里发往 `/api/chart` 的请求体带 `skip_vedastro_main_entry_overview: true`。Python 合同按路由原文锁住这两次调用和这个开关。`/api/chart` 仍不在重计算路径名单里。 - 相关记录:BUG-161、BUG-715、BUG-717、BUG-1302。 - 复发自:无。 - 修复版本:分支 `codex/api-chart-subprocess-gate-20261013`。编号是任务书预留的空号,夹在 BUG-1332 和 BUG-1335 之间。 @@ -36081,8 +36081,8 @@ - 触发条件:打开合盘。排盘接口本身默认仍走完整链,给报告和外部调用留着。 - 根因:合盘这条路由没跟上「只读盘面就关掉外部概览」的约定,也没有合同测试拦住。名额按路径一刀切,不带 skip 的排盘默认不占名额。 - 修复:合盘两次排盘都带上关闭外部概览,两张盘同时排;婚恋分支的两张分盘也同时排。前端里凡是发给排盘接口的请求体,都要带这个开关,由源码合同守着。另加一个默认关闭的开关:打开后,不带 skip 的同步排盘才占一个重计算名额。名额占满时记一行日志,只写被拒的路径和当前占用者的路径、已占秒数,不写请求正文。 -- 验证:`frontend/tests/synastry-chart-skip.test.ts`、`frontend/tests/chart-request-skip-contract.test.ts`、`tests/test_api_chart_subprocess_gate.py`、`tests/test_api_heavy_compute_gate.py`。合盘耗时见 `docs/testing/api-chart-subprocess-gate-ab-20261013.md`。 -- 防复发:源码合同要求 `frontend/src/app/api` 和 `frontend/src/lib` 里发往 `/api/chart` 的请求体带 `skip_vedastro_main_entry_overview: true`。`/api/chart` 仍不在重计算路径名单里。 +- 验证:`frontend/tests/synastry-chart-skip.test.ts`、`frontend/tests/chart-request-skip-contract.test.ts`、`tests/test_api_chart_subprocess_gate.py`、`tests/test_api_heavy_compute_gate.py`。合盘耗时见 `docs/testing/api-chart-subprocess-gate-ab-20261013.md`。`tests/test_supabase_user_data_contract.py` 锁住合盘路由向 `/api/chart` 请求本人和对方两张盘,且两次都带 `skip_vedastro_main_entry_overview: true`。 +- 防复发:源码合同要求 `frontend/src/app/api` 和 `frontend/src/lib` 里发往 `/api/chart` 的请求体带 `skip_vedastro_main_entry_overview: true`。Python 合同按路由原文锁住这两次调用和这个开关。`/api/chart` 仍不在重计算路径名单里。 - 相关记录:BUG-161、BUG-715、BUG-717、BUG-1302。 - 复发自:无。 - 修复版本:分支 `codex/api-chart-subprocess-gate-20261013`。编号是任务书预留的空号,夹在 BUG-1332 和 BUG-1335 之间。 diff --git a/docs/tasks/PROGRESS-api-chart-subprocess-gate-20261013.md b/docs/tasks/PROGRESS-api-chart-subprocess-gate-20261013.md index c067ad7f..93f936a1 100644 --- a/docs/tasks/PROGRESS-api-chart-subprocess-gate-20261013.md +++ b/docs/tasks/PROGRESS-api-chart-subprocess-gate-20261013.md @@ -72,3 +72,19 @@ - `JYOTISH_GATE_CHART_OVERVIEW` 默认关。 - 合盘 skip 和报告短路没有开关。 + +## 2026-10-15 打回修复 + +合盘路由的合同跟上了新写法:仍锁本人和对方各请求一次排盘,并锁住关闭外部概览。对照脚本默认写到系统临时目录,只有带 `--out` 才写指定文件,不再覆盖已入库的记录。业务代码没改。名额配额仍不实现。没有新 bug 编号,补在 BUG-1333 的两处副本上。 + +| 检查 | 命令 | 结果 | +| --- | --- | --- | +| 用户数据合同 | `.venv\Scripts\python.exe -m pytest tests/test_supabase_user_data_contract.py -q` | 8 passed,退出码 0 | +| 脚本默认路径 | 调用 `resolve_record_path` | 默认不在仓库内,也不是已入库的 json;`--out` 指向传入路径 | +| 源码文本检索 | `tests` 与 `frontend/tests` 里的合盘路由、`postPython("/api/chart"`、`postPython("/api/varga_full"` | 只有这一条合同在断言旧写法,已改。其它命中是在读路由文件,没有断言旧的两次调用。分盘前缀仍匹配,没改 | +| 类型检查 | 在 `frontend` 下 `node_modules\.bin\tsc --noEmit -p .` | 退出码 0 | +| lint | 在 `frontend` 下 `npm run lint` | 退出码 0,0 error,123 条原有 warning | + +原值:`postPython("/api/chart", selfPayload)` 与 `postPython("/api/chart", partnerPayload)`。新值:两次调用都展开对应 payload,并带 `skip_vedastro_main_entry_overview: true`。原因:合盘改为同时排两张盘并关掉用不上的外部概览,合同要锁住这两次请求和这个开关,不放宽。 + +偏离:先合并了 `origin/staging` `1de3cc307be9134a3b8d1d606c738c1468414118`。相对打回 SHA `336286e4`,`frontend/src` 里多出来的是数据访问层那一单,不是这次修复改的。技能目录下的同名脚本没改,它的输出根不是仓库的 `docs/testing`。 diff --git a/docs/tasks/README.md b/docs/tasks/README.md index 2151bb9b..abe0307a 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -484,7 +484,7 @@ | `TASK-frontend-dead-code-20261013.md` | `PROGRESS-frontend-dead-code-20261013.md` | 前端死代码 17 文件与无调用方接口删除,含未登录重计算接口(BUG-1342) | 待验收 | `codex/frontend-dead-code-20261013` | | `TASK-frontend-dead-code-fix-20261014.md` | `PROGRESS-frontend-dead-code-20261013.md` | **#63 第 1 次打回**:类名白名单去掉已删组件留下的条目 | 待验收 | `codex/frontend-dead-code-20261013` | | `TASK-api-chart-subprocess-gate-20261013.md` | `PROGRESS-api-chart-subprocess-gate-20261013.md` | 合盘不带 skip 串行排盘、报告无效子进程、名额轻重混用(只模拟)(BUG-1333~1334,A/B) | 第 1 次打回,见修复单 | `codex/api-chart-subprocess-gate-20261013` | -| `TASK-api-chart-subprocess-gate-fix-20261015.md` | — | **#64 第 1 次打回**:`336286e4` 内容通过(合盘 1.19→0.015 s、正文逐字节一致);Python 合同按源码检查合盘路由旧写法未跟改;A/B 脚本默认覆盖入库记录 | 待领取 | `codex/api-chart-subprocess-gate-20261013` | +| `TASK-api-chart-subprocess-gate-fix-20261015.md` | `PROGRESS-api-chart-subprocess-gate-20261013.md` | **#64 第 1 次打回**:`336286e4` 内容通过(合盘 1.19→0.015 s、正文逐字节一致);Python 合同按源码检查合盘路由旧写法未跟改;A/B 脚本默认覆盖入库记录 | 待验收 | `codex/api-chart-subprocess-gate-20261013` | | `TASK-answer-effort-ab-20261013.md` | — | 答题步推理强度开关 + A/B(需模型 key) | 待领取(排队:consult-prep-parallel) | `codex/answer-effort-ab-20261013` | | `TASK-answer-effort-ab-fix-20261015.md` | — | **#65 第 1 次打回**:`ab7f66be` 开关逻辑通过(默认请求体不变);研究脚本从 `frontend/tests` 读文件(BUG-1140) | 待领取 | `codex/answer-effort-ab-20261013` | | `TASK-consult-route-split-20261013.md` | — | consult POST 拆分第一阶段:开流前加载 + 计费结算 | 待领取(排队:consult-prep-parallel、answer-effort-ab) | `codex/consult-route-split-20261013` | diff --git a/scripts/research/api_chart_subprocess_ab.py b/scripts/research/api_chart_subprocess_ab.py index 6232f2b9..fccc7279 100644 --- a/scripts/research/api_chart_subprocess_ab.py +++ b/scripts/research/api_chart_subprocess_ab.py @@ -10,12 +10,14 @@ generated_at, created_at, timestamp, elapsed_seconds, elapsed_ms, duration_ms, r from __future__ import annotations +import argparse import json import os import random import statistics import subprocess import sys +import tempfile import threading import time from concurrent.futures import ThreadPoolExecutor @@ -246,7 +248,22 @@ def _simulate() -> list[dict]: return [run(mode) for mode in ("O1", "O2", "O3", "O4")] -def main() -> None: +def resolve_record_path(explicit: str | None) -> Path: + """Write the A/B JSON only where asked. The committed note stays untouched.""" + if explicit: + return Path(explicit) + directory = Path(tempfile.mkdtemp(prefix="api-chart-subprocess-ab-")) + return directory / "api-chart-subprocess-gate-ab-20261013.json" + + +def main(argv: list[str] | None = None) -> None: + parser = argparse.ArgumentParser(description="A/B for issue #64 chart subprocess gate") + parser.add_argument( + "--out", + default=None, + help="Write the JSON record to this path. Omit to use a fresh temp directory, not the committed docs/testing file.", + ) + args = parser.parse_args(argv) counter = _Counter() counter.install() charts = _measure_charts(counter) @@ -263,8 +280,10 @@ def main() -> None: "jhora_installed": False, } text = json.dumps(out, ensure_ascii=False, indent=2) - dest = ROOT / "docs" / "testing" / "api-chart-subprocess-gate-ab-20261013.json" + dest = resolve_record_path(args.out) + dest.parent.mkdir(parents=True, exist_ok=True) dest.write_text(text + "\n", encoding="utf-8") + print(dest, file=sys.stderr) print(text) diff --git a/tests/test_supabase_user_data_contract.py b/tests/test_supabase_user_data_contract.py index e4300dbd..63633b2b 100644 --- a/tests/test_supabase_user_data_contract.py +++ b/tests/test_supabase_user_data_contract.py @@ -298,8 +298,11 @@ def test_synastry_route_orchestrates_python_chart_and_ashtakoot() -> None: route = SYNASTRY_ROUTE.read_text(encoding="utf-8") for token in ( 'const apiBase = process.env.JYOTISH_API_BASE ?? "http://127.0.0.1:5200"', - 'postPython("/api/chart", selfPayload)', - 'postPython("/api/chart", partnerPayload)', + # 原值: postPython("/api/chart", selfPayload) 与 postPython("/api/chart", partnerPayload) + # 新值: 两次调用都展开对应 payload,并带 skip_vedastro_main_entry_overview: true + # 原因: 合盘改为同时排本人和对方两张盘,并关掉用不上的外部概览。断言仍锁住这两次 /api/chart,同时锁住这个开关,不放宽。 + 'postPython("/api/chart", { ...selfPayload, skip_vedastro_main_entry_overview: true })', + 'postPython("/api/chart", { ...partnerPayload, skip_vedastro_main_entry_overview: true })', 'postPython("/api/varga_full"', 'postPython("/api/synastry"', "moonLongitude(selfChart)",