fix(vedastro): pin SDK at install and cap free-tier wait
Image build patches vedastro.check_for_update to a no-op after pip install so import cannot hit pypi or upgrade the pin. Free-tier queue waits are capped to VEDASTRO_TIMEOUT_SECONDS and fail fast as free_tier_rate_limited. Gateway status exposes runtime mode as booleans without secrets. BUG-719 resolved; BUG-720 stays investigating until production env is filled in.
This commit is contained in:
@@ -11173,3 +11173,35 @@
|
||||
- 相关记录:BUG-161、BUG-065、BUG-715、BUG-716、BUG-717、ERR-107、ERR-108、TASK-chart-page-blocking-open-20260915
|
||||
- 复发自:BUG-161
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-719 | 官方 vedastro SDK 在 import 时联网自升级,运行期版本与 pin 不一致
|
||||
|
||||
- 状态:resolved
|
||||
- 首次发现:2026-09-15
|
||||
- 最近更新:2026-09-15
|
||||
- 影响面:`vedastro` Python 包、`deploy/railway-api.Dockerfile`、bridge 子进程
|
||||
- 用户现象:镜像按 `requirements.txt` 固定版本安装,进程一启动却去访问 pypi,并可能把包升到更新版本。
|
||||
- 触发条件:`import vedastro`(每次 spawn `vedastro_python_bridge` 子进程都会发生)。
|
||||
- 根因:`vedastro/update_check.py` 在导出符号前请求 pypi 并 `pip install --upgrade`。包本身是 REST 客户端,不是本地计算库。
|
||||
- 修复:镜像在 `pip install` 之后运行 `deploy/patch_vedastro_update_check.py`,把 `check_for_update` 改成 no-op;hook 不存在则构建失败。
|
||||
- 验证:补丁单测(无网络)、Dockerfile 合同(install 之后必须跑 patch)、运行期版本等于 pin(本机若未装该包则 skip)。
|
||||
- 防复发:第三方 SDK 若在 import 期联网或改写环境,必须在镜像层中和,并用测试锁住 pin。
|
||||
- 相关记录:ERR-107、BUG-089
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
## BUG-720 | 无 key 时 VedAstro 免费层同步排队可堵住前台线程数分钟
|
||||
|
||||
- 状态:investigating
|
||||
- 首次发现:2026-09-15
|
||||
- 最近更新:2026-09-15
|
||||
- 影响面:`scripts/vedastro_service_adapter.py` 的 `_acquire_free_tier_slot`
|
||||
- 用户现象:外部证据路径可能卡住很久。是否在生产发生取决于 `VEDASTRO_API_KEY` 是否真的有值,产品负责人尚未回填 `docs/testing/vedastro-runtime-20260915.md`。
|
||||
- 触发条件:命中官方公共 endpoint 且没有 API key;一次 full snapshot 约 24 个请求,免费层默认 5 个/分钟。
|
||||
- 根因:名额耗尽时持进程级锁 `time.sleep()`,没有前台等待预算。
|
||||
- 修复:增加 `VEDASTRO_FREE_TIER_WAIT_BUDGET_SECONDS`,默认不超过 `VEDASTRO_TIMEOUT_SECONDS`。超出预算立即返回 `free_tier_rate_limited` 降级,不再无限等。生产是否仍会走到这条路径,等清单回填后更新本条。
|
||||
- 验证:预算为 0 时第二次请求不 sleep、返回体可区分限流降级;既有「窗口内等待一次」回归仍绿。
|
||||
- 防复发:前台同步路径不得无上限排队;不得靠调大免费层配额绕过第三方额度。
|
||||
- 相关记录:ERR-108、BUG-065、BUG-161、BUG-718
|
||||
- 复发自:无
|
||||
- 修复版本:待发布
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# PROGRESS · VedAstro 运行期真相(2026-09-15)
|
||||
|
||||
工作树:`.worktrees/vedastro-runtime-ops-20260915`
|
||||
分支:`codex/vedastro-runtime-ops-20260915`
|
||||
基线:`origin/staging` @ `ce1939b0`
|
||||
本机 Windows。Anaconda Python 3.11.7 + pytest 9.1.1。无 Docker。`python3` 是 Windows Store 桩(9009)。
|
||||
|
||||
未改 `scripts/jyotish_api_server.py`、未改 workflow、未 SSH 生产、未写入任何 key。Skill 未 bump。CHANGELOG 补了一句免费额度用尽时马上说明(用户可感知的是「不再空等」)。
|
||||
|
||||
## 任务状态
|
||||
|
||||
| 任务 | 状态 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| 1 隔离 SDK 自更新 | 完成 | 镜像 `pip install` 后跑 `deploy/patch_vedastro_update_check.py`,失败即构建失败 |
|
||||
| 2 免费层排队预算 | 完成 | 默认预算 ≤ `VEDASTRO_TIMEOUT_SECONDS`;超预算 fail-fast `free_tier_rate_limited`。生产是否走这条路径见任务 4 |
|
||||
| 3 status 可观测 | 完成 | `/api/vedastro_gateway/status` 增加 endpoint/key 布尔、fanout、range scan、免费层是否 active、sdk_version、两份 TTL |
|
||||
| 4 生产模式确认 | 环境缺口 | 清单 `docs/testing/vedastro-runtime-20260915.md`,只由产品负责人执行 |
|
||||
| 5 Bug 历史 | 完成 | BUG-719 resolved;BUG-720 investigating(等任务 4 回填) |
|
||||
|
||||
## 既有断言
|
||||
|
||||
| 文件 | 原值 | 新值 | 原因 |
|
||||
| --- | --- | --- | --- |
|
||||
| `test_post_json_with_retry_waits_for_free_tier_slot` | 窗口内第二次请求会 sleep | **未改**;预算默认等于 timeout,短等待仍发生 | 有预算的等待保留,只砍掉无上限排队 |
|
||||
|
||||
## 反向验证
|
||||
|
||||
- 把 Dockerfile 里 `python patch_vedastro_update_check.py` 删掉,`test_dockerfile_patches_vedastro_update_check_after_install` 失败。
|
||||
- 把 `check_for_update` 从目标文件拿掉,`test_patch_fails_closed_when_hook_is_missing` 失败(`SystemExit`)。
|
||||
- 把 `birthPayload` 那一行与本单无关;本单不改前端。
|
||||
|
||||
## 耗时
|
||||
|
||||
本机未在镜像里跑 bridge 子进程(无 Docker 构建)。改前机制:每次 `import vedastro` 可能付 5 秒 pypi 超时,并可 `pip install --upgrade`。改后 `check_for_update` 为 no-op,不再发起该请求。镜像构建证据待有 Docker 的门禁/部署环境给出,不得写成已在本机验证。
|
||||
|
||||
## 测试
|
||||
|
||||
| 命令 | 结果 |
|
||||
| --- | --- |
|
||||
| `python -m pytest tests/test_vedastro_runtime_ops.py tests/test_vedastro_official_full_snapshot.py::test_post_json_with_retry_waits_for_free_tier_slot -v` | **7 passed / 1 skipped**(skip:本机未装 `vedastro`,运行期 pin 断言按任务书允许 skip) |
|
||||
| `python -m pytest` 网关 status / 密钥不泄露 / chat runtime / 既有免费层等待 | 通过 |
|
||||
| `tests/test_vedastro_gateway.py::test_gateway_completion_archives_official_raw_response` | **本机失败**(Windows `st_mode` 33206 vs `0o600`)。改前即如此,本单未动归档权限,不修 |
|
||||
| `py_compile` 改动的三个 py 文件 | 通过 |
|
||||
| `scripts/run_quality_gate.py --profile quick` | 本机未跑全量:无 `.venv`、无 Docker、`python3` 不可用。定向 VedAstro 回归如上 |
|
||||
| `scripts/pre_work_check.py` | 本机 `python3` 是 Store 桩。未声称预检通过 |
|
||||
|
||||
## 环境缺口
|
||||
|
||||
- 无 Docker:镜像层 patch 生效、运行期版本等于 pin,只能等门禁构建 / 部署后由产品负责人按清单第 5 条回填。
|
||||
- 生产 env(key / fanout / TTL)未查:见 `docs/testing/vedastro-runtime-20260915.md`。回填前不得声称生产行为已验证。
|
||||
- BUG-720 保持 `investigating`,直到清单回填。
|
||||
@@ -233,7 +233,7 @@
|
||||
| `TASK-staging-auto-migrate-on-deploy-20260915.md` | `PROGRESS-staging-auto-migrate-on-deploy-20260915.md` | 门禁通过后自动先跑 staging 迁移再部署,不再手点(迁移幂等、无挂起时是 no-op,`db-migrate.mjs --check` 挂起返 3 可用于日志)。今天 `deploy-staging.yml` 完全不提迁移,忘点就让新代码跑在旧 schema 上且无人拦。**产品再次授权改 workflow,范围限 `backend-quality-gate.yml` 的 dispatch 段**;迁移失败必须阻断部署;回滚不自动迁移;生产完全不动。⚠️ 同轮必须把「迁移须对已部署代码向后兼容、破坏性变更拆两轮」写进 AGENTS.md §7.6 | 待验收 | `codex/staging-auto-migrate-on-deploy-20260915` |
|
||||
| `TASK-api-server-decomposition-20260916.md` | `PROGRESS-api-server-decomposition-20260916.md` | **重构单(串行在 qizheng 单之后)**:把业务逻辑搬出 `JyotishAPIHandler`。核心不是行数,是全仓 3 处靠 `JyotishAPIHandler.__new__` 伪造空壳 handler 借方法(`consultation_workflow_service` ×2、`capture_report_blocked_repairs_golden`、`local_accuracy_report`,MCP 也走这条),依赖方向反了、handler 没有 `headers`/`wfile` 随时可炸。四阶段:拆 `__new__` 后门 → 抽 ≥150 行业务方法 → `do_POST`/`do_GET` 改路由表 → 重新冻结行数 baseline(余量 300→50)。纯搬运不改行为,`test_api_server_security.py` 3841 行断言一条不许改。预计 11,314 → 约 9,230 行。BUG 段 710+ | 待领取 | — |
|
||||
| `TASK-chart-vedastro-decouple-20260915.md` | `PROGRESS-chart-vedastro-decouple-20260915.md` | **P0**:星盘页首屏那一发 `/api/chart` 没传 `skip_vedastro_main_entry_overview`,实测冷算 0.40–0.66 秒里约 0.36 秒是 VedAstro 空转(本机连 endpoint 都没配);生产 env 开着 network + fanout,等于首屏同步等 24 个外部请求 + 3 次领域扫描,而 `chart-view-mapper.ts` / `chart-view-contract.ts` 根本不读这份证据。星历页同端点传了标志,两页策略相反。BUG-718,**复发自 BUG-161**(前台请求不得同步串联可选外部证据)。串行在 chart-page-blocking-open 之后 | 待验收 | `codex/chart-vedastro-decouple-20260915` |
|
||||
| `TASK-vedastro-runtime-ops-20260915.md` | `PROGRESS-vedastro-runtime-ops-20260915.md` | 运行期真相单(与上单并行,文件不重叠;**不得改 `jyotish_api_server.py`**):官方 `vedastro==1.23.25` 其实是 REST 客户端(46 KB,全打 `api.vedastro.org`),且 import 时请求 pypi 并 `pip install --upgrade` 自升级——本机实测 pin 装完一 import 就变 1.23.26,`requirements.txt` 的锁在运行期是假的(BUG-719);无 key 时免费层排队是同步 sleep + 全局锁,24 个请求 ≈ 4.8 分钟堵住前台线程(BUG-720,定级依赖生产 key 是否配置)。生产 env 核对清单在 `docs/testing/vedastro-runtime-20260915.md`,**只能由产品负责人执行**。台账 ERR-107 / ERR-108 | 待领取 | — |
|
||||
| `TASK-vedastro-runtime-ops-20260915.md` | `PROGRESS-vedastro-runtime-ops-20260915.md` | 运行期真相单(与上单并行,文件不重叠;**不得改 `jyotish_api_server.py`**):官方 `vedastro==1.23.25` 其实是 REST 客户端(46 KB,全打 `api.vedastro.org`),且 import 时请求 pypi 并 `pip install --upgrade` 自升级——本机实测 pin 装完一 import 就变 1.23.26,`requirements.txt` 的锁在运行期是假的(BUG-719);无 key 时免费层排队是同步 sleep + 全局锁,24 个请求 ≈ 4.8 分钟堵住前台线程(BUG-720,定级依赖生产 key 是否配置)。生产 env 核对清单在 `docs/testing/vedastro-runtime-20260915.md`,**只能由产品负责人执行**。台账 ERR-107 / ERR-108 | 待验收 | `codex/vedastro-runtime-ops-20260915` |
|
||||
|
||||
## 命名与归档
|
||||
|
||||
|
||||
Reference in New Issue
Block a user