Skip to content

Q3 iter-4 — drop replay #9, CDS stops rejecting and goes quiescent

Status: verified — completed 2026-04-19

iter-4 tested hypothesis 1 from iter-03/findings.md by dropping replay #9 RST_STREAM(s1, STREAM_CLOSED) from the DATA(s3) composite trigger. Outcome: CDS no longer emits its own RST_STREAM(s3, STREAM_CLOSED), no GOAWAY, no teardown of any kind. Connection enters a quiescent state — CDS has nothing more to send and is waiting for server-initiated next steps that a pure replay cannot provide. Forward progress is qualitative: the error signal is gone. Full writeup: findings.md.

This closes Q3 under the replay approach. Any further s2c progress goes through Phase D backend implementation, not more iphone_replay_bytes.py iterations.

What iter-4 does

One-line change vs iter-3: the DATA(s3) trigger emits [7, 8] instead of [7, 8, 9].

Rationale: iter-3 proved the CDS RST_STREAM(s3, STREAM_CLOSED) was not caused by frame ordering. The next cheapest hypothesis was that our own emission of #9 (server-initiated reset on s1 with STREAM_CLOSED) looked to CDS like "server bailed out before the client acknowledged" and CDS reciprocated on s3. iter-4 falsifies or confirms that by simply skipping #9.

Files

Result vs iter-3

Aspect iter-3 iter-4
Server bytes emitted 14326 (10 frames) 14313 (9 frames, #9 skipped)
CDS recv bytes 217 (9 frames) 204 (8 frames, RST_STREAM gone)
CDS teardown RST_STREAM(s3, STREAM_CLOSED) none — no teardown at all
CDS GOAWAY none none
Session end reason CDS reset pkill on listener (CDS silent)

What hypothesis 1 now tells us

Confirmed: our #9 was the direct cause of iter-3's RST_STREAM(s3). CDS was reciprocating our server-initiated reset on s1 by closing s3.

Not confirmed (still open, now hard to test under replay): whether the zeroed identifiers in #8 Handshake dict matter. With CDS gone silent, we cannot distinguish "accepted but idle" from "silently rejected with long deadline". Investigating requires either restoring plausible identifiers (iter-5 under continued replay) or switching to an interactive backend that can respond to CDS's post-handshake service calls.

The findings document recommends not continuing iter-5 under replay: the ceiling of "what a pre-recorded stream can do" has been reached. The next productive step is implementing Phase D backend, which has the ability to respond dynamically to whatever CDS asks after handshake.