Skip to content

Phase 3a: I/O Contracts #11

Description

@Wahbeh-Mohammad

Build the byte-streaming layer every body, every logging snapshot, every codec and the whole of SSE and
pagination later stand on: one FIFO buffer, one buffered source/sink pair with typed reads and non-consuming
views, and one tee sink that mirrors a bounded tap without ever altering the wire body. The behavioural
contract is the whole deliverable — design §10.1 retired the seam that made it pluggable, so there is no
factory, no registry and no installation call.

Scope

  • Dexpace::IO's FIFO buffer (IO-7–IO-10, with MAX_MATERIALIZED_BYTES as §10.18's substituted
    constant), BufferedSource/BufferedSink with typed reads, exact-count reads (IO-12), explicit-charset
    reads (IO-13), peek and slice views (IO-19/IO-20), and the close latch (IO-41/IO-42).
  • IO-1's read primitive is #read_into, not #read — IO.copy_stream hands #readpartial one buffer
    it reuses across calls, so a tail-append under Ruby's name would corrupt every streamed upload; #read,
    #readpartial, #getbyte and #each keep Ruby's semantics, which is what makes IO-16 true by
    construction.
  • Dexpace::EndOfStreamError < ::EOFError, load-bearing: IO.copy_stream terminates only on an EOFError
    subclass from a duck-typed #readpartial.
  • The TeeSink (IO-25–IO-29) that 3b's request-logging tee restates one layer up.
  • IO-6's ownership-on-wrap rule stated once, without SEAM-3 (R3); the Dexpace::IO shadowing gate (R1) —
    inside module Dexpace, x.is_a?(IO) is silently false for a real ::IO.
  • Every chunk is Encoding::BINARY; resource acquisition and release never live inside an Enumerator block
    (design §7.1).

Spec refs

Product spec §5 — IO-1–IO-42 (42 IDs); IO-6 read out of appendix C, IO-32–IO-35 out of ch.05 as the
retired provider apparatus. sdk-design: §3.1, §10.1, §10.12, §10.18.

Dependencies

Phases 0–2. Leads 3b, which consumes the FIFO buffer, the tee sink, the peek/slice views and the close latch
by name — nothing in 3a needs anything from 3b.

Docs

  • Segmentation: docs/work/mvp/phase3/2026-09-08-phase3-segmentation-design.md
  • Design: docs/work/mvp/phase3/phase3a/2026-09-08-phase3a-io-contracts-design.md
  • Plan: docs/work/mvp/phase3/phase3a/2026-09-08-phase3a-io-contracts.md (15 tasks)
  • Checklist: docs/work/mvp/phase3/phase3a/<date>-phase3a-io-contracts-checklist.md — written at execution
    time, one row per ID in scope

Notes

3a adds nothing to the require allowlist and requires nothing at all. The #read_line_utf8 line-cap finding
this sub-phase opens is resolved by phase 7b (its Tasks 6 and 12), not here.

Activity

  1. added this to the v1/mvp milestone on Sep 13, 2026
  2. added
    type:featureNew capability or enhancement
    area:coreCore HTTP, IO, body, context, encoding: HTTP-* IO-* BODY-* CTX-* UTF-*
    on Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

area:coreCore HTTP, IO, body, context, encoding: HTTP-* IO-* BODY-* CTX-* UTF-*type:featureNew capability or enhancement

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions