diff --git a/BLOCKED.md b/BLOCKED.md index d07b64e1..ddddaf60 100644 --- a/BLOCKED.md +++ b/BLOCKED.md @@ -1,5 +1,20 @@ # BLOCKED +## 快速门 timezone 推断依赖(2026-09-15,对照 `039b0a26` / `1d2aeffa`) + +- **`run_quality_gate.py --profile quick` 必红一条,不是 BUG-693/694 的回归。** 验收机在 `1d2aeffa` 上 `739 passed, 1 failed`;同一条在修复前的 `039b0a26` 上同样红。 +- 失败测试:`tests/test_api_server_security.py::test_shadbala_endpoint_returns_ranked_planet_strength` +- warning 原文:`WARNING [api_server] shadbala advanced layer failed: timezone inference dependency unavailable` +- 断言:`assert ['core_sixfold'] == ['core_sixfold', 'advanced_evidence']`(缺 `timezonefinder`,高级层没挂上)。 +- 本机口径:快速门通过 =「除这一条外全绿」。谁要宣称快速门全绿,必须先在该环境装上 `timezonefinder`(`requirements.txt` / `pyproject.toml` 已声明 `timezonefinder>=6.5`)。不得改这条断言来让门变绿。 + +复现: + +```bash +python -m pytest tests/test_api_server_security.py::test_shadbala_endpoint_returns_ranked_planet_strength +python scripts/run_quality_gate.py --profile quick +``` + ## 采集流程重设计(2026-09-10,分支 `codex/rectification-collection-redesign-20260910`) - **`next build` / 首屏 gzip 未核。** 本 worktree 的 `frontend/node_modules` 是指向主仓的软链。实测 `npm run build` 在 Next 16.3.1 Turbopack 失败:`Symlink [project]/frontend/node_modules is invalid, it points out of the filesystem root`。不得把 `/` Static 或 gzip ±2% 写成通过。 diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index c6944a37..1e68e5de 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -10801,7 +10801,7 @@ - 根因:被哈希的载荷含墙钟字段(`elapsed_seconds`、分阶段耗时、VedAstro `called_at` / cache 时间)。`kendra_lords` 由 `list(set(...))` 生成,跨进程顺序不稳定。 - 修复:`binding_scope` 显式排除自引用(`report_quality_gate`、`shared_full_report_authority`)、生成时刻(`generated_at` 以及 `**.called_at` / `**.cache_created_at` / `**.cache_expires_at`)、墙钟耗时(`**.elapsed_seconds`)。业务字段仍输出。Kendra / trikona lords 改为排序后的稳定列表。 - 验证:同输入两次构造 `result_hash` 相同;只改 `elapsed_seconds` 不变;改 `coverage` 必变。虚构盘三次 CLI 哈希 `2f4739a4…` 全同,内部 `elapsed_seconds` 仍为 2.74 / 2.86 / 2.83。 -- 防复发:排除集只能是自引用 / 生成时刻 / 墙钟三类,必须写进回执并由质量门重算。加第四类要改任务书。 +- 防复发:排除集只能是自引用 / 生成时刻 / 墙钟三类,必须写进回执并由质量门重算。加第四类要改任务书。允许集有字面量合同测试守门,改动必须先过测试再改任务书。 - 相关记录:BUG-693、BUG-576 - 复发自:无 - 修复版本:待发布 diff --git a/docs/tasks/PROGRESS-report-binding-scope-lock-20260915.md b/docs/tasks/PROGRESS-report-binding-scope-lock-20260915.md new file mode 100644 index 00000000..6569388e --- /dev/null +++ b/docs/tasks/PROGRESS-report-binding-scope-lock-20260915.md @@ -0,0 +1,51 @@ +# 进度 · 绑定排除集字面量锁 + timezone 缺口入账(2026-09-15) + +## 范围 + +- 分支:`codex/report-binding-scope-lock-20260915`(基于 `origin/staging` @ `10b463b9`) +- 任务单:`docs/tasks/TASK-report-binding-scope-lock-20260915.md` +- 不新增 BUG 编号;只补强 BUG-694 防复发条 +- 生产代码一行未改(`calculation_profile_contract.py` / `full_report_quality_gate.py` / `jyotish_engine.py`) +- `CHANGELOG.md` 不写(D5) + +## 完成 + +- T1:`test_binding_exclusion_allowlist_is_the_literal_d2_set` 钉死两个常量的完整字面量与顺序。注释写明三类归属,以及改这里要先改任务书并在 BUG-694 补记。 +- T2:`BLOCKED.md` 记 timezone 缺口;本机复现同一条测试红,warning 原文一致。未改该断言。未装 `timezonefinder`(仓内已声明,本机 Anaconda 没有;装上只绿本机,不改变验收机缺口)。 +- T3:BUG-694 防复发条补了一句字面量合同测试守门。 + +## 任务 1 红 / 绿 + +在 `ALLOWED_BINDING_EXCLUDED_PATHS` 临时加 `"**.generated_by"`: + +``` +FAILED tests/test_calculation_profile_contract.py::test_binding_exclusion_allowlist_is_the_literal_d2_set +AssertionError: assert ('ai_and_audi...generated_by') == ('ai_and_audi...e_expires_at') + Left contains one more item: '**.generated_by' +RED_EXIT 1 +``` + +恢复常量后: + +``` +. [100%] +GREEN_EXIT 0 +``` + +`git diff scripts/calculation_profile_contract.py` 为空。 + +## 定向测试 + +`tests/test_calculation_profile_contract.py` + `tests/test_full_report_quality_gate.py`:全绿(既有 3 skipped)。 + +## `--profile quick` 失败清单 + +验收机(任务书 §1.2):`739 passed, 1 failed`。 + +``` +FAILED tests/test_api_server_security.py::test_shadbala_endpoint_returns_ranked_planet_strength +WARNING [api_server] shadbala advanced layer failed: timezone inference dependency unavailable +assert ['core_sixfold'] == ['core_sixfold', 'advanced_evidence'] +``` + +本机隔离复现同一条,warning 原文相同。本机没有项目 `.venv`,Anaconda 还缺 `mcp`,完整 `run_quality_gate.py --profile quick` 会先在 `interpretation_source_inventory_gate` 红掉,跑不到 739 那条汇总;timezone 缺口以隔离命令为准,见 `BLOCKED.md`。 diff --git a/docs/tasks/README.md b/docs/tasks/README.md index ea96b527..6cbe1d83 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -137,7 +137,7 @@ | `TASK-report-chart-render-20260909.md` | `PROGRESS-report-chart-render-20260909.md` | 报告页所有分盘标题下空白:引擎 22 张 `` 被 `skipHtml` 丢弃(09-06 Markdown 直渲回归)。引擎旁加 ```jyotish-chart 围栏 JSON,前端 zod 校验后用自绘北印式组件全部渲染;不放开原始 HTML | 已验收(2fdcb14f):tsc/lint 0 error、chart 测试 29/29、`/` Static、gzip +0.96%;围栏构造在 try 外的 P2 并入 `TASK-upstream-sync2-fix-20260909.md` 任务 3 | `codex/report-chart-render-20260909`(BUG-607) | | `TASK-report-chart-layout-fix-20260909.md` | `PROGRESS-report-chart-layout-fix-20260909.md` | 星盘渲染回归修复:22 张北印盘全部重叠(浮动 + 负 margin 凑两栏对连续多对无效)+ 滚动时 `components` 每渲染新建导致整篇报告卸载重建、页面卡;改 rehype 成组进既有两栏 grid、文章树 `useMemo`、目录状态下沉 | 待验收 | `87daffe2`(BUG-616/617);已 merge origin/staging `df090fd5` | | `TASK-report-provenance-binding-20260915.md` | `PROGRESS-report-provenance-binding-20260915.md` | 专业报告溯源绑定:`result_binding` 只绑到中间态包(实测 18/36 个顶层键、6.24 MB / 交付 10.04 MB),`full_report_pack`、`chart_identity`、`timing_precision_contract` 等全在覆盖外,而质量门只比自洽所以恒 passed(BUG-693);被哈希的载荷含墙钟 `ai_and_audit.summary.elapsed_seconds`,同一输入两次跑出不同 `result_hash`(BUG-694)。末尾按交付对象重绑 + 显式排除集写进回执 + 质量门补覆盖校验;上游 09-14 的有界投影实测收益 < 0.1 秒,不抄 | 已验收(`1d2aeffa`):三次 CLI + 三个 `PYTHONHASHSEED` 哈希全同、变异法验证覆盖 33/40 键、耗时中位数 2737 ms(修复前 2769 ms)、`npm test` fail 27 = 基线;快速门唯一红的 `test_shadbala_endpoint_returns_ranked_planet_strength` 在修复前同样红(timezone 依赖缺)。遗留补漏单 `TASK-report-binding-scope-lock-20260915.md` | `1d2aeffa` | -| `TASK-report-binding-scope-lock-20260915.md` | `PROGRESS-report-binding-scope-lock-20260915.md` | 验收补漏单:BUG-694 的「排除集只能三类」是纸面规矩——质量门与测试引用的是生产者同一对常量,往常量里加第四类会自动放行;把允许集的字面量钉进合同测试(改动即红)。另把 `--profile quick` 必红的 `timezone inference dependency unavailable` 记进 `BLOCKED.md`(修复前同样红,非回归)。不新增 BUG 编号,只更新 BUG-694 | 待领取 | — | +| `TASK-report-binding-scope-lock-20260915.md` | `PROGRESS-report-binding-scope-lock-20260915.md` | 验收补漏单:BUG-694 的「排除集只能三类」是纸面规矩——质量门与测试引用的是生产者同一对常量,往常量里加第四类会自动放行;把允许集的字面量钉进合同测试(改动即红)。另把 `--profile quick` 必红的 `timezone inference dependency unavailable` 记进 `BLOCKED.md`(修复前同样红,非回归)。不新增 BUG 编号,只更新 BUG-694 | 待验收 | `codex/report-binding-scope-lock-20260915` | ### 前端基础与工程 diff --git a/tests/test_calculation_profile_contract.py b/tests/test_calculation_profile_contract.py index 3b784022..99c16b93 100755 --- a/tests/test_calculation_profile_contract.py +++ b/tests/test_calculation_profile_contract.py @@ -542,6 +542,33 @@ def test_direct_script_and_package_import_are_functionally_equivalent() -> None: assert module.build_calculation_profile(BIRTH_PAYLOAD) == build_calculation_profile(BIRTH_PAYLOAD) +def test_binding_exclusion_allowlist_is_the_literal_d2_set() -> None: + """Lock the allowlist so widening it cannot silently go green. + + Three classes only (BUG-694). Adding a fourth class, renaming a path, or + dropping one must fail this test until the task book and BUG-694 are + updated. The quality gate imports the same constants, so a lock here is + the only check that fails when the producer set grows. + + 自引用: ``report_quality_gate``, ``shared_full_report_authority``. + 生成时刻: ``generated_at``; ``**.called_at`` / ``**.cache_created_at`` / + ``**.cache_expires_at``. + 墙钟耗时: ``ai_and_audit.summary.elapsed_seconds`` and ``**.elapsed_seconds``. + """ + assert ALLOWED_BINDING_EXCLUDED_TOP_KEYS == ( + "generated_at", + "report_quality_gate", + "shared_full_report_authority", + ) + assert ALLOWED_BINDING_EXCLUDED_PATHS == ( + "ai_and_audit.summary.elapsed_seconds", + "**.elapsed_seconds", + "**.called_at", + "**.cache_created_at", + "**.cache_expires_at", + ) + + REQUIRED_DELIVERED_KEYS = ( "full_report_pack", "chart_identity",