fix(pipeline-status): align TS wrapper timeout with CI polling budget #69

Merged
slaid098 merged 3 commits from fix/pipeline-status-timeout-alignment into main 2026-08-13 18:42:44 +03:00
Owner

Что сделано

  • .opencode/tools/pipeline-status.ts:15: timeout: 60000 → timeout: 480000 (480s) — TS-обёртка spawnSync теперь даёт Python-оракулу полный CI polling budget вместо того, чтобы убивать его на 60-й секунде.
  • .opencode/scripts/pipeline-status.py:61: CI_WAIT_TIMEOUT = 300 → CI_WAIT_TIMEOUT = 420 (7 мин) — budget CI poll loop увеличен с 5 до 7 минут, чтобы покрывать длинные CI-прогоны.
  • tests/test_pipeline_status_tool.py:133: assert timeout == 60000 → timeout == 480000; переписан docstring — прежний «headroom over 10s×3=32s» описывал Forgejo-запрос, а не CI-поллинг (семантическая ошибка).
  • .env.example: добавлены OPENCODE_CI_WAIT_TIMEOUT=420 и OPENCODE_CI_POLL_INTERVAL=10 — env-override в Python уже существовал и тестирован, но не был задокументирован.

Почему

TS-обёртка pipeline-status.ts ставила spawnSync({ timeout: 60000 }) (60s), но Python-оракул pipeline-status.py опрашивает CI до CI_WAIT_TIMEOUT=300 секунд. Любой CI-прогон дольше 60s приводил к тому, что spawnSync убивал процесс по SIGTERM — оракул не дорабатывал poll loop и возвращал ошибку вместо финального статуса CI. Это ломало пайплайн на CI-фазе для реальных прогонов.

Правка выравнивает таймауты: 480000ms (TS) > 420s (Python) + overhead, так что оракул гарантированно дорабатывает весь poll budget. CI_POLL_INTERVAL = 10 намеренно не меняется.

Watch out

  • 60000 литерал остаётся в spec-status.ts, project-status.ts и create-pr.ts — у них другая семантика (локальные быстрые операции, не CI-поллинг). Слепой find-and-replace 60000 → 480000 по репо был бы ошибкой — правка точечная.
  • Если в окружении заданы env-переменные OPENCODE_CI_WAIT_TIMEOUT/OPENCODE_CI_POLL_INTERVAL, они переопределяют константы в коде — поведение Python не меняется, меняется только дефолт.
  • Coverage-порог 80% в CI не достигается этим PR (тесты покрывают только pipeline-status) — это предсуществующее состояние, не регрессия.

Pending

  • Обновить memory-запись repos/slaid098/opencode-config.md после merge (фаза MEMORY пайплайна).
  • Рассмотреть выравнивание spec-status.ts/project-status.ts отдельным issue, если их 60s таймаут окажется недостаточным для их use-case (вне scope этого PR).

Closes #68

