fix(core): five sweep lows — seal-lane fallback, flush partial, codec echo, idle clamp, pair-name UTF-8
From the 2026-07-20 punktfunk-core quality sweep's adjudicated lows (~/punktfunk-sweeps/punktfunk-core-2026-07-20.json), each with a regression test: - session: the two-lane seal's dead-worker fallback dropped the frame's back half and returned Ok with half an access unit; the corpse lane was also never respawned. The send-failure arm now reclaims the tail (single-lane seals the WHOLE frame) and both failure arms drop the lane so the next large frame respawns it. A recv-side death now surfaces as an error instead of silent truncation. - reassemble: Reassembler::reset() left pending_partial parked, so a pre-flush stale partial survived Session::flush_backlog and was delivered as the first "frame" after a jump-to-live. - caps: resolve_codec echoed a non-conformant multi-bit preferred byte verbatim (downstream from_wire folds it to HEVC — possibly outside the shared set). It now isolates one bit of the intersection. - endpoint: stream_transport_idle only floored the value; an absurd operator-supplied idle timeout blew past QUIC's VarInt ms ceiling and panicked host startup through the expect. Clamped to 1s..1h. - pairing: PairRequest::encode cut the device name at a raw byte-64 boundary, splitting multi-byte UTF-8 (host showed U+FFFD forever); it now shares Hello's char-boundary truncate_to. The frozen-FEC-ceiling finding (reassemble.rs:109) was already fixed on main by the sweep's high-severity commit — skipped as stale. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -518,6 +518,10 @@ impl Reassembler {
|
||||
// The dropped frames' buffers (and their parity bufs) go back to the allocator, not the
|
||||
// pool — a flush is the rare path. The budget resets with them.
|
||||
self.in_flight_bytes = 0;
|
||||
// An aged-out partial parked for delivery is from the discarded past too — without this
|
||||
// it survives `flush_backlog` and gets handed up as the first "frame" after the
|
||||
// jump-to-live, exactly the stale content the flush existed to discard.
|
||||
self.pending_partial = None;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -645,3 +649,35 @@ impl ReassemblyWindow {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod reset_tests {
|
||||
use super::*;
|
||||
|
||||
/// `flush_backlog` discards the past wholesale — an aged-out partial parked for delivery is
|
||||
/// part of that past and must not survive [`Reassembler::reset`] to be handed up as the
|
||||
/// first "frame" after a jump-to-live.
|
||||
#[test]
|
||||
fn reset_drops_a_parked_partial() {
|
||||
let mut r = Reassembler::new(ReassemblerLimits {
|
||||
shard_bytes: 64,
|
||||
max_data_shards: 8,
|
||||
max_total_shards: 16,
|
||||
max_blocks: 4,
|
||||
max_frame_bytes: 4096,
|
||||
});
|
||||
r.pending_partial = Some(Frame {
|
||||
data: vec![0u8; 64],
|
||||
frame_index: 7,
|
||||
pts_ns: 1,
|
||||
flags: 0,
|
||||
complete: false,
|
||||
received_ns: 0,
|
||||
});
|
||||
r.reset();
|
||||
assert!(
|
||||
r.take_partial().is_none(),
|
||||
"a pre-flush partial must not survive reset()"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user