diff --git a/docs/tasks/PROGRESS-api-server-backdoor-close-20260916.md b/docs/tasks/PROGRESS-api-server-backdoor-close-20260916.md new file mode 100644 index 00000000..dc195278 --- /dev/null +++ b/docs/tasks/PROGRESS-api-server-backdoor-close-20260916.md @@ -0,0 +1,105 @@ +# 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/` 零改动。