## Что сделано - `.opencode/tools/pipeline-status.ts:15`: `timeout: 60000` → `timeout: 480000` (480s) — TS-обёртка `spawnSync` теперь даёт Python-оракулу полный CI polling budget вместо того, чтобы убивать его на 60-й секунде. - `.opencode/scripts/pipeline-status.py:61`: `CI_WAIT_TIMEOUT = 300` → `CI_WAIT_TIMEOUT = 420` (7 мин) — budget CI poll loop увеличен с 5 до 7 минут, чтобы покрывать длинные CI-прогоны. - `tests/test_pipeline_status_tool.py:133`: assert `timeout == 60000` → `timeout == 480000`; переписан docstring — прежний «headroom over 10s×3=32s» описывал Forgejo-запрос, а не CI-поллинг (семантическая ошибка). - `.env.example`: добавлены `OPENCODE_CI_WAIT_TIMEOUT=420` и `OPENCODE_CI_POLL_INTERVAL=10` — env-override в Python уже существовал и тестирован, но не был задокументирован. ## Почему TS-обёртка `pipeline-status.ts` ставила `spawnSync({ timeout: 60000 })` (60s), но Python-оракул `pipeline-status.py` опрашивает CI до `CI_WAIT_TIMEOUT=300` секунд. Любой CI-прогон дольше 60s приводил к тому, что `spawnSync` убивал процесс по SIGTERM — оракул не дорабатывал poll loop и возвращал ошибку вместо финального статуса CI. Это ломало пайплайн на CI-фазе для реальных прогонов. Правка выравнивает таймауты: 480000ms (TS) > 420s (Python) + overhead, так что оракул гарантированно дорабатывает весь poll budget. `CI_POLL_INTERVAL = 10` намеренно не меняется. ## Watch out - `60000` литерал остаётся в `spec-status.ts`, `project-status.ts` и `create-pr.ts` — у них другая семантика (локальные быстрые операции, не CI-поллинг). Слепой find-and-replace `60000` → `480000` по репо был бы ошибкой — правка точечная. - Если в окружении заданы env-переменные `OPENCODE_CI_WAIT_TIMEOUT`/`OPENCODE_CI_POLL_INTERVAL`, они переопределяют константы в коде — поведение Python не меняется, меняется только дефолт. - Coverage-порог 80% в CI не достигается этим PR (тесты покрывают только pipeline-status) — это предсуществующее состояние, не регрессия. ## Pending - Обновить memory-запись `repos/slaid098/opencode-config.md` после merge (фаза MEMORY пайплайна). - Рассмотреть выравнивание `spec-status.ts`/`project-status.ts` отдельным issue, если их 60s таймаут окажется недостаточным для их use-case (вне scope этого PR). Closes #68
docs(env): document OPENCODE_CI_WAIT_TIMEOUT and OPENCODE_CI_POLL_INTERVAL
All checks were successful
CI (always) / bootstrap (pull_request) Successful in 4s
CI / bootstrap (pull_request) Successful in 7s
CI / typecheck (pull_request) Successful in 28s
CI / complexity (pull_request) Successful in 27s
CI / lint (pull_request) Successful in 28s
CI / test (3.13) (pull_request) Successful in 1m46s
48e4a26a7f
Author
Owner

Code Review Summary

PR точечно выравнивает таймауты TS-обёртки и Python-оракула: spawnSync timeout 60s→480s (480000ms) и CI_WAIT_TIMEOUT 300→420. Корневая причина (SIGTERM-убийство оракула на 60-й секунде при CI-прогоне >60s) устранена корректно. Дифф минимален (4 файла, +18/−9), тест-регресс обновлён, env-override задокументирован.

Positives

  • Точечная правка: изменены только pipeline-status файлы + .env.example; spec-status.ts, project-status.ts, create-pr.ts не тронуты (их 60000 имеет другую семантику — локальные быстрые операции, не CI-поллинг). Find-and-replace был бы ошибкой — автор правильно этого избежал.
  • Математика сходится: 480000ms (TS) > 420s (Python) + overhead → оракул гарантированно дорабатывает poll loop. CI_POLL_INTERVAL = 10 намеренно сохранён.
  • Тест-регресс обновлён синхронно: test_execute_passes_timeout_to_spawnsync assert 480000 + переписанный docstring исправляет семантическую ошибку (прежде описывал Forgejo HTTP timeout, а не CI-поллинг).
  • Env-документация: .env.example описывает обе переменные с пояснением инварианта TS timeout >= wait_timeout + overhead.
  • PR body качественный: ## Что сделано / ## Почему / ## Watch out / ## Pending заполнены осмысленно, Watch out явно документирует риск ложного find-and-replace и env-override.

