fix(proxy): recover goal restarts from unavailable owners - #1679
fix(proxy): recover goal restarts from unavailable owners#1679leventov wants to merge 8 commits into
Conversation
2412c6d to
a8e8199
Compare
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: cd554303b9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@codex review |
|
Codex Review: Didn't find any major issues. You're on a roll. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Gate check: codex is clean on 65103b4 and CI Required is green, but #1696 (merged after your last CI run) added migration |
|
Correction to the re-parent target: #1657 just merged, so main's Alembic head is now |
65103b4 to
736dd4c
Compare
|
Rebased onto current |
|
To use Codex here, create a Codex account and connect to github. |
|
Re-parent target update (second correction, sorry for the churn): #1618 just merged and its migration sits on the previous head, so main's Alembic head is now |
Permit an explicit, account-neutral Codex goal restart to retire an unchanged legacy owner only while its persisted account status is unavailable. Preserve fail-closed routing for all other continuity evidence and guard retirement with one compare-and-set tombstone.
736dd4c to
431492f
Compare
|
Addressed in |
|
Follow-up on the failed unit shard: fixed in |
Summary
A Codex conversation restart can resend a self-contained thread under the same process-session identifier after its legacy owner exhausts quota. Raw legacy
codex_sessionrows are intentionally hard, so ordinary requests must fail closed; before this change, that same row also trapped an explicit, self-contained goal restart on an unavailable account.This PR adds one proof-gated direct-routing exception. A request may retire an unavailable raw legacy owner only when it carries Codex's recognized goal-continuation marker and its canonical upstream Responses payload is account-neutral and self-contained. Retirement is compare-and-set, policy-scoped, and request-owned. Ordinary, incremental, file-pinned, conversation-bound, and unresolved-tool requests remain fail-closed.
HTTP bridge reuse/replacement is deliberately split into the dependent #1680. No public wire format, setting, or default timeout changes. One nullable sticky-session column records source-qualified abandonment without backfilling historical rows.
Linked issue: none exists for this incident-derived defect; routed regression coverage exercises the public Codex Responses and direct WebSocket paths.
Behavior and safety
PAUSED,RATE_LIMITED, orQUOTA_EXCEEDED.OpenSpec
openspec/changes/archive/2026-08-10-recover-restarted-conversation-affinity/.openspec/specs/sticky-session-operations/.Origin and concurrent work
Landed lineage:
b1d27bc6) introduced bounded stale hard-owner cleanup while keeping hot-path requests hard. This PR preserves that default and adds only a proof-gated explicit-restart path.201281b5) established the canonical account-neutral fresh-resend classifier. This PR reuses that boundary rather than defining another movable payload heuristic.68397054) enforced ownership ofprevious_response_id; requests with that anchor remain immovable here.f2f8f916) and fix(proxy): recover dead durable bridge anchors fast #1625 (85f1ee4b) expanded bridge recovery and dead-owner handling. Their bridge lifecycle concerns are handled separately by fix(http-bridge): preserve goal-restart recovery across reconnects #1680, not hidden in this object.7a0b6719) and fix(http-bridge): keep idle retirements out of retry circuit #1677 (7c467198) landed before this rebase. Their durable-operation and retry-circuit behavior is retained by the parent tree and exercised further in fix(http-bridge): preserve goal-restart recovery across reconnects #1680.Concurrent work reviewed for overlap:
Review findings addressed
Concrete review findings incorporated in this object:
The cloud Codex review was clean at
65103b40. Current-head review was requested after the rebase, but the fork connector rejected it with an account-linking error; there are no unresolved non-outdated review threads.Current-main rebase
Rebased on current
mainat7c467198(#1677), which already includes #1657 and its Alembic merge head. The additive migration is renamed to20260812_120000_add_sticky_abandonment_scopeand now follows20260812_000000_merge_recovery_dispatch_and_hourly_cancelled_heads, preserving a single-head graph.Validation
The first current-head cloud run passed unit, core integration, PostgreSQL, migration, Ruff, type, packaging, Docker, and browser jobs. Its bridge shard had one isolated
bridge_instance_mismatchintest_v1_responses_http_bridge_classifies_responses_lite_developer_interleaved_full_resend[unowned-developer-message]; that exact test passes locally on736dd4cd, and the same bridge suite is green on the stacked #1680 head. The fork author cannot use GitHub's failed-job rerun action without upstream repository administration.Screenshots / output
No dashboard-visible change.
Before:
After:
Simplicity
Checklist
CHANGELOG.mdwas not edited.