Files
Jyotisha/PROGRESS-engine-runtime-hygiene-20260901.md
T
Jesse_Chen 124d3990b2
Independent Staging Quality Gate / validate (push) Failing after 12m34s
Independent Staging Quality Gate / publish (push) Has been skipped
fix(api): persist scratch/local and bound heavy compute concurrency
Keep async job and chart-cache files across API recreates, freeze jyotish_api_server.py growth, and fail fast with 429 when rectification or high-rigor compute is saturated.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-02 06:12:23 +08:00

6.3 KiB
Raw Blame History

PROGRESS · Python 引擎运行时治理(2026-09-01

工作树:.worktrees/engine-runtime-hygiene-20260901
分支:codex/engine-runtime-hygiene-20260901
HEAD80e7736163be684119c03013a07980031468c634(仍等于 origin/staging

未提交、未推送。未改 frontend/src/app/page.tsx。未改 .gitea/workflows/**。未切分支、未 reset。迁移 squash 按任务书明确延后。

任务 1 · api 命名卷

  • 容器 WORKDIRdeploy/railway-api.Dockerfile):/app
  • 代码路径:Path(REPO_ROOT) / 'scratch' / 'local' / ... → 容器内 /app/scratch/local
  • Compose 卷名:api_scratch
  • 挂载:api_scratch:/app/scratch/localdeploy/docker-compose.server.yml 的 api 服务)
  • 项目前缀后的 Docker 卷名:jyotisha-staging_api_scratch / jyotisha-production_api_scratch
  • 向后兼容:首次 docker compose up 创建命名卷;当前 overlay 数据本就是易失的,无迁移

备份结论(已写入 deploy/README.md

  • Chart cache/app/scratch/local/api_chart_cache,默认 TTL 900s)不值得备份;重建比归档便宜。
  • Async / high-rigor job 态(async_jobs / async_jobs.sqlite3 / high_rigor_jobs,默认 TTL 3600s)是短生命周期进行中工作,不是恢复单元。
  • Staging 加密备份继续只走 deploy/backup-staging-postgres.sh不要api_scratch 加进该脚本。命名卷的唯一目标是容器重建后缓存与进行中任务还在。

Deploy 脚本: run-staging-deploy.sh / run-production-deploy.sh 未改docker compose up 会创建并重新挂上命名卷;现有 up -d --remove-orphans 不会 down -v

Staging 实机三条验收(blocked:需要真正 dispatch 部署后才能 docker volume ls、重启 api 证明 /app/scratch/local 存活、核对 /api/health。Compose 挂载合同已锁在 tests/test_railway_deployment.py

任务 2 · 冻结 jyotish_api_server.py

  • 开工 live wc -l11063(任务书 11035 已过时;出生精度合入后又涨了约 28 行)
  • 本轮薄注册后:11088
  • 合同上限:1136311063 + 300 bugfix slack
  • 测试:tests/test_api_server_growth_contract.py(注释写明新功能必须开模块)
  • 已列入 scripts/run_quality_gate.py CORE_PYTEST_TARGETS
  • AGENTS.md 第 8 节:scripts/jyotish_api_server.py must not grow;新端点/功能落 scripts/ 模块,主文件只薄注册

任务 3 · 重计算并发闸

新模块 scripts/api_heavy_compute_gate.py。主文件只 import,并在 do_POST 里 acquire/release。GET(含 /api/health 与 job 轮询)不经过闸门。

  • 环境变量 JYOTISH_HEAVY_COMPUTE_CONCURRENCY,默认 2(对齐 2 vCPU
  • JYOTISH_HEAVY_COMPUTE_RETRY_AFTER_SECONDS,默认 2
  • 饱和:fail-fast,不排队。HTTP 429 + Retry-After + error_code=ERR_COMPUTE_BUSY

入闸端点

  • POST /api/rectification/sensitivity_scan
  • POST /api/active_rectification_events
  • POST /api/active_rectification_events_v4
  • POST /api/rectification/v5/candidate-features
  • POST /api/rectification/v5/score
  • POST /api/rectification/v5/diagnostics
  • POST /api/rectification/v5/vedastro-validate
  • POST /api/dynamic_rectification_opportunities
  • POST /api/dynamic_rectification_score
  • POST /api/high_rigor_workflow
  • POST /api/consultation_workflow
  • POST /api/professional_reading
  • POST /api/vedastro/range_scan
  • POST /api/vedastro_gateway/run
  • POST /api/vedastro_gateway/jobs/{id}/run(前缀匹配)
  • POST /api/thematic_report

不入闸: GET /api/health、城市/位置解析、job 轮询、/api/chart(已有 TTL 缓存 + JYOTISH_ASYNC_JOB_* 有界队列;再叠 429 会误伤常规排盘)、问卷、v5 versions、capability/catalog 等轻量路由。

验证命令与输出

/opt/anaconda3/bin/python3.12 -m pytest \
  tests/test_api_server_growth_contract.py \
  tests/test_api_heavy_compute_gate.py -v
collected 7 items
tests/test_api_server_growth_contract.py ...                             [ 42%]
tests/test_api_heavy_compute_gate.py ....                                [100%]
============================== 7 passed in 0.28s ===============================

饱和用例(limit=1):第二个重请求 429 + Retry-After: 2 + ERR_COMPUTE_BUSY;释放后 200;同期 GET /api/healthPOST /api/location/resolve 仍 200。

/opt/anaconda3/bin/python3.12 -m pytest tests/test_api_server_security.py -q
# 129 passed, ~90s(仅 datetime.utcnow DeprecationWarning

/opt/anaconda3/bin/python3.12 -m pytest \
  tests/test_runtime_security_p0.py \
  tests/test_api_server_script_entrypoint.py -q
# 11 passed

/opt/anaconda3/bin/python3.12 -m pytest \
  tests/test_api_async_job_contract.py \
  tests/test_railway_deployment.py \
  tests/test_api_server_security.py::test_health_endpoint_exposes_runtime_accuracy_metadata \
  tests/test_api_server_security.py::test_vedastro_range_scan_endpoint_uses_user_birth_and_returns_controlled_blocked_state \
  tests/test_api_server_security.py::test_professional_reading_composes_high_rigor_and_gateway \
  tests/test_api_server_growth_contract.py \
  tests/test_api_heavy_compute_gate.py -v
# 22 passed in 0.38s

python3 scripts/pre_work_check.py --remote-timeout 8 --command-timeout 45status=pass

未改前端,故未跑 npm test / tsc。未跑完整 scripts/run_quality_gate.py --profile quickquick 仍会跑 Next.js test/lint/build;本轮前端豁免)。

改动文件

  • deploy/docker-compose.server.yml
  • deploy/README.md
  • AGENTS.md
  • scripts/jyotish_api_server.py(薄注册;+25 行)
  • scripts/api_heavy_compute_gate.py(新)
  • scripts/run_quality_gate.py
  • tests/test_api_server_growth_contract.py(新)
  • tests/test_api_heavy_compute_gate.py(新)
  • tests/test_railway_deployment.py
  • PROGRESS-engine-runtime-hygiene-20260901.md(本文件)

未改:deploy/run-staging-deploy.shdeploy/run-production-deploy.shdeploy/backup-staging-postgres.sh

明确未做 / blocked

  • Staging/production 实机挂卷、重启存活、/api/health 部署 SHA(需部署窗口)。
  • 完整 quick gate(含 frontend runtime)。
  • 迁移 squash。
  • /api/chart 同步路径送进这道闸。
  • 提交 / 推送 / 提升 main