Skip to content

release/v0.0.201 — http send-failed poison (#177) + ultracode codeword sticky (#178) - #180

Merged
justrach merged 8 commits into
mainfrom
release/v0.0.201
Jul 12, 2026
Merged

justrach merged 8 commits into
mainfrom
release/v0.0.201

Conversation

@justrach

Copy link
Copy Markdown
Owner

Consolidated release. Two committed fixes plus test hardening and a login-page polish, adversarially reviewed before this PR (6 review lanes + refute pass; 0 confirmed defects).

Fixes

Tests

Polish

  • graff login codex callback now lands on a branded, dark-mode-aware confirmation card instead of a bare line of text.

Changelog bumped to 0.0.201. Merging this closes #177 and #178; tag v0.0.201 on the merge commit triggers release.yml.

justrach and others added 8 commits July 12, 2026 11:41
…orm the session (#177)

post() was built on client.fetch, which never exposes the Request: a
request whose body SEND failed left reader.state == .ready, Request.deinit
read that as "connection still clean", and the DEAD connection went back
into the shared keep-alive pool. findConnection hands the free list out
LIFO, so every retry — and every later same-host request — pulled the same
corpse: the observed storm where a ~230k-token compaction request failed
6/6 and then, after /clear, a tiny [title] request failed 6/6 in the same
process while live WS/SSE turns kept working (they bypass the pool).

The streaming path has poisoned exactly this failure for a while
(agent_stream.zig's errdefer conn.closing = true, "WriteFailed forever
after (observed in the wild)"), and RetryPlan's doc comment even claimed
postWatched had the same protection — it never did.

- post(): client.request + sendHeadTask (same wire behavior as fetch for
  our POSTs) with the errdefer poison on every error path, plus an
  explicit poison on the 429/5xx early-returns that leave body bytes
  unread on the connection.
- RetryPlan doc: describe the protection that now actually exists.
- Regression test on a real loopback listener: conn 1 is closed unread so
  an 8MB send fails mid-write; the follow-up tiny POST must dial fresh and
  reach conn 2's 200 (it re-failed on the pooled corpse before the fix).
  Red-checked: 165/166 with the poison disabled, 166/166 with it.

Fixes #177

Co-Authored-By: blackfloofie <265516171+blackfloofie@users.noreply.github.com>
…ets goal/ultracode steering (#178)

The explicit "ultracode" scan ran over the fully ASSEMBLED turn message —
base prompt plus the goal/todos/eval harness notes — so any standing goal
containing the word kept re-triggering the explicit banner and workflow
steering on every turn. And /clear kept root.goal and root.ultracode_mode
(only /new reset them — an artifact of /new landing later, not a design
choice), so even "context cleared — fresh conversation" didn't stop it:
the observed session bannered ULTRACODE on a plain prompt right after
/clear, every time.

- applyUltracodeSteering takes the raw typed text alongside the assembled
  msg and scans ONLY the raw text for the codeword; the note still lands
  on the assembled msg. The oneshot path (session_run) already scanned the
  raw prompt; the REPL mainloop now matches it.
- /clear resets the same conversation steering as /new (goal +
  ultracode_mode) via a shared helper, and says so when a standing goal is
  dropped.
- Regression tests: codeword arriving via an appended harness note is not
  explicit; typed codeword still is (case-insensitive); persistent mode
  still notes without bannering; the /clear//new reset helper.

Fixes #178

Co-Authored-By: blackfloofie <265516171+blackfloofie@users.noreply.github.com>
http: poison send-failed connections so one WriteFailed can't storm the session (#177)
ultracode: scan the codeword on the raw prompt only + /clear resets goal/ultracode steering (#178)
Co-Authored-By: blackfloofie <265516171+blackfloofie@users.noreply.github.com>
…t can't hang the binary

The regression test's first assertion (expectError WriteFailed) had no
safety net: if the 8MB send ever failed with something other than
WriteFailed, the test returned before the second post() ran, leaving the
server task parked in its second accept() and hanging the deferred
fut.await. The trigger is unreachable today (Io.Writer collapses every
send error to WriteFailed; the loopback RST lands on the first bytes),
but the guard mirrors the second post()'s existing throwaway-dial release
so the test can never hang regardless. Surfaced by the pre-PR adversarial
review; test-only, no production change.

Co-Authored-By: blackfloofie <265516171+blackfloofie@users.noreply.github.com>
Adds a loopback test for post()'s 429/5xx branch — previously the whole
branch was uncovered; only the send-failed path had a test. conn 1 answers a
keep-alive 500 with an oversized (>600B capture buffer) body; post() must
partial-drain it, return error.ServerError, and the session must recover on
the next request (fresh dial to conn 2's 200).

Honest scope note (verified by disabling the poison): unlike the send-failed
case, std does NOT re-pool a partially-read response connection on its own, so
post()'s explicit 5xx poison is defensive/redundant — this test exercises the
5xx path end-to-end, it does not isolate that poison. The load-bearing #177
regression (a failed SEND leaves the reader deceptively .ready, so std DOES
re-pool the corpse) remains covered by the send-failed test, which provably
goes red when the poison is removed. Surfaced by the pre-PR adversarial review.

Co-Authored-By: blackfloofie <265516171+blackfloofie@users.noreply.github.com>
The graff login codex PKCE callback (localhost:1455) served a single bare
line of HTML. Replace it with a branded, dark-mode-aware confirmation card
(centered, system font, prefers-color-scheme, charset=utf-8 so the ✓/◆
render) and bump the write buffer to fit it. Same close-tab-and-return
semantics — correct for a CLI login. Folded into v0.0.201.

Co-Authored-By: blackfloofie <265516171+blackfloofie@users.noreply.github.com>
@justrach
justrach merged commit ccb9358 into main Jul 12, 2026
4 of 6 checks passed
@justrach
justrach deleted the release/v0.0.201 branch August 4, 2026 08:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

http: a send-failed request re-pools its dead connection — one WriteFailed poisons every later non-streaming request (compaction, [title], subagents)

1 participant