Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.d/20260918-adr-0032-review-runner-occupancy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### ADR-0032 settles what may bound review runner occupancy (progress + admission), never model elapsed time

- Renumbered from the Draft #2207 / #2140 "ADR-0030" reconstruction: on current `main` ADR-0030 is already `0030-ci-centralization-scope-given-plan-ceiling.md`, so this decision is `docs/adr/0032-review-runner-occupancy-progress-bound.md`.
- `contextual-orchestrator#1118` changed `ModelClient.__init__`'s `timeout` default from `int = 90` to `float | None = None`. That removal is correct -- an implicit 90-second cap on the inference path is what ADR-0003's 2026-08-31 amendment forbids and what `#1889`/`#1890`/`#1892` were reverted for reintroducing -- but three layers then decline to bound the call: the library default is `None`, `contextual_orchestrator_review_launcher.py:1240` passes no `timeout`, and `noema-review.yml:261` states "No job-level `timeout-minutes` here, deliberately." Production evidence from `#1884` head `e85fc437` (run 34732993973, sidecar stderr artifact 10310273053) shows fifteen provider attempts in 907.3s across two agents on two credential accounts; eight of the ten measured attempt-to-failure durations land on exactly 90.0s, so the default is expiring requests that emitted no response bytes within the measured window. The same trace shows why elapsed time itself cannot be a model-failure verdict: `google/gemma-4-31b-it` was rejected at preflight after exactly 90.0s, which does not distinguish failure from a legitimately longer time-to-first-byte. ADR-0032 therefore bounds **progress/runner occupancy, not model elapsed time**. Within the external job boundary, active byte streaming is not interrupted by the idle-socket bound; a GitHub job ceiling or separately classified runner-reclamation event may still terminate the request without becoming a model-failure verdict or route-ranking signal. Before the first response byte, silence is classified only as a transport-level no-progress state: it does not prove provider/model failure and must not penalise, circuit-break, or rank the route if an occupancy bound expires. The threshold remains unnamed until pool-wide time-to-first-byte evidence supports one. Continuation admission separately prevents a breaker reset from immediately re-offering the same failing agent while equally ranked preflight-`ready` alternatives remain untried.
- Separately documents the Actions admission layer under the org plan concurrent-job ceiling (~60): multi-hour wall time is predominantly inter-job / schedule queue wait (`docs/doctoring/actions-capacity-root-cause-20260917.md`); coalesce tick keeps dedicated concurrency group `opencode-review-coalesce-tick` with `cancel-in-progress: false` for mid-dispatch safety but must **not** use runner reservation or step-scoped inert gates — job-level skip-before-admission (`#2242`) and post-merge live verify (`docs/doctoring/coalesce-tick-post-2242-live-verify-20260917.md`) are the admission contract. Model-path timeouts remain forbidden as an Actions-capacity repair. Refs #1884, #1915, #2137, #2139, #2140, #2207, #2242, #2244, ContextualWisdomLab/contextual-orchestrator#1118.
Loading
Loading