Skip to content

fix(proxy): recover Codex sessions across bridge lineage changes - #1549

Closed
ret2basic wants to merge 4 commits into
Soju06:mainfrom
ret2basic:fix/quarantine-eventless-durable-anchors
Closed

fix(proxy): recover Codex sessions across bridge lineage changes#1549
ret2basic wants to merge 4 commits into
Soju06:mainfrom
ret2basic:fix/quarantine-eventless-durable-anchors

Conversation

@ret2basic

Copy link
Copy Markdown

Summary

Recover Codex HTTP-bridge sessions after Escape/downstream cancellation, stale connection-local anchors, and upstream encrypted compaction. The fix quarantines dead store=false lineage before socket retirement and admits exact encrypted compaction only on its durable owner account.

Type of change

  • fix: — bug fix (no behavior change beyond the bug)
  • Breaking change

Linked issue: none filed; this covers production Codex session reports ending in ebb7 and the Escape reconnect failure.

OpenSpec

  • This PR includes / updates an OpenSpec change
  • This PR touches a codex-faithful path and preserves upstream-equivalent behavior

Change directory: openspec/changes/recover-codex-desktop-idle-bridge/

The encrypted compaction item is forwarded unchanged. No intentional upstream wire-format divergence is introduced.

Changes

  • Quarantine the exact eligible proxy-injected store=false anchor when downstream Escape cancellation retires the upstream socket, with lifecycle locking through durable quarantine and socket retirement.
  • Recover fresh-socket and quarantined sessions from verified full context while rejecting incremental lineage loss with actionable continuity_requires_full_resend errors.
  • Accept only exact upstream encrypted-compaction items with retained durable proof and a concrete owner; preserve that owner binding across auth, capacity, security-work, prewarm, reconnect, and owner-forward recovery paths.
  • Preserve settlement, account-health, forwarding provenance, and stale-write fencing invariants; add unit and backend-route regressions for cancellation races, malformed compaction, owner pinning, and fresh-socket recovery.

Simplicity

No new setting, environment variable, dependency, migration, README section, dashboard navigation item, required setup step, or default change.

Test plan

# Affected bridge, replay-safety, WebSocket helper, and backend route suites
1656 passed in 54.85s

.venv/bin/ruff check .
# All checks passed

.venv/bin/ruff format --check .
# 849 files already formatted

.venv/bin/ty check
# All checks passed

make architecture-check
# proxy architecture checks passed

openspec validate recover-codex-desktop-idle-bridge --strict
# Change is valid

openspec validate --specs --strict
# 48 passed, 0 failed

Screenshots / output

No dashboard-visible change.

Post-deploy verification:

{"status":"ok"}
{"status":"ok","checks":{"database":"ok"}}

Checklist

  • Title is in Conventional Commits format.
  • Linked issue/discussion — no issue was filed for the production session reports.
  • Added or updated tests covering the change.
  • Ran the relevant local CI subsets for the affected proxy paths.
  • openspec validate --specs --strict passes.
  • Simplicity gates P1-P5 reviewed; no budgeted surface changed.
  • CHANGELOG.md is not edited.

Cloud CI and current-head @codex review remain required before merge. This PR must not be self-merged.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@gitguardian

gitguardian Bot commented Jul 30, 2026

Copy link
Copy Markdown

⚠️ GitGuardian has uncovered 1 secret following the scan of your pull request.

Please consider investigating the findings and remediating the incidents. Failure to do so may lead to compromising the associated services or software components.

Since your pull request originates from a forked repository, GitGuardian is not able to associate the secrets uncovered with secret incidents on your GitGuardian dashboard.
Skipping this check run and merging your pull request will create secret incidents on your GitGuardian dashboard.

🔎 Detected hardcoded secret in your pull request
GitGuardian id GitGuardian status Secret Commit Filename
- - Basic Auth String b3aa134 tests/unit/test_proxy_websocket_client.py View secret
🛠 Guidelines to remediate hardcoded secrets
  1. Understand the implications of revoking this secret by investigating where it is used in your code.
  2. Replace and store your secret safely. Learn here the best practices.
  3. Revoke and rotate this secret.
  4. If possible, rewrite git history. Rewriting git history is not a trivial act. You might completely break other contributing developers' workflow and you risk accidentally deleting legitimate data.

To avoid such incidents in the future consider


🦉 GitGuardian detects secrets in your source code to help developers and security teams secure the modern development process. You are seeing this because you or someone else with access to this repository has authorized GitGuardian to scan your pull request.

@Soju06

Soju06 commented Aug 4, 2026

Copy link
Copy Markdown
Owner

This was a serious piece of work, but the ground moved under it. The design.md positions this as the no-schema alternative to #1394 ("does not import PR #1394's retry-circuit, replay policy, new schema, or migration surface") — and #1394 has now merged (a66f793, 08-04). Main resolves the same anchor re-injection loop via durable recovery-attempt claims + retry circuits + durable full-resend recovery (app/modules/proxy/_service/http_bridge/streaming.py durable_full_resend_* paths, retry_circuit.py), so decisions 6/9/10/11/12 here (quarantine CAS, fresh-socket lineage boundary, send-boundary revalidation) are superseded by a different architecture. #1562's capability lineage also rewrote websocket/mixin.py and support.py under this diff. A rebase would be a rewrite, so closing in favor of #1394 seems right.

Two things worth carrying forward:

  1. The encrypted-compaction same-account recovery slice is NOT covered on main: git grep account_bound_owner_id on main is empty, and app/modules/proxy/replay_safety.py:836 still rejects any item with encrypted_content as non-account-neutral, so those sessions fail closed today. responses_payload_is_same_account_compaction_recovery + owner pinning through reconnect/auth/capacity would make a good small standalone PR against post-fix(http-bridge): stabilize silent and clean-close recovery #1394 main.

  2. If you re-file the egress-failure correlator (decision 13), please rethink it first: _correlate_no_close_receive_error waits up to 1s on every ambiguous Responses receive failure (including the generic except Exception path); correlation needs >=2 distinct account ids, so single-account deployments pay the delay with zero possible benefit; and on the shared direct:wss://chatgpt.com:443 key a genuine upstream outage correlates across accounts and gets classified proxy_network_unavailable, masking upstream incidents and triggering shared-transport rotation. It also overlaps fix(proxy): fail over dead account proxy routes before upstream dispatch #1542's dead-account route failover classification — coordinate there.

Minor: GitGuardian flags a hardcoded basic-auth string in tests/unit/test_proxy_websocket_client.py (b3aa134, ~L374) — use an obviously-dummy placeholder in any re-file.

@Komzpa Komzpa added the needs rebase Needs rebase or conflict repair against current main label Aug 4, 2026
@Soju06

Soju06 commented Aug 4, 2026

Copy link
Copy Markdown
Owner

Closing per maintainer decision: the owner merged #1394 on 08-04, which settles the design competition this PR was built as an alternative to (see analysis above). The encrypted-compaction same-account recovery slice is genuinely uncovered on main and would be welcome as a small standalone PR on the post-#1394 base.

@Soju06 Soju06 closed this Aug 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs rebase Needs rebase or conflict repair against current main

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants