fix(tui): recover poisoned TLS client generations - #694
Closed
yxlyx wants to merge 2 commits into
Closed
Conversation
A request-construction TLS failure occurs before the existing connection poison can run, so retries and later TUI trajectories kept reusing a launch-scoped client that only process replacement could heal. Route model HTTP calls through leased generations, rotate on construction failure without deinitializing in-flight users, and preserve the original client for unrelated launch consumers. Gate every managed constructor on CA readiness, distinguish CA warm and request-construction failures in traces, and cover concurrent stale reports plus later ordinary and child POST recovery with a loopback regression. Co-Authored-By: Codegraff <blackfloofie@codegraff.com>
Close model-client admission before teardown, drain active generation leases and CA-ready waiters, and serialize global lookup with destruction. This prevents ReleaseFast use-after-free races while allowing unrelated HTTP clients to remain usable.\n\nCorrect retry accounting so the advertised limit is the actual total, preserve throttle/server failure attribution, and add deterministic real-TLS, concurrent, allocation, TUI-root, foreground-child, and background-child recovery coverage. Remove the unrequested ADR and raise the test-count ratchet to the verified suite size.\n\nCo-Authored-By: Codegraff <blackfloofie@codegraff.com>
Owner
|
Folded into release/v0.0.282 (#696), including the TLS-lifecycle follow-up. Closing as superseded. ADR is 0048. |
cursor Bot
pushed a commit
that referenced
this pull request
Aug 31, 2026
…ycle yxlyx: drain generation leases on teardown, fix retry accounting, add real-TLS / child coverage. Keep ADR 0048 (the first #694 commit's record, remapped off the TUI-claims 0042 slot). # Conflicts: # docs/adr/0048-model-http-client-recovery-uses-generations.md # docs/adr/README.md # scripts/eval/tier1-manifest.json
cursor Bot
pushed a commit
that referenced
this pull request
Aug 31, 2026
The follow-up dropped the TLS-generation record; 0042 is TUI claims and 0048 stays the leased-client decision. Floor stays 1817.
cursor Bot
pushed a commit
that referenced
this pull request
Aug 31, 2026
Complementary to #694 model-HTTP generations: MCP HTTP/WSS keep the warmed client and accept gzip catalogs. ADR remapped off 0043. # Conflicts: # docs/adr/README.md # src/http_warm.zig # src/test_hooks.zig
cursor Bot
pushed a commit
that referenced
this pull request
Aug 31, 2026
Record the ADR remaps (0049 / 0050) and the extra #694 lifecycle hardening. Still no tag.
justrach
added a commit
that referenced
this pull request
Aug 31, 2026
…recovery The malformed-handshake test asserts error.TlsRequestConstructionFailed from both production constructor catches, and green on Linux/macOS. On Windows CI the handshake read dies with NTSTATUS LOCAL_DISCONNECT, which std surfaces as error.Unexpected — raw, bypassing the recovery rotation the test (and #694's contract) demands. constructionTlsFailure() is the shared predicate: TlsInitializationFailed always, plus error.Unexpected when the request is https (a plain-HTTP connect error must not be mislabeled a TLS failure). Both catches — http.post and the streaming path — consult it. Co-Authored-By: Codegraff <blackfloofie@codegraff.com>
yermakoffivan
pushed a commit
to yermakoffivan/codegraff
that referenced
this pull request
Aug 31, 2026
… generations yxlyx: lease/rotate the shared std.http.Client on TlsInitializationFailed at request construction. ADR number will be remapped off 0042. # Conflicts: # docs/adr/README.md
yermakoffivan
pushed a commit
to yermakoffivan/codegraff
that referenced
this pull request
Aug 31, 2026
…justrach#694 Record the three product merges on the new release branch, remap the TLS-generation ADR to 0048 so 0042 stays TUI claims, and leave justrach#277 / justrach#200 parked.
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Closes #691.
What changed
http.postWatchedcalls and streamingAgent.postStreamWithClientcalls lease the active client generation.std.http.Client.requestreturnsTlsInitializationFailedbefore aRequestexists, retire that generation and publish a CA-prewarmed replacement. Concurrent callers keep the retired generation alive until their final lease releases; stale reports do not rotate twice.std.http.Clientinstances remain usable.postWatchedusers such as server compaction, and added distinct breadcrumbs for launch CA failure, replacement CA failure, TLS rotation, and final retry exhaustion.runSub, and backgroundexecSubagent/agentOutput.Why
A transient network transition can poison the launch-owned
std.http.Clientat request construction, before the existing post-construction connection cleanup has aRequestto mark closing. Retrying the same client therefore leaves every later model-backed TUI trajectory failing until the process is replaced.Generation leasing fixes that lifecycle boundary rather than masking individual failures. One poisoned client can be retired immediately while in-flight compaction, root, or child calls safely finish on the object they already leased, and later retries resolve the original launch pointer to the replacement.
The design intentionally applies to model request constructors rather than every best-effort launch HTTP consumer. The original launch client is never deinitialized by rotation because telemetry/fleet callers may still hold its pointer. The cost is one mutex-protected lookup per model request plus temporary retention of retired generations while calls remain in flight.
Reinitializing the shared client in place was rejected because concurrent users can still dereference it. Creating a fresh client for every request was rejected because it discards connection pooling and repeatedly reloads CA state. Relying on debug assertions or external job-join ordering was rejected because ReleaseFast teardown still needs an in-process lifetime guarantee.
Verification
scripts/eval-tier1.sh— green with the test-count ratchet updated to the verified suite size.zig build -Doptimize=ReleaseFast— green.git diff --check— clean.