Suggestions (info, not blocking)

  • pipeline-status.ts:6 [stale-doc] Tool description всё ещё говорит "Blocks up to 5 min while CI runs" — но CI_WAIT_TIMEOUT теперь 420s = 7 мин, не 5. Описание стало неточным после увеличения budget. Fix: заменить "5 min" → "7 min" (или "up to CI_WAIT_TIMEOUT").

  • pipeline-status.ts:18 [stale-literal] Error message "timed out (60s)" хардкодит старое значение — но timeout теперь 480000ms = 480s. Если timeout действительно сработает (редкий случай), пользователь увидит误导ющее "60s". Fix: "timed out (480s)" или вычислять из константы.

  • tests/test_pipeline_status_tool.py:156,172 [paired-stale] test_execute_timeout_returns_readable_error docstring говорит "mentioning the 60s timeout" и assert "60s" in result. Тест проходит (потому что line 18 ещё хардкодит "60s"), но это paired stale state: если line 18 исправят на "480s", этот тест сломается. Fix: при обновлении line 18 синхронно обновить docstring + assert на "480s".

Примечание: три замечания выше — cosmetic drift, не блокируют merge. Core fix корректен, функциональное поведение правильное, тесты зелёные. Рекомендуется завести отдельный issue для зачистки stale-строк (или включить в этот PR, если автор хочет).

Verdict: APPROVE

## Code Review Summary PR точечно выравнивает таймауты TS-обёртки и Python-оракула: `spawnSync` timeout 60s→480s (480000ms) и `CI_WAIT_TIMEOUT` 300→420. Корневая причина (SIGTERM-убийство оракула на 60-й секунде при CI-прогоне >60s) устранена корректно. Дифф минимален (4 файла, +18/−9), тест-регресс обновлён, env-override задокументирован. ### Positives - **Точечная правка**: изменены только pipeline-status файлы + .env.example; `spec-status.ts`, `project-status.ts`, `create-pr.ts` не тронуты (их `60000` имеет другую семантику — локальные быстрые операции, не CI-поллинг). Find-and-replace был бы ошибкой — автор правильно этого избежал. - **Математика сходится**: 480000ms (TS) > 420s (Python) + overhead → оракул гарантированно дорабатывает poll loop. `CI_POLL_INTERVAL = 10` намеренно сохранён. - **Тест-регресс обновлён синхронно**: `test_execute_passes_timeout_to_spawnsync` assert `480000` + переписанный docstring исправляет семантическую ошибку (прежде описывал Forgejo HTTP timeout, а не CI-поллинг). - **Env-документация**: `.env.example` описывает обе переменные с пояснением инварианта `TS timeout >= wait_timeout + overhead`. - **PR body** качественный: `## Что сделано` / `## Почему` / `## Watch out` / `## Pending` заполнены осмысленно, `Watch out` явно документирует риск ложного find-and-replace и env-override. ### Suggestions (info, not blocking) - **pipeline-status.ts:6** [stale-doc] Tool `description` всё ещё говорит `"Blocks up to 5 min while CI runs"` — но `CI_WAIT_TIMEOUT` теперь 420s = 7 мин, не 5. Описание стало неточным после увеличения budget. Fix: заменить `"5 min"` → `"7 min"` (или `"up to CI_WAIT_TIMEOUT"`). - **pipeline-status.ts:18** [stale-literal] Error message `"timed out (60s)"` хардкодит старое значение — но timeout теперь 480000ms = 480s. Если timeout действительно сработает (редкий случай), пользователь увидит误导ющее "60s". Fix: `"timed out (480s)"` или вычислять из константы. - **tests/test_pipeline_status_tool.py:156,172** [paired-stale] `test_execute_timeout_returns_readable_error` docstring говорит `"mentioning the 60s timeout"` и assert `"60s" in result`. Тест проходит (потому что line 18 ещё хардкодит "60s"), но это paired stale state: если line 18 исправят на "480s", этот тест сломается. Fix: при обновлении line 18 синхронно обновить docstring + assert на `"480s"`. Примечание: три замечания выше — cosmetic drift, не блокируют merge. Core fix корректен, функциональное поведение правильное, тесты зелёные. Рекомендуется завести отдельный issue для зачистки stale-строк (или включить в этот PR, если автор хочет). ### Verdict: APPROVE
slaid098 deleted branch fix/pipeline-status-timeout-alignment 2026-08-13 18:42:44 +03:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
slaid098/opencode-config!69
No description provided.