从四处 JyotishAPIHandler.__new__ 的实际入口重算传递闭包(含模块级 execute_consultation_workflow 的 handler._x() 一层):实测 115 方法 / 4,104 行,非任务书估算的 8 方法 / 314 行;碰 HTTP 上下文者 0 个, 任务书 §5.1 的停手条件未触发。 闭包按入口分裂为可搬的 7 方法 / 300 行(vedastro 证据 + 合盘)与 不可搬的 114 方法 / 4,086 行(咨询工作流),后者含 _compute_chart_sync 与 _build_chart_prompt_pack 两个 ≥150 行方法,与 §4.3 冲突。 未改 scripts/ 与 tests/。 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01JUei7K13cYxLHE3Axe4A45
5.6 KiB
PROGRESS · 关掉 JyotishAPIHandler.__new__ 后门
- 日期:2026-09-16
- 分支:
codex/api-server-backdoor-close-20260916 - 基线:
origin/staging@37e6c519(任务书写的4f643aa0已被超车) - 状态:§5.1 完成,§5.2 起停手待决——闭包重算结果推翻了任务书「8 个方法 / 314 行」的规模前提
1. §5.1 传递闭包重算(强制第一步)
方法:ast 解析 scripts/jyotish_api_server.py,从四处 JyotishAPIHandler.__new__ 实际借用的入口出发,沿 self._x() 以及模块级函数的 handler._x() 追传递闭包,并对每个成员扫 self.headers / wfile / rfile / path / client_address 等 HTTP 上下文属性。
1.1 入口(四处伪造实际借用的方法)
| 位置 | 借用 |
|---|---|
scripts/consultation_workflow_service.py:20 |
模块级 execute_consultation_workflow(handler, ...) |
scripts/consultation_workflow_service.py:27 |
_high_rigor_vedastro_official_summary、_compute_vedastro_gateway_archives、_interpretation_source_runtime_coverage |
scripts/capture_report_blocked_repairs_golden.py:59 → :234 |
_compute_consultation_workflow |
scripts/local_accuracy_report.py:141 |
_compute_synastry |
1.2 实测结果
| 任务书 §1 | 实测 | |
|---|---|---|
| 需要搬的类方法 | 8 | 115 |
| 合计行数 | 314 | 4,104 |
| 其中碰 HTTP 上下文 | 0 | 0 |
| 另外途经的模块级函数(已在类外,不需搬) | — | 65 个 / 2,028 行 |
| 占全类(regex 225 方法 / 11,291 行)比例 | 4 % / 4 % | 51 % / 36 % |
前提成立的那一半:闭包里 0 个方法碰 HTTP 上下文。任务书 §5.1 的停手条件(有方法碰 HTTP)未触发。
前提不成立的那一半:规模是任务书估算的 13 倍。
1.3 按入口拆分——闭包分裂得很干净
| 入口 | 闭包方法数 | 行数 | 可搬? |
|---|---|---|---|
_compute_vedastro_gateway_archives |
1 | 4 | ✅ |
_interpretation_source_runtime_coverage |
1 | 41 | ✅ |
_high_rigor_vedastro_official_summary |
1 | 220 | ✅ |
_compute_synastry |
4 | 35 | ✅ |
_compute_consultation_workflow |
114 | 4,086 | ❌ |
模块级 execute_consultation_workflow |
113 | 4,080 | ❌ |
前四项去重合计 7 个方法 / 300 行——这正是任务书「8 个方法 / 314 行」的来源。
1.4 任务书数字是怎么偏的(已定位)
execute_consultation_workflow 是模块级函数,不是类方法。一次只跟 self._x() 的闭包走到它就停了,于是 _compute_consultation_workflow(自身 6 行)被当成叶子。但它签名是 execute_consultation_workflow(handler, *, body, surface),函数体内对传进来的 handler 调了 113 个类方法。跟进这一层,闭包从 300 行炸到 4,104 行。
consultation_workflow_service.py:20 与 capture_report_blocked_repairs_golden.py:59 这两处伪造都落在这条链上。
1.5 闭包里的大方法(与任务书 §4.3 直接冲突)
| 方法 | 行数 |
|---|---|
_build_chart_prompt_pack |
289 |
_compute_chart_sync |
280 |
_high_rigor_vedastro_official_summary |
220 |
_derived_career_evidence |
144 |
_compute_thematic_report |
122 |
_derive_thematic_evidence |
111 |
_compute_prashna |
101 |
_build_chart_prompt_pack(289)与 _compute_chart_sync(280)是 ≥150 行的业务方法,属于任务书 §4.3 明令不得搬的阶段 2 范围,却落在 §5.2 要求必须搬的闭包里。§5.2 ∧ §4.3 在真实代码上不可同时满足。
(_high_rigor_vedastro_official_summary 虽然 220 行,但它是后门入口本身、且含在任务书自己的 314 行估算内,不算 §4.3 的「顺手搬」。)
2. 另一处口径偏差:__new__ 基线不是 4
tests/test_api_server_growth_contract.py 现行基线 JYOTISH_API_HANDLER_NEW_COUNT_BASELINE = 33,注释写明「scripts/ production forgeries = 4, tests/ = 29」。
任务书 §4.1 要求 grep -rn "JyotishAPIHandler.__new__" --include=*.py .(排除 skills/*/versions/**)零命中。该 grep 覆盖 tests/,其中 29 处分布在 20 个测试文件里,包括 tests/test_api_server_security.py:34——而 §4.2 规定该文件不许改。
因此「零命中」只能理解为 scripts/ 生产侧零命中(4 → 0),tests/ 的 29 处保持不增长。这与 §4.1 括号里的「基线 4 → 0」一致。
3. 可行性预检(为 §5.2 备)
两组小闭包搬出去后对 jyotish_api_server 的模块级依赖,均可解析、无反向 import 死结:
| 组 | 方法 | 需一并处理的模块级名字 |
|---|---|---|
| vedastro 证据 | _high_rigor_vedastro_official_summary、_compute_vedastro_gateway_archives、_interpretation_source_runtime_coverage |
_build_vedastro_official_full_snapshot_payload_from_chart(L2942)、_free_tier_queue_enabled_env(L2564)、_preferred_strict_contract(L3005) |
| 合盘 | _compute_synastry、_get_float、_check_range、_normalize_degree |
BadRequest(L3177) |
这些依赖全在 jyotish_api_server.py 内部定义,需随组搬走或提到共享模块,否则新模块就得反向 import(违反 §4.4)。
4. 环境
python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45 → exit=0,六项检查全绿(python_runtime / fragment_scan / external_engine_adapters / remote_visibility=verified / focused_tests)。
5. 待决
见回报。§5.2 / §5.3 / §5.4 未动,scripts/ 与 tests/ 零改动。