- dasha-unify: fix Ashtottari birth balance (BUG-1344) - rect-scoring-perf: server-side candidate cap 241 (BUG-1345) - node-runtime-resources: enable user-side session cookie cache, 300 s (BUG-1346) - consult-prep-parallel: classifier/reserve concurrency declined - answer-effort-ab: model key supplied by product at acceptance - drop stricter-than-test line-count red lines (AGENTS.md section 6) Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_014Ad9rqAB8pXXvyzh7f4X8v
198 lines
22 KiB
Markdown
198 lines
22 KiB
Markdown
# TASK · 星盘接口与报告的多余子进程、合盘串行、重计算名额轻重混用(issue #待定)
|
||
|
||
- 日期:2026-10-13
|
||
- 来源:「2026-10-13 全仓屎山与性能排查」P1 · 星盘接口子进程与闸门
|
||
- 执行方:**Grok(Windows + Docker)**,分支 `codex/api-chart-subprocess-gate-20261013`,只推这个分支
|
||
- 验收:Claude(Linux)
|
||
- BUG 编号:**BUG-1333~1334**(开工时核对 `docs/BUG_HISTORY.md` 最大号;写作时最大号 BUG-1317,BUG-1323~1332 已被同批其它任务书占用)(另:`TASK-upstream-sync7-20261014` 占 BUG-1318~1322,本批号段整体从 BUG-1323 起)
|
||
- **开工前置**:`TASK-api-disk-cache-retention-20261013`(分支 `codex/api-disk-cache-retention-20261013`)**已合入 `origin/staging`**。两单都改 `scripts/jyotish_api_server.py`,且本单 A/B 依赖那一单的缓存键规范化;未合入不得开工。
|
||
- **主会话补充的串行链(2026-10-14)**:引擎/API 文件链按此顺序逐单合入后开工(`upstream-sync7` 也改 `jyotish_engine.py` / `jyotish_api_server.py`,若在途,后合一方 rebase):`api-disk-cache-retention` + `report-reference-perf` → `api-chart-subprocess-gate` → `pl9-render-split` → `python-hygiene` → `dasha-unify` → `api-server-service-extract`。本单的前置以这条链为准(与上一行不一致时以本行为准)。
|
||
|
||
## 1. 基线
|
||
|
||
- 基线 commit:`origin/staging` `77057a819`(开工时以前置单合入后的 `origin/staging` 为准,§9 有核对命令)。
|
||
- 生产镜像只装 `requirements.txt`:**有** `vedastro==1.23.25`,**没有** PyJHora(PyJHora 在 `requirements-reference-engines.txt`,AGPL,只作离线参照)。本单所有计时**必须**在「模拟生产依赖」下再跑一遍:把只含下面这个 `sitecustomize.py` 的目录放在 `PYTHONPATH` 最前(子进程会继承)。
|
||
|
||
```python
|
||
# <临时目录>/nojhora/sitecustomize.py —— 只挡 jhora;要模拟「无 VedAstro SDK」时把 'vedastro' 也加进集合
|
||
import sys
|
||
class _Block:
|
||
def find_spec(self, name, path=None, target=None):
|
||
if name.split('.')[0] in {'jhora'}:
|
||
raise ModuleNotFoundError(f"No module named '{name}'")
|
||
return None
|
||
sys.meta_path.insert(0, _Block())
|
||
```
|
||
|
||
## 2. 事故实证
|
||
|
||
计时脚本:用 `JyotishAPIHandler.__new__(JyotishAPIHandler)` 造处理器,直接调 `_compute_chart_sync` / `professional_report_reference.build_professional_report_reference`,monkeypatch `subprocess.run` 记录每次命令与耗时;`JYOTISH_API_CHART_CACHE_TTL_SECONDS=0` 避开缓存。虚构盘 1990-01-01 12:00 新德里 28.6139/77.2090 +5.5。本机(Linux,无 vedastro SDK、外网关闭)实测:
|
||
|
||
### 2.1 `/api/chart` 不带 skip 每次起 2 个子进程(BUG-1333)
|
||
|
||
| 请求 | 子进程 | 热态耗时(4 次,后 3 次中位) | 响应体 |
|
||
| --- | --- | --- | --- |
|
||
| 不带 `skip_vedastro_main_entry_overview` | 2 个:`vedastro_official_capability_runner.py --bundle official_full_snapshot` 与 `--bundle official_full_capability_catalog` | **约 1.03–1.09 s**(排查报告另一次测得 0.56 s) | 160,643 字节 |
|
||
| 带 skip | 0 | **约 5–9 ms** | 55,345 字节 |
|
||
|
||
- 子进程来自 `scripts/jyotish_api_server.py::_attach_vedastro_main_entry_overview` → `vedastro_evidence_orchestrator.orchestrate_vedastro_evidence(route='overview')` → `scripts/vedastro_service_adapter.py` 的 `subprocess.run`。本机没有 SDK,子进程秒败;**生产装了 SDK,若开了外网,这两个子进程会真的打 VedAstro,耗时上限是 `VEDASTRO_TIMEOUT_SECONDS`**——本机测不到,是环境缺口。
|
||
- 出生资料以 `--birth-json` 明文出现在子进程命令行里(同机 `ps` 可见)。记录,本单不改。
|
||
- `/api/chart` 不在 `scripts/api_heavy_compute_gate.py::HEAVY_COMPUTE_PATHS` 里(`tests/test_api_heavy_compute_gate.py::test_health_and_light_paths_are_not_gated` 明确断言 `"/api/chart" not in HEAVY_COMPUTE_PATHS`),所以这 1 s 级的子进程调用不受名额约束。
|
||
|
||
### 2.2 前端调用方逐一核对
|
||
|
||
| 调用方 | 是否带 skip | 用到响应里的什么 | 需要 VedAstro 主入口概览吗 |
|
||
| --- | --- | --- | --- |
|
||
| `frontend/src/lib/chart-view-load.ts`(星盘页主盘,`payload`) | 带 | 盘面 | 否 |
|
||
| 同文件 transit 层 → `frontend/src/lib/transit-chart-body.ts::transitChartBody` | 带 | 行运盘 | 否 |
|
||
| `frontend/src/app/api/ephemeris/route.ts`(两处) | 带 | 盘面 | 否 |
|
||
| `frontend/src/app/api/synastry/route.ts::POST` | **不带** | 只读 `planets`、`ascendant`、月亮经度(`moonLongitude`) | **否** |
|
||
|
||
- 合盘还**串行**:`selfChart` 与 `partnerChart` 两次 `await postPython("/api/chart", …)` 先后执行;romance 分支里两次 `/api/varga_full`(D9)也是串行(business 分支已是 `Promise.all`)。按本机数字,合盘一次光是两次 chart 就约 2 s,带 skip 并发后约 10 ms 级。
|
||
- Python 内部:`execute_consultation_workflow` 的 `compute_chart` 步骤按 `defer_optional_external_evidence` 传 skip(前台咨询 skip,BUG-161);个人报告、高严谨、主题报告、MCP / API Explorer(`API_COMMAND_MAP` 的 `chart`、`full-reading`)走不 skip 的完整链。**这些保持不变**(BUG-161:个人报告保持默认完整工作流)。
|
||
|
||
### 2.3 报告每次起 10 个子进程(BUG-1334)
|
||
|
||
`/api/professional_report_reference`(`edition=full_data`、`languages=["zh","en"]`,个人报告长文的真实请求形状,见 `frontend/src/lib/personal-report-longform-generate.ts`),各跑 2 次:
|
||
|
||
| 环境 | 总耗时 | 子进程数 | 子进程合计 |
|
||
| --- | --- | --- | --- |
|
||
| 本机(装了 PyJHora) | 19.8 s / 18.4 s | 10 | 6.5 s / 6.0 s |
|
||
| 模拟生产(挡 `jhora`,本机本就无 vedastro SDK) | 13.5 s / 13.2 s | 11 | 0.71 s / 0.92 s |
|
||
|
||
子进程明细(模拟生产):
|
||
|
||
| 子进程 | 次数 | 每次 | 来源 |
|
||
| --- | --- | --- | --- |
|
||
| `vedastro_official_capability_runner.py`(snapshot / catalog)+ 无 SDK 时多一个 `vedastro_python_bridge.py` | 2–3 | 0.06–0.09 s | 官方快照,报告完整链的一部分,**保留** |
|
||
| `oracle_collection_queue.py` → `oracle_evidence_validator.py` | 2 | 0.03–0.27 s | `scripts/jyotish_engine.py::_oracle_progress_snapshot`:读仓库里的静态文件 `references/oracle/dasha_shadbala_oracle_cases.json` 做校验,**与用户盘无关,每份报告重跑** |
|
||
| `python -c "from scripts.annual_pyjhora_replay import _isolated_tajaka_worker…"` | 3 | 0.06–0.08 s | `scripts/annual_pyjhora_replay.py::_run_isolated_tajaka_year_lord` |
|
||
| `python -c "… _isolated_annual_worker…"` | 3 | 0.06–0.08 s | `::_run_isolated_annual_replay` |
|
||
|
||
- **修正排查报告**:生产没有 PyJHora 时这 6 个 PyJHora 子进程确实「快速失败但仍付启动开销」,但每个只有约 60–80 ms,合计约 0.4 s;排查报告里的「年度回放 3 次 ~4.2 s、Tajika 3 次 ~0.9 s」只在装了 PyJHora 的机器(开发机、参照环境)成立。生产上的收益是**每份报告约 0.5–0.9 s、8 个子进程**,不是 5 s。
|
||
- 另:`scripts/tajika.py::_resolve_external_pyjhora_python` 不缓存「找不到 PyJHora」的结论,每次都对 `python3.14`、`python3` 各起一个 `find_spec` 探测子进程(当前解释器路径与候选相同时才跳过)。生产镜像里 `sys.executable` 与 `which python3` 是否同一路径未核实——执行方在 Docker 镜像里核实并写进 PROGRESS。
|
||
|
||
### 2.4 重计算名额轻重混用(只评估)
|
||
|
||
- `HEAVY_COMPUTE_PATHS` 共 22 条,共用一个 `BoundedSemaphore(JYOTISH_HEAVY_COMPUTE_CONCURRENCY=2)`,满了立刻 429(`acquire_heavy_compute_slot` 非阻塞)。
|
||
- 排查报告数字(本单 A/B 复测):`/api/consultation_workflow` 卡片缓存命中时约 0.2 s;个人报告约 18 s(本机模拟生产 13 s);校正打分 5–12 s。两份报告同时在算时,任何一条 0.2 s 的咨询请求都会拿到 429(前端 `frontend/src/mastra/consultation-workflow.ts` 映射为 `workflow_rate_limited`)。
|
||
- 现在 429 发生时日志里看不出名额被谁占着,staging 上无法从记录确认这种「连带 429」的频率。
|
||
|
||
## 3. 根因
|
||
|
||
1. **BUG-1333**:合盘路由写于 BUG-161 之前或之外,没跟上「只读盘面的调用方带 skip」的约定;`/api/chart` 默认走完整链(为 MCP / 报告保留),于是任何漏带 skip 的调用方都会白付两个 VedAstro 子进程。串行 `await` 是写法问题。不是回归,是约定从没落到这个路由,也没有合同测试拦。
|
||
2. **BUG-1334**:PyJHora 回放为了 AGPL 隔离用子进程(正确),但没在父进程先判断「本机根本没装 PyJHora」;oracle 进度快照是给离线审计表用的,被挂在每份报告的技法审计表构建里,又没有进程内复用。
|
||
3. **名额**:闸门按「路径」一刀切,不按耗时分级;BUG-717 明令不得靠放宽路径或调高并发解决 429,所以轻重分名额不是技术问题,是产品取舍。
|
||
|
||
关联:BUG-161、BUG-301(前台仍取官方层)、BUG-715 / BUG-717(星盘页不得 429、不得放宽 `HEAVY_COMPUTE_PATHS` 或提高并发)、BUG-720(前台不得无上限排队)、BUG-721(禁止模块级缓存跨请求持有出生资料派生数据)、BUG-723(429 必须单独成档)、BUG-1302(预热不占名额)、BUG-1265 / 验收须模拟无 PyJHora。
|
||
|
||
## 4. 决策记录
|
||
|
||
- 产品负责人 2026-10-13 同意按排查结论全部立单交 Grok 执行;P1,必须 A/B。
|
||
- 授权范围:合盘改带 skip 并发;报告里与用户盘无关或必然失败的子进程在父进程短路;给闸门加观测。
|
||
- **不推翻 BUG-717**:本单**不**把任何路径移出 `HEAVY_COMPUTE_PATHS`,**不**新增第二个并发池,**不**改 `JYOTISH_HEAVY_COMPUTE_CONCURRENCY` 的语义与默认值。轻重分名额只做评估与模拟(T5),结论交产品**拍板**后另立单。
|
||
- **不推翻 BUG-161 / BUG-301**:`/api/chart` 不带 skip 时的默认行为(附 VedAstro 主入口概览)不变;报告、高严谨、MCP 的完整链不变。
|
||
- `/api/chart` 不带 skip 时占名额(T3)是**收紧**而非放宽,但会让 MCP 等外部调用方可能拿到 429,所以做成开关、**默认关**,A/B 有证据再提议打开(打开仍需拍板)。
|
||
|
||
## 5. 硬红线
|
||
|
||
1. `scripts/jyotish_api_server.py`:行数只按 `tests/test_api_server_growth_contract.py` 的粗护栏(AGENTS.md §6:不另加比测试更严的行数红线,也不得压行凑数),类方法数与 `JyotishAPIHandler.__new__` 伪造点不得增长。闸门的判定逻辑(含 BUG-1302 的 `consult_card_warm_only` 判断)可以搬进 `scripts/api_heavy_compute_gate.py`,主文件调用点保持一行。
|
||
2. `frontend/src/app/(app)/page.tsx` 不碰;不写第二套请求封装。
|
||
3. 不改 `deploy/**`、`.gitea/workflows/**`、数据库结构与迁移;不升级依赖。
|
||
4. 不改引擎数值。所有改动在「模拟生产依赖」与「装了 PyJHora」两种环境下,报告 Markdown(中英)与 `fact_table_packet` **逐字节一致**(去掉生成时间戳等已知易变字段,易变字段清单写进差分脚本并在 PROGRESS 列出)。
|
||
5. 进程内复用只允许缓存**与用户无关**的结论(PyJHora 是否可导入、静态 oracle 文件的校验结果,键含文件路径 + mtime + 大小);不得缓存任何含出生资料的结果(BUG-721)。
|
||
6. `tests/test_api_heavy_compute_gate.py` 现有断言(含 `"/api/chart" not in HEAVY_COMPUTE_PATHS`、`DEFAULT_CONCURRENCY == 2`)一条不改。
|
||
7. 改既有断言写「原值 / 新值 / 原因」三栏;golden 来自真实引擎输出。
|
||
|
||
## 6. 任务分解
|
||
|
||
### T1 · 合盘:带 skip、两两并发(BUG-1333)
|
||
|
||
- `frontend/src/app/api/synastry/route.ts`:两次 `/api/chart` 请求体加 `skip_vedastro_main_entry_overview: true`(在路由里加,**不改** `synastryBirthPayload`,因为 `global-birth-payloads.ts` 别处也用);`selfChart` / `partnerChart` 改 `Promise.all`;romance 分支两次 D9 `/api/varga_full` 改 `Promise.all`;`/api/synastry` 调用仍在两者之后。错误语义不变(任一失败仍走现有 `catch` 返回 `blocked`)。
|
||
- 新合同测试(前端):桩 `fetch`,断言两次 `/api/chart` 请求体都带 skip、两次是并发发出(第二次在第一次 resolve 之前已发出);romance 与 business 两分支的最终 JSON 与改前桩输出一致。
|
||
- 同时加一条**源码合同**:`frontend/src/app/api/**` 与 `frontend/src/lib/**` 里所有向 Python `/api/chart` 发的请求体都必须带 `skip_vedastro_main_entry_overview: true`,除非在白名单里写明理由(当前白名单为空)。
|
||
- 验收:`tsc --noEmit` 0 错、`npm run lint` 0 error、新测试与 `frontend/tests/chart-view-route.test.ts`、`frontend/tests/ephemeris-route.test.ts` 单文件通过。
|
||
- 分工:Grok 自跑;Claude 复验 + 前端全量 `npm test`。
|
||
|
||
### T2 · 报告子进程短路(BUG-1334)
|
||
|
||
- `scripts/annual_pyjhora_replay.py`:在起子进程前,父进程用 `importlib.util.find_spec("jhora")` 判断(进程内记一次,可被测试重置)。不可导入时**不起子进程**,直接返回与「子进程在无 PyJHora 环境下返回的结果」**完全相同**的 dict。做法:先在模拟生产环境里真实跑一次子进程,把返回值存成 golden(`tests/fixtures/…`,写明生成命令),短路分支的返回值必须与 golden 相等(`request_hash`、`settings` 等按入参计算的字段照常计算)。
|
||
- `scripts/tajika.py::_resolve_external_pyjhora_python`:结果进程内记一次(含「没找到」)。
|
||
- `scripts/jyotish_engine.py::_oracle_progress_snapshot`:按 (`oracle_file` 路径, mtime, 大小) 进程内记一次;文件变了自动重算。
|
||
- 不改:VedAstro 官方快照子进程;装了 PyJHora 时的子进程隔离(AGPL 边界,必须仍是子进程)。
|
||
- 验收:
|
||
- 新测试:无 PyJHora 时 `_run_isolated_tajaka_year_lord` / `_run_isolated_annual_replay` 不调用 `subprocess.run` 且返回值等于 golden;装了 PyJHora(或 `find_spec` 被桩成可用)时仍调用子进程;`_oracle_progress_snapshot` 连调两次只跑一次子进程,`touch` 文件后重跑。
|
||
- 既有 `tests/test_report_reader_main.py`、`tests/test_report_longform_parity.py`、`tests/test_report_density_facts.py` 及 `grep -rln "annual_pyjhora_replay\|_oracle_progress_snapshot\|_resolve_external_pyjhora_python" tests` 命中的测试全绿。
|
||
- 分工:Grok 自跑;Claude 复验 + 全量 pytest 与基线逐名比对(引擎相关文件有改动)。
|
||
|
||
### T3 · `/api/chart` 不带 skip 时占重计算名额(开关,默认关)(BUG-1333)
|
||
|
||
- `scripts/api_heavy_compute_gate.py` 新增 `acquire_heavy_compute_slot_for_request(path, body)`(或同义名):现有按路径的逻辑原样保留;另加:`path == "/api/chart"` 且 body 不带真值 `skip_vedastro_main_entry_overview` 且 body 不带 `async`/`enqueue` 且开关 `JYOTISH_GATE_CHART_OVERVIEW=1` 时,占一个名额。BUG-1302 的 `consult_card_warm_only` 判断一并搬进来。
|
||
- `jyotish_api_server.py` 调用点改成这一个函数(新逻辑放新模块,主文件只留调用)。
|
||
- `HEAVY_COMPUTE_PATHS` 不加 `/api/chart`。
|
||
- 验收:新测试——开关关时任何 `/api/chart` 都不占名额;开关开时只有不带 skip 的同步请求占名额,带 skip 的、`async` 的不占;`test_warm_consultation_does_not_consume_the_user_slot` 等既有测试不改仍绿。
|
||
- 分工:Grok 自跑;Claude 复验。
|
||
|
||
### T4 · 名额观测(BUG-1333 防复发的一部分)
|
||
|
||
- `api_heavy_compute_gate.py` 记录当前占名额的路径(只记路径字符串与开始时间,进程内计数);`HeavyComputeBusy` 抛出时,服务端打一行结构化日志:被拒路径、当前占用者路径列表与已占秒数。**不得**记 body、出生资料、用户标识。
|
||
- 若能不增长主文件:`/api/health` 的返回里加 `heavy_compute: {limit, in_use}`(只数字);做不到不增长就不做,写进 PROGRESS。
|
||
- 验收:新测试——饱和时日志行含占用者路径、不含 body 字段;释放后计数归零。
|
||
- 分工:Grok 自跑;Claude 复验。
|
||
|
||
### T5 · A/B 验证(P1 必做)
|
||
|
||
- 脚本 `scripts/research/api_chart_subprocess_ab.py`(位置执行方定,写进 PROGRESS)。A = 前置单合入后的 `origin/staging`(`git show <sha>:<path>` 导出到临时目录同进程 import),B = 本分支。每组重复 3 次取中位数,两种依赖环境(模拟生产 / 装了 PyJHora)各一遍;Grok 侧若装了 vedastro SDK 且有外网,再加一组「真 SDK」并如实标注。
|
||
1. **合盘**:同一对虚构盘,A 的调用序列(两次不带 skip、串行)vs B(两次带 skip、并发),在 Python 侧用线程池模拟并发。度量:总耗时、子进程数、响应字节。正确性:合盘最终 JSON(`selfChart`/`partnerChart` 摘要、`synastry`、`relationshipReport`)A/B 逐字节一致。
|
||
2. **报告**:`build_professional_report_reference`(真实请求形状),度量总耗时、子进程数与合计耗时;正确性:中英 Markdown 与 `fact_table_packet` 去易变字段后逐字节一致。
|
||
3. **闸门模拟**(评估用,不改生产行为):用真实 `api_heavy_compute_gate` 模块,按实测耗时用 `sleep` 模拟混合负载(例:每分钟 2 份报告、20 次咨询 0.2 s、6 次校正打分 8 s,随机种子固定),统计各路径 429 比例。比较方案:O1 现状;O2 轻路径独立小池(**违反 BUG-717,只模拟不实现**);O3 轻路径有界等待(≤1.5 s,不增并发,只模拟);O4 名额预留(重路径最多占 `N-1`,只模拟)。输出每个方案下咨询 429 率、报告/校正 429 率、CPU 最高并发数。
|
||
- 目标:合盘 chart 段耗时 B ≤ A 的 10%、子进程 4 → 0;报告子进程 B ≤ 3(模拟生产)、总耗时不劣于 A;所有正确性比对 0 差异。达不到如实写。
|
||
- 开关默认值:T3 默认关;T1、T2 不设开关(纯去冗余,正确性由逐字节比对保证)。
|
||
- 记录写 `docs/testing/api-chart-subprocess-gate-ab-20261013.md`;O1–O4 的模拟结果整理成给产品看的一张表(方案 / 咨询 429 率 / 报告 429 率 / 是否触碰 BUG-717)。
|
||
- 分工:Grok 跑并交记录;Claude 在 Linux 上复跑 1、2 两项(数字差 >20% 以 Claude 为准)。
|
||
|
||
### T6 · 记录
|
||
|
||
- `docs/BUG_HISTORY.md`:BUG-1333(`/api/chart` 漏带 skip 的合盘白付 VedAstro 子进程且串行、不占名额、429 无观测);BUG-1334(报告每份 10 个子进程,其中 PyJHora 回放在生产必然失败、oracle 静态校验每次重跑)。BUG-1334 的「验证」里写清生产收益是约 0.5–0.9 s / 份,不是 5 s。
|
||
- `docs/tasks/PROGRESS-api-chart-subprocess-gate-20261013.md`,含 T5 O1–O4 结论与「需拍板」一节。
|
||
- `CHANGELOG.md`:「合盘更快」一句。
|
||
- `docs/tasks/README.md` 索引加本单。
|
||
- 不改 `frontend/DESIGN.md`(无 UI 变化)。
|
||
|
||
## 7. 让步顺序
|
||
|
||
时间不够时按此顺序往后砍:T4 的 `/api/health` 字段 → T3 → T5.3 闸门模拟 → T2 的 `_resolve_external_pyjhora_python`。T1、T2 主体、T5.1–5.2、T6 不可砍。
|
||
|
||
## 8. 验收命令分工
|
||
|
||
| 谁 | 命令 |
|
||
| --- | --- |
|
||
| Grok 自跑 | `.venv` 下:`python -m pytest tests/test_api_heavy_compute_gate.py tests/test_api_server_growth_contract.py tests/test_report_reader_main.py tests/test_report_longform_parity.py tests/test_report_density_facts.py <T2/T3/T4 新测试> -q`;前端 `tsc --noEmit`、`npm run lint`、T1 新测试与 `chart-view-route` / `ephemeris-route` 单文件;T5 脚本。前端全量、Python 快速门、全量 pytest **不跑**,以 Claude 为准 |
|
||
| Claude 验收 | 上述全部 + `run_quality_gate.py --profile quick` + 全量 `pytest` 与基线逐名比对(T2 动了引擎文件)+ 前端全量 `npm test` + 在挡 `jhora` 的环境复跑 T2 测试与 T5.1–5.2 + `wc -l scripts/jyotish_api_server.py` 不超过开工值 |
|
||
| 不需要 | `test:db`;`next build` 只在 Claude 侧跑一次确认 `/` 仍 Static(只改了 API 路由) |
|
||
|
||
## 9. 开工前置命令
|
||
|
||
```bash
|
||
git fetch origin --prune
|
||
# 前置单必须已合入:
|
||
git log origin/staging --oneline | grep -i "api-disk-cache-retention\|BUG-1330" | head -3 # 必须有结果
|
||
git merge-base --is-ancestor origin/codex/api-disk-cache-retention-20261013 origin/staging && echo merged
|
||
git worktree add -b codex/api-chart-subprocess-gate-20261013 .worktrees/api-chart-subprocess-gate-20261013 origin/staging
|
||
cd .worktrees/api-chart-subprocess-gate-20261013
|
||
git log -1 --format=%h
|
||
grep -n "^## BUG-" docs/BUG_HISTORY.md | tail -3 # 确认 1333、1334 未被占
|
||
wc -l scripts/jyotish_api_server.py # 记下开工行数
|
||
grep -rn "skip_vedastro_main_entry_overview\|\"/api/chart\"" frontend/src --include=*.ts --include=*.tsx
|
||
grep -rln "annual_pyjhora_replay\|_oracle_progress_snapshot\|_resolve_external_pyjhora_python\|acquire_heavy_compute_slot" scripts tests
|
||
# Docker 镜像内核实(写进 PROGRESS):
|
||
# python -c "import sys,shutil;print(sys.executable, shutil.which('python3'), shutil.which('python3.14'))"
|
||
# python -c "import importlib.util as u;print(u.find_spec('jhora'))" # 预期 None
|
||
```
|
||
|
||
## 10. 环境缺口(预告)
|
||
|
||
- 生产装了 vedastro SDK:不带 skip 的 `/api/chart` 在开外网时的真实耗时(上限 `VEDASTRO_TIMEOUT_SECONDS`)本机测不到;合盘改动部署 staging 后,由 Claude 用虚构盘在内网复测一次合盘耗时,或写进 `docs/testing/` 清单交产品负责人在页面上计时。
|
||
- 闸门「连带 429」的真实频率:T4 上线后看 staging 日志一周再给产品结论。
|
||
- 轻重分名额方案(O2/O3/O4):**需产品拍板**,本单不实施。
|