-
Notifications
You must be signed in to change notification settings - Fork 1
fix(routing): select concrete free model groups #971
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Draft
seonghobae
wants to merge
137
commits into
main
Choose a base branch
from
fix/model-group-timeout-openrouter
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+6,682
−406
Draft
Changes from 83 commits
Commits
Show all changes
137 commits
Select commit
Hold shift + click to select a range
8a90464
fix(routing): select concrete free model groups
seonghobae 4a5122b
fix(discovery): remove default network deadlines
seonghobae a367701
fix(groups): preserve exact model identity
seonghobae 684f188
docs(gaps): align routing baseline with no-timeout policy
seonghobae a331beb
docs(gaps): distinguish implementation revision from PR head
seonghobae 5abd66e
fix(routing): cancel raced provider transports
seonghobae 643f02b
fix(discovery): migrate exact model identities
seonghobae 248ed66
fix(routing): finalize race and legacy sync once
seonghobae fec7ac5
fix(discovery): activate refreshed legacy endpoint
seonghobae 85216e7
fix(routing): preserve legacy discovery contracts
seonghobae 5e638a7
fix(discovery): activate migrated legacy agents
seonghobae 0a49fc3
fix(discovery): activate only discovered legacy agents
seonghobae 9348385
fix(discovery): skip manual legacy id collisions
seonghobae 81f3a24
fix(routing): remove readiness network deadlines
seonghobae 94d3ca3
fix(routing): preserve cancellable no-timeout transport
seonghobae f185f90
fix(transport): make unbounded setup cancellable
seonghobae f993c2a
fix(transport): bound cancellable resolver ownership
seonghobae 2183040
fix(discovery): release failed resolver ownership
seonghobae 51a3642
fix(readiness): keep slow probes nonblocking
seonghobae 011083c
fix(discovery): protect operator-owned agent identities
seonghobae dab4246
fix(discovery): preflight durable identity conflicts
seonghobae c4e7ad6
fix(discovery): canonicalize Unicode legacy IDs
seonghobae e2deddf
ci(opencode): wait without a readiness deadline
seonghobae 7f92e44
fix(discovery): preserve historical Unicode agent IDs
seonghobae b7991a8
ci(opencode): stop waiting after gateway exit
seonghobae 5ce6ec5
docs(bytez): correct prefix-free authorization contract
seonghobae 8f0c476
fix(embeddings): quarantine rejected endpoints
seonghobae 60526ba
fix(privacy): enforce OpenRouter ZDR at request time (#953)
seonghobae 375d8c2
fix(embeddings): preserve endpoint quarantine semantics
seonghobae b51f0b1
fix(embeddings): map quarantine to availability
seonghobae 8569a06
fix(ci): bound gateway readiness wait
seonghobae 3124d7a
fix(ci): reserve maintenance runtime after discovery
seonghobae edc243f
fix(ci): reserve full maintenance budget
seonghobae 2bc1b08
fix(ci): keep gateway and inference waits unbounded
seonghobae 5e73d6b
fix(network): remove OpenRouter evidence deadlines
seonghobae e1977a5
fix(network): bound control-plane evidence calls
seonghobae 39c8092
revert: keep control-plane evidence waits unbounded
seonghobae 7e8257a
docs(gap): refresh model-group delivery evidence
seonghobae 117aa18
Merge origin/main into fix/model-group-timeout-openrouter
70cddd8
fix: repair merge-interaction bugs found while validating tests/main …
3ca6b7c
test(responses): fix 3 tests stale after orchestrator/free auto-route…
claude 4d2d5b4
test(provider): cover DeepSeek 502 recovery and no default deadline
seonghobae ef88d16
test: generalize provider retry and inference deadline contract
seonghobae 6bc0834
test: remove model-specific resilience fixture
seonghobae fd593a3
test(routing): retain default connection-deadline contract
seonghobae 6f588c0
ci: repair PR 971 exact-head findings
seonghobae fb6d8ba
ci: fit PR971 repair to slim-runner and publish scope
seonghobae 66d49f0
ci: repair PR971 source-fix workflow parse
seonghobae c1dcff6
test(routing): fail closed on unproven default retries
seonghobae 7f64c80
chore(repair): add PR971 default-retry source fix
seonghobae ce07141
chore(repair): add PR971 default-retry TDD workflow
seonghobae ffafb7c
chore(repair): trigger PR971 default-retry source fix
seonghobae 90838d6
fix(repair): make PR971 exact-head repair transactional
seonghobae 7486a1d
fix(ci): make PR971 repair publishable and least-privileged
seonghobae 92ff90b
ci: retrigger PR971 default retry source fix
seonghobae 5b71340
Merge remote-tracking branch 'origin/main' into fix/model-group-timeo…
claude 65d3c60
chore(repair): retrigger PR971 default-retry source fix
seonghobae 2aa206c
fix(routing): remove unproven default provider retry allocation
claude 039d86c
Merge remote-tracking branch 'origin/fix/model-group-timeout-openrout…
claude e4cacff
ci: run exact-head persisted embedding repair
seonghobae 6c379a4
fix(ci): repair PR971 one-shot YAML and timeout regression
seonghobae 8d19b28
ci: isolate PR971 one-shot repair helper
seonghobae 6fed18c
fix(ci): make PR971 repair workflow parse-safe
seonghobae 56a34ab
fix(embeddings): fix default-timeout OverflowError, recovered-ZDR rev…
claude bfb2e81
fix(discovery): disable failed configured-gateway probes under a pers…
claude a7550d0
fix(embeddings): quarantine a repeatedly incomplete sync member, not …
claude 2c8804a
fix(uptime): bound the background OpenRouter uptime fetch independent…
claude 3832a3e
docs(pr971): record dated review findings and self-modifying workflow…
claude aaa3a68
test(race): preserve failed loser provenance
seonghobae 9aa2eec
fix(race): preserve terminal loser provenance
seonghobae 56127e3
chore(review): stage PR971 exact-head quality repair
seonghobae 79b9cb9
chore(review): run PR971 RED-GREEN owner repair
seonghobae 353cb96
fix(review): fold discovery and provider-diversity regressions into P…
seonghobae 170103c
fix(review): require discovery and failure-domain GREEN
seonghobae 6723792
fix(discovery): bound per-provider model discovery independent of any…
claude 3dd989b
test(discovery): prove bootstrap pool selection is genuinely provider…
claude b415b41
docs(pr971): record the discovery-deadline and bootstrap-diversity fixes
claude 5f45887
Merge remote-tracking branch 'origin/fix/model-group-timeout-openrout…
claude 9b8f609
chore(review): remove now-superseded PR971 review-quality repair work…
claude fff6424
chore(ci): run exact-head review-quality owner repair
seonghobae 109df43
test(review): add PR 971 false-negative regressions
seonghobae be23a2a
chore(ci): add temporary PR 971 repair helper
seonghobae 03b620a
fix(ci): make PR 971 repair workflow parse-safe
seonghobae e3fa6d9
fix(cost_router): restore request_policy and reject mixed-ZDR embeddi…
claude 12967aa
fix(discovery): bound shared metadata fetches and eliminate a ThreadP…
claude c07e67b
fix(ci): publish PR 971 repair with workflow-starting token
seonghobae 4949626
fix(server): fail over terminal-failure batch embedding documents
claude 0d77445
fix(discovery): bound OpenRouter free-endpoint fetch to a fixed 8-wor…
claude 9a2e3a4
Merge remote-tracking branch 'origin/fix/model-group-timeout-openrout…
claude 56785d7
test(review): stage current PR 971 false-negative repairs
seonghobae 3d520fb
ci(review): run current exact-head PR 971 repair
seonghobae fe13068
fix(ci): cancel stale PR971 repair runs
seonghobae 41aaeff
Merge remote-tracking branch 'origin/fix/model-group-timeout-openrout…
claude d932026
Merge remote-tracking branch 'origin/main' into HEAD
claude 9b28bd2
fix(routing): eliminate a ThreadPoolExecutor shutdown-block in endpoi…
claude a3afc80
fix(race): settle futures when review callbacks fail
seonghobae 83582ad
test(race): cover callback failure settlement
seonghobae 742b5d5
docs(changelog): trace endpoint race callback settlement
seonghobae 0247eca
chore(ci): retire stale PR 971 source-fix workflow
seonghobae d388564
chore(ci): remove retired PR 971 source-fix helper
seonghobae 29bc5b7
test: align bootstrap selector oracle comment
seonghobae 59b2fc8
fix(routing): eliminate a ThreadPoolExecutor shutdown-block in provid…
claude d402ec0
Merge remote-tracking branch 'origin/fix/model-group-timeout-openrout…
claude d29198e
test: prove blocked embedding worker cannot hold process exit
seonghobae 7dc5ee7
test: keep single stronger embedding process-exit regression
seonghobae 02389e2
test: reject daemon worker submissions after shutdown
seonghobae 8caf844
ci: run one-shot daemon pool shutdown repair
seonghobae 18a76eb
fix(routing): reject _DaemonWorkerPool submissions after shutdown
claude d87a1cb
Merge remote-tracking branch 'origin/fix/model-group-timeout-openrout…
claude 558c847
docs(changelog): trace daemon pool post-shutdown submit fail-fast fix
claude df9f380
fix(routing): close daemon worker admission before shutdown drain
claude 09f0249
chore(ci): remove obsolete PR971 daemon-pool-shutdown repair workflow
claude 2510766
docs(gap-baseline): record PR 971 merge-resolution and concurrency-bu…
claude b05d028
Merge remote-tracking branch 'origin/fix/model-group-timeout-openrout…
claude 770dada
test(bootstrap): reproduce durable report identity mismatch
seonghobae 7369d48
fix(bootstrap): report persisted selected identities
seonghobae 3acc6cd
test(catalog): reproduce durable report identity mismatch
seonghobae d02c97c
fix(catalog): report persisted selected identities
seonghobae 696fd17
docs(changelog): record durable bootstrap identity contract
seonghobae 121d898
Merge protected main into fix/model-group-timeout-openrouter
seonghobae 2d8e233
docs(gap-baseline): track immutable release + resumable execution gap
claude df587e1
docs(gap-baseline): fix citations Devin Review flagged on the new entry
claude 8b05b83
merge(main): restack PR 971 and repair exact RED fixtures
seonghobae 521e613
fix(actions): remove merge artifact from hourly workflow
seonghobae 6ddc6b4
test(bootstrap): make identity regressions directly executable
seonghobae 1e59d4f
fix(restack): restore complete orchestrator source blob
seonghobae 98aed1a
test(bootstrap): reproduce durable selection-order loss
seonghobae 457ebb3
fix(bootstrap): preserve durable selector order
seonghobae d469085
refactor(bootstrap): remove superseded unordered ID seed
seonghobae eeb9cc1
test(routing): reject ambiguous bootstrap admission
seonghobae 575148b
fix(routing): fail closed on ambiguous bootstrap admission
seonghobae 50b0c86
test(routing): cover equal-price admission boundary
seonghobae 7206c5f
fix(routing): reject unmodeled diversity displacement
seonghobae 838cbcb
test(routing): reject unmodeled full-pool ordering
seonghobae 726911c
docs(gaps): record 2026-09-08 diversity displacement + full-pool orde…
seonghobae d9c2f57
docs(provider-bootstrap): note provider-spread migration for model-gr…
seonghobae 2f02876
fix(discovery): scope OpenRouter ZDR evidence to its provider
seonghobae File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
105 changes: 105 additions & 0 deletions
105
.github/workflows/source-fix-971-live-review-quality.yml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,105 @@ | ||
| name: PR 971 live review quality repair | ||
|
|
||
| on: | ||
| push: | ||
| branches: | ||
| - fix/model-group-timeout-openrouter | ||
| paths: | ||
| - .github/workflows/source-fix-971-live-review-quality.yml | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: write | ||
|
|
||
| concurrency: | ||
| group: pr-971-live-review-quality-repair | ||
| cancel-in-progress: false | ||
|
|
||
| jobs: | ||
| repair: | ||
| name: RED to GREEN owner repair | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout exact writer head | ||
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # actions/checkout@v7 | ||
| with: | ||
| fetch-depth: 0 | ||
| persist-credentials: true | ||
|
|
||
| - name: Set up Python | ||
| uses: actions/setup-python@ece7cb06caefa5fff74198d8649806c4678c61a1 # actions/setup-python@v6 | ||
| with: | ||
| python-version: "3.12" | ||
|
|
||
| - name: Set up uv | ||
| uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1 | ||
| with: | ||
| version: "0.12.5" | ||
|
|
||
| - name: Guard exact writer head | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| remote_head="$(git ls-remote origin "refs/heads/${GITHUB_REF_NAME}" | cut -f1)" | ||
| test "$remote_head" = "$GITHUB_SHA" | ||
|
|
||
| - name: Verify four causal RED regressions | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| nodes=( | ||
| "tests/test_pr971_review_quality_regressions.py::test_recovered_zdr_batch_reenters_request_privacy_scope" | ||
| "tests/test_pr971_review_quality_regressions.py::test_provider_embedding_batch_rejects_mixed_privacy_identity" | ||
| "tests/test_pr971_review_quality_regressions.py::test_terminal_embedding_batch_document_fails_over_before_marking_health" | ||
| "tests/test_pr971_review_quality_regressions.py::test_discover_all_models_bounds_every_shared_metadata_fetch" | ||
| ) | ||
| for node in "${nodes[@]}"; do | ||
| set +e | ||
| uv run --locked --extra api --extra db --extra queue --group dev python -m pytest -q "$node" | ||
| rc=$? | ||
| set -e | ||
| if [ "$rc" -ne 1 ]; then | ||
| echo "Expected pytest RED exit 1 for ${node}, got ${rc}" >&2 | ||
| exit 1 | ||
| fi | ||
| done | ||
|
|
||
| - name: Apply causal owner repairs | ||
| run: python scripts/ci/pr971_live_review_quality_repair.py | ||
|
devin-ai-integration[bot] marked this conversation as resolved.
Outdated
|
||
|
|
||
| - name: Verify focused GREEN | ||
| run: >- | ||
| uv run --locked --extra api --extra db --extra queue --group dev | ||
| python -m pytest -q | ||
| tests/test_pr971_review_quality_regressions.py | ||
| tests/test_provider_embedding_batch_backend.py | ||
| tests/test_embeddings_model_pool_http_honesty.py | ||
| tests/test_model_discovery.py | ||
|
|
||
| - name: Verify broader GREEN | ||
| run: | | ||
| set -euo pipefail | ||
| uv run --locked --extra api --extra db --extra queue --group dev python -m pytest -q | ||
| python -m compileall -q contextual_orchestrator tests/test_pr971_review_quality_regressions.py | ||
| git diff --check | ||
|
|
||
| - name: Remove temporary repair machinery and publish | ||
| shell: bash | ||
| run: | | ||
| set -euo pipefail | ||
| remote_head="$(git ls-remote origin "refs/heads/${GITHUB_REF_NAME}" | cut -f1)" | ||
| test "$remote_head" = "$GITHUB_SHA" | ||
| rm .github/workflows/source-fix-971-live-review-quality.yml | ||
| rm scripts/ci/pr971_live_review_quality_repair.py | ||
| if find .github/workflows -maxdepth 1 -type f -name '*source-fix-971*' -print -quit | grep -q .; then | ||
| echo "A source-fix-971 workflow would remain in the publishable tree" >&2 | ||
| exit 1 | ||
| fi | ||
| git diff --check | ||
| git config user.name "github-actions[bot]" | ||
| git config user.email "41898282+github-actions[bot]@users.noreply.github.com" | ||
| git add -A | ||
| git commit -m "fix(review): enforce embedding privacy health and discovery bounds" | ||
| remote_head="$(git ls-remote origin "refs/heads/${GITHUB_REF_NAME}" | cut -f1)" | ||
| test "$remote_head" = "$GITHUB_SHA" | ||
| git push origin "HEAD:${GITHUB_REF_NAME}" | ||
|
coderabbitai[bot] marked this conversation as resolved.
Outdated
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| Stopped treating OpenRouter as a whole-account, ZDR-motivated serving exclusion. `PROVIDER_MODEL_SOURCES`'s `openrouter` entry no longer sets `evidence_only=True`: ZDR eligibility is a route/model-level property, never grounds to block an entire provider account from serving, and OpenRouter was the one provider source with genuinely reliable native pricing/`is_free` evidence, so excluding it directly caused `orchestrator/free`'s previously-documented structural emptiness (ADR 0041). Also fixed a backwards side effect of the old flag: `_apply_discovered_model_evidence` could never mark OpenRouter's own rows `zdr_capable=True` even when they exactly matched OpenRouter's own declared ZDR feed. The provider-neutral evidence-application contract from PR #901 (OpenRouter's feed also crediting matching rows from every other provider) is unchanged. Since OpenRouter can multiplex one model id across several backing providers, `ModelClient` now pins every OpenRouter request made under an active `zdr_only` scope with OpenRouter's own documented `"provider": {"zdr": true}` request-time enforcement, applied at the shared `_send`/`_stream_send`/`_send_raw` transport chokepoints, and at the async Batch API path (`_batch_run`) via the same helper on each uploaded JSONL request body. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔍 Hourly runs can queue indefinitely
The removed job deadline lets one hung readiness or maintenance run block every later hourly run because concurrency never cancels the incumbent.
Was this helpful? React with 👍 or 👎 to provide feedback.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Confirmed this is a real gap, and traced its history: on
maintoday theloopjob still carries an explicittimeout-minutes: 55(present since the job was introduced in #834, well before this PR). This branch (fix/model-group-timeout-openrouter) removed that job-level bound and replaced it with narrow per-step timeouts on the deterministic setup steps only, deliberately leaving the gateway-start and hourly-loop-agent steps unbounded — so on this PR's current head there is indeed no job-level bound left at all, which is exactly what this thread is flagging.One correction for the record: this line is not a file that predates and sits outside this PR's diff —
.github/workflows/opencode-hourly-loop.yml(including this exacttimeout-minutesline) is part of #971's own diff, not a routinemain-merge artifact.I'm fixing this independently on
mainrather than adding another commit to this already-large, not-merge-ready branch: #1027 restores a job-leveltimeout-minutes: 300(5h) onloop— generous headroom above the ~2h+-per-model floor this repo's inference steps need, while staying well under the platform's implicit 360-minute cap socancel-in-progress: falsecan no longer let one wedged run block multiple hourly triggers. That also fixes a pre-existing, independent problem:main's current 55-minute cap is already tighter than the "2+ hours per model" floor, so legitimate long runs were already at risk of being killed by their own timeout.This thread's underlying condition still exists on this branch's current head (no job-level bound), so I'm leaving it unresolved here rather than closing it out — whoever finishes #971 should reconcile its per-step timeout structure against #1027 (likely: keep the per-step timeouts on setup steps, and restore/keep a generous job-level bound like #1027's rather than dropping it).
Generated by Claude Code
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fresh owner-boundary correction: do not resolve this by importing #1027's
timeout-minutes: 300into this canonical lane. GitHub's current workflow syntax documents 360 minutes as the defaultjobs.<job_id>.timeout-minutes, and GitHub-hosted runners have a platform 6-hour job-execution limit. The platform ceiling is real, but CWL's current model contract is also explicit: application/Agent/Gateway model timeout defaults tonull, and elapsed time alone must not terminate reasoning/streaming/tool calls. A caller-owned 300-minute job timeout would therefore create an earlier inference deadline rather than repair the queue/hang architecture.Keep this thread open until a deterministic RED proves both sides at the production boundary: (a) no model-backed Actions client can terminate the inference solely at 300m/other leaf-authored elapsed-time threshold; and (b) an externally killed GitHub-hosted job cannot lose or synthesize the exact-head model execution/result. Smallest GREEN is durable/resumable contextual-orchestrator-owned execution (or equivalent exact-identity checkpoint/re-dispatch mechanism) with Actions reduced to bounded dispatch/observe/reconcile; setup/cleanup/network-health bounds may remain distinct from inference termination. Preserve explicit taxonomy for user cancel, provider termination, audited admin timeout, and infrastructure loss.
Also integrate the still-valid
orchestrator/freeworkflow delta from #1006@c7ca8a06901bc65b7376fbe7a4852267d134cf96/ #1013@0a800f87c6df8bb310e1a09859f44d5451fcc969; protectedmain@464da4715b495b5eaaa593eba3796e2d976ee0c9still usesorchestrator/auto. Do not retire either predecessor until one verified successor carries the complete free-pool contract/tests/docs delta.Current live #971 head has already advanced to
41aaeff951fd5bc49b6e17386944a9b562843e8aand has no materialized exact-head PR workflow runs yet, so predecessor checks/reviews remain non-transferable.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Follow-up: the review discussion on this same file/finding (echoed on both this PR and #1027) surfaced a correction I want to record here too. My first pass on #1027 proposed a
timeout-minutes: 300job-level cap — that was wrong: any finite job-level timeout covering the gateway-start/inference steps is exactly the elapsed-time model cutoff this org's policy forbids (see AGENTS.md/CLAUDE.md — model timeout defaults to unlimited/null; only user cancellation, provider termination, or an explicit audited admin timeout may end a call). Raising the number doesn't fix that, it just moves the violation further out.The corrected fix (now landed on #1027, #1027) removes the job-level timeout entirely rather than replacing it — which means this PR's branch (
fix/model-group-timeout-openrouter) already has the architecturally correct shape here: no job-level cutoff onloop, only narrow per-step timeouts on the deterministic setup steps, gateway-start/inference left genuinely unbounded. #971 and #1027 have converged on the same design independently.What's still genuinely unaddressed by either PR, and out of scope for both: the underlying concurrency problem this finding named (
cancel-in-progress: falsemeans a truly-hung run still occupies the group until GitHub's implicit 360-minute hard ceiling kicks in, and any run superseded during that window doesn't execute). Fixing that for real needs a durable/resumable execution boundary (checkpoint/re-dispatch that preserves exact-head identity and doesn't synthesize a result across the platform's forced termination) — a separate, larger piece of work, not a workflow-file tweak. Leaving this open as a tracked gap rather than resolving it, since the concurrency behavior itself isn't fixed yet.Generated by Claude Code