Skip to content

[HTTP interoperability] Bound stacked Content-Encoding chains without budget bypass #326

Open

Description

@seonghobae

Buyer-visible gap

The current originweave-http first slice intentionally accepts at most one HTTP content coding (identity, gzip, or deflate). That is safe and explicit, but RFC 9110 permits an ordered list of content codings applied to a representation. A governed browser/runtime can therefore reject otherwise valid responses such as a representation encoded through two supported layers.

This is also a negotiation-consistency gap in the current first slice: request serialization advertises Accept-Encoding: gzip, deflate, while response decoding accepts either coding alone but rejects a second Content-Encoding member. This is fail-closed behavior, not an unsafe decoder bypass.

A fresh RFC 9110 review also found a narrower interoperability defect in the proposed repair contract itself: Content-Encoding uses the #content-coding list rule, and §5.6.1.2 requires recipients to parse and ignore a reasonable number of empty list elements. Therefore an implementation that categorically rejects empty comma members would be non-conforming. OriginWeave already bounds individual field values, field count, and the complete header section, so empty-element tolerance can remain linear and byte-bounded without turning an empty-member run into unbounded work.

This is an interoperability gap, not a claim that current #37 is protocol-unsafe. Keep #37/#9 bounded and mergeable; implement this only after the canonical HTTP authority is stable in its parent lineage or through an ordinary-forward successor that preserves every current test/evidence contract.

Standards / semantics authority

RFC 9110 defines Content-Encoding as #content-coding and states that codings are listed in the order in which they were applied. Decoding therefore proceeds in reverse application order. Repeated field lines with the same field name are combined in received order; the accepted coding chain must therefore preserve both field-line encounter order and comma-member order.

RFC 9110 §5.6.1.1 says senders MUST NOT generate empty list elements, but §5.6.1.2 separately says recipients MUST parse and ignore a reasonable number of empty list elements. Empty elements do not contribute to list cardinality. For this bounded client, non-empty content-coding count is therefore the depth authority; empty elements are ignored only within the already enforced header-value/header-section byte budgets and must not create decoder work. An all-empty Content-Encoding list has zero non-empty codings and is treated as no content coding, rather than as an unsupported coding token.

RFC 9110 reserves identity for its special role in Accept-Encoding and says it SHOULD NOT be included in Content-Encoding; a sole explicit identity may remain a compatibility leniency, but identity combined with another non-empty coding is not an admitted stack.

RFC 1952 permits gzip data as a concatenated series of members; that intra-gzip member rule is distinct from HTTP-level stacking. The existing raw RFC 1951 fallback for a single deflate layer is a separately evidenced compatibility path and must not become an unbounded retry mechanism inside a coding chain. RFC 9530 digest semantics remain bound to their current content/representation byte domains; adding coding layers must not silently move integrity verification to post-decoding bytes.

References:

Current RFC Editor metadata lists the RFC 1951/1952 author as P. Deutsch. IETF Datatracker synchronized that metadata on 20 May 2026; the immutable RFC text retains the historical full name “L. Peter Deutsch.” This provenance note prevents a metadata-normalization change from being mistaken for a standards or semantic change.

Ownership / DDD boundary

This remains inside OriginWeave HTTP semantics. It must not move content-decoding policy into Chromium, MCP/driver adapters, contextual-orchestrator, EgressWeave, Wardnet, or a model decision. Browser/domain policy continues to consume typed HTTP evidence; adapters do not mint success.

Model the accepted coding chain as a bounded value rather than an unbounded string list. Evidence must preserve the exact admitted wire-order coding sequence and each layer's actual decoder outcome without retaining response content.

RED → repair acceptance

  1. Start with a realistic regression proving the current exact implementation rejects a standards-valid two-layer response composed only of already-supported codings. Use a real authenticated loopback TLS exchange, not only a unit fixture. The captured request must prove the client actually advertised Accept-Encoding: gzip, deflate before the test attributes buyer impact to negotiation inconsistency.
  2. Use reviewed fixed/default max_content_coding_depth = 2 for this first slice while request serialization remains fixed to Accept-Encoding: gzip, deflate. Do not expose a caller-lowerable depth of 1 under that fixed advertisement. If a lower depth is required later, introduce one bounded accepted-coding/advertisement policy and derive both request advertisement and decoder admission from it, or narrow the request advertisement to one coding. A future increase above 2 is a separate resource/security decision.
  3. Parse the complete repeated-field/combined field-value sequence first, preserving received field-line and member order in a bounded ContentCodingChain. Ignore empty list elements as RFC 9110 §5.6.1.2 requires, within the existing bounded header bytes; count only non-empty codings toward max_content_coding_depth. Reject unknown non-empty codings, mixed identity, and non-empty depth overflow before any decoder runs. Decode admitted layers in reverse application order. Preserve a sole explicit Content-Encoding: identity only as the existing compatibility behavior; an all-empty list is zero codings/no-op.
  4. Enforce decoded-byte and expansion limits cumulatively across the complete chain. Every layer output must be checked against the original transfer-decoded coded-content byte count; a layer transition must not reset the ratio denominator or allow ratio^depth amplification. Use checked or fail-closed arithmetic and fail before observable success.
  5. Preserve gzip multi-member semantics within a single gzip layer. Do not confuse concatenated RFC 1952 members with multiple HTTP content-coding layers.
  6. Preserve the raw RFC 1951 DEFLATE fallback as a bounded compatibility decision for that exact layer only. Size/ratio failures must never trigger fallback, and nested-layer failures must not cause combinatorial retry paths.
  7. Realistic hostile/interoperability cases must cover: valid gzip, deflate and deflate, gzip chains; the equivalent repeated-field-line form in encounter order; RFC 9110 empty-list-element tolerance such as gzip, , deflate, plus an all-empty list; malformed outer and inner layers; truncated members; trailing non-coding bytes; non-empty layer-depth overflow; cumulative expansion attack; zero-length input; and a chain containing an unsupported non-empty coding. Empty elements must not create decoder invocations or count toward depth.
  8. Content-Digest/Repr-Digest semantics must remain code-current. In the current full-200 slice, integrity validation occurs on transfer-decoded, still-content-coded bytes before content decoding; stacked decoding must not silently move that byte-domain boundary or collapse distinct digest semantics into one generic post-decode result.
  9. Evidence must retain the exact admitted wire-order chain of non-empty codings plus each layer's actual decoder outcome (standard or raw-DEFLATE compatibility where applicable). Audit evidence need not preserve ignored empty list syntax; wire-order semantics must never be reconstructed from the final decoder result.
  10. Update ADR/design/doctoring/TRACEABILITY/CHANGELOG and the canonical product-gap baseline owner lane with problem, alternatives, selected limit, rejected alternatives, risk/effect, rollback and exact evidence. Keep ADR Proposed until exact-head repository/security/browser-relevant evidence exists.
  11. Owned production rustdoc, unit/integration/edge-case coverage remain 100%; exact-head CI/SAST/Security/CodeQL and eligible independent review must execute. Queued/skipped/predecessor/status-only evidence is not acceptance.

Performance / resource contract

Measure the buyer path with representative compressed payloads. The implementation should stream layer output through bounded sinks rather than materialize an unbounded intermediate per layer. If the current Vec-based decoder is retained for the first repair, every intermediate remains bounded by the same decoded-content ceiling and the coarse strict-default payload-buffer peak is approximately 80 MiB: original coded body up to 16 MiB + one prior intermediate up to 32 MiB + one new output up to 32 MiB, excluding allocator, decoder and TLS overhead. Record that explicitly; do not call the first Vec-based implementation streaming.

Empty list-element handling must remain linear in already admitted header bytes and must not allocate or invoke a decoder per empty element. The existing per-field value, field-count, and complete-header-section budgets are the outer DoS bounds; if implementation profiling shows a separate list-element cap is required, add it as a named policy with a documented RFC 9110 “reasonable number” rationale rather than silently rejecting every empty element.

Non-goals

  • adding Brotli or Zstandard in the same change;
  • increasing current maximum encoded/decoded size or expansion ratio to make tests pass;
  • changing transfer-coding support;
  • connection pooling/reuse;
  • browser rendering or file persistence;
  • LLM/model adjudication of content safety;
  • copying mutable source from another CWL owner.

Depends on the canonical HTTP authority tracked by #9/#37. Keep this issue open until stacked supported codings have exact-head realistic evidence and normal protected integration.

Activity

  1. seonghobae commented on Sep 22, 2026

    @seonghobae
    ContributorAuthor

    Test-first successor is now materialized as #327 on exact canonical HTTP parent #37 15e7c97dc1102934fa1e3ca8517b86938a808565.

    Exact child head 6f9614513a1d5abce918739e52129dd9c8cfd7c7 adds only one realistic authenticated loopback TLS integration regression: the representation is encoded gzip first and then zlib-wrapped deflate, the wire advertises Content-Encoding: gzip, deflate, and the exchange must recover the original payload by decoding in reverse application order. The current parent select_content_coding rejects the second member, so this test mechanically targets the #326 interoperability gap without changing production semantics, policy limits, dependencies, workflows, or release surfaces.

    Fresh CI run 35795592798 exists for the test-only head, but its Rust contracts 106974026475 and Production coverage 106974026446 are still pre-step queued with no runner/steps. No hosted RED is claimed yet. Keep #37 bounded and unchanged; #327 remains a stacked successor and must ordinary/non-force adopt any future accepted parent movement before production repair acceptance.

  2. seonghobae commented on Sep 22, 2026

    @seonghobae
    ContributorAuthor

    Implementation decision candidate while #327 RED waits for runner admission, derived from the current parent code rather than from a protocol-validity claim:

    • Depth budget: use reviewed maximum/default max_content_coding_depth = 2 for this bounded successor. RFC 9110 permits a list but sets no product resource limit; two layers closes the concrete buyer gap with the smallest auditable expansion of authority. Callers may lower the budget to 1, never raise it above the reviewed maximum. A future depth increase is a separate resource/security decision.
    • Value model: parse the complete field list first into a bounded wire-order ContentCodingChain; missing Content-Encoding remains identity/no transform. Preserve a sole explicit Content-Encoding: identity only as current compatibility behavior: RFC 9110 §8.4 reserves identity for its special role in Accept-Encoding and says it SHOULD NOT be included in Content-Encoding. Reject identity combined with any other member, empty members, unknown codings, and depth overflow before any decoder runs. Repeated gzip/deflate are not rejected merely for repetition because RFC 9110 allows codings to be listed in application order; the depth budget is the controlling product bound.
    • Decode order: iterate the admitted chain in reverse wire order. Raw RFC 1951 compatibility is an outcome of one deflate layer, not a wire coding and not a second candidate branch after a size/ratio failure.
    • Cumulative budget: every layer output is checked against the original transfer-decoded coded-content byte count, not the preceding layer length. Therefore the existing decoded-byte ceiling and expansion ratio cannot reset at a layer boundary or compound as ratio^depth.
    • Evidence: retain the exact wire-order admitted coding list plus each layer's actual decoder outcome (standard vs raw-DEFLATE compatibility). Do not infer wire order later from the final decoder result. RFC 9110 §§8.1 and 8.4 define representation metadata, including Content-Encoding, against the coded form. RFC 9530 §§2-3 keeps Content-Digest/Repr-Digest tied to HTTP content/representation semantics; current OriginWeave validates those integrity fields on the transfer-decoded, still-content-coded bytes before content decoding. Stacked decoding must not silently move that byte-domain boundary.
    • Memory bound for the first repair: if the current Vec-based decoder is retained, enforce the same cumulative 32 MiB decoded ceiling for every intermediate. With the existing 16 MiB encoded ceiling, the current exchange retaining the original coded body plus one prior intermediate plus one new output has a coarse worst-case payload-buffer bound of about 80 MiB (16 + 32 + 32 MiB), excluding allocator/decoder/TLS overhead. Record that explicitly rather than calling the path streaming. A later streaming pipeline can reduce peak memory without changing the chain contract.

    Primary standards authority:

    Rejected for this successor: unbounded RFC-list depth; per-layer ratio reset; ratio^depth allowance; treating gzip members as HTTP coding layers; trying both raw/zlib decoders after a resource-limit error; and changing digest validation to post-decoding bytes.

    This remains Proposed until the exact test-only #327 head executes the realistic RED. No production change should be accepted from this comment alone.

  3. seonghobae commented on Sep 22, 2026

    @seonghobae
    ContributorAuthor

    #327 test-only head advanced ordinary-forward to 64f9e4ebaea15b245d41b27c7092d1a80fc12ff4 before accepting any RED. The only added delta tightens fixture causality: join and propagate the TLS server result, prove the exact GET request reached that authenticated peer, distinguish the expected UnsupportedContentCoding rejection from unrelated setup/network failures, and keep desired success as the test oracle. New native CI is 35796140817, currently nonterminal; predecessor queued evidence does not transfer. Production code remains untouched.

  4. seonghobae commented on Sep 22, 2026

    @seonghobae
    ContributorAuthor

    Fresh parent-source audit on #37 exact 15e7c97dc1102934fa1e3ca8517b86938a808565 narrows the implementation shape before #327 leaves RED:

    • HttpPolicyLimits / HttpClientPolicy currently have encoded-byte, decoded-byte and expansion-ratio budgets but no coding-depth budget. Add max_content_coding_depth to the named limits path and immutable HttpResourceBudgets; strict_defaults() should use the reviewed value 2. Keep the existing positional compatibility constructor from gaining another same-typed argument: it can delegate with the reviewed default, while callers that need depth 1 use from_limits. This avoids creating a new parameter-transposition hazard merely to expose the bound.
    • DecodedContent and HttpExchangeEvidence currently collapse decoding to one ContentCoding, and content_coding() returns that single value. That cannot truthfully represent gzip, deflate plus a layer-local raw-DEFLATE compatibility outcome. The repair therefore needs a bounded typed per-layer evidence value in wire order, with decoder outcome separate from the wire coding. Do not reconstruct a chain from the final decoder result.
    • decode_reader currently receives the current input length as the expansion denominator. Reusing it naïvely per layer would reset the ratio at each transition. The chain implementation must carry the original transfer-decoded coded-content length into every layer limit check; current-layer length may still be used for decoder/trailing-byte mechanics, but not as the cumulative expansion denominator.
    • RFC 9110 §8.4 also says identity is reserved for its special role in Accept-Encoding and SHOULD NOT appear in Content-Encoding. The parent currently accepts a sole explicit Content-Encoding: identity; retaining that behavior in this successor is therefore a deliberate compatibility leniency, not a standards requirement. Mixed identity chains remain fail-closed as already planned and the doctoring/ADR must make this distinction explicit.

    This is an API/resource-model finding from current source plus current RFC authority, not permission to skip the realistic RED. #327 exact 64f9e4ebaea15b245d41b27c7092d1a80fc12ff4 remains test-only until its current native run executes the intended parser rejection.

  5. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Fresh RFC 9110 review adds one parser/evidence acceptance detail without changing the live #327 test-only head.

    Content-Encoding is a list-valued field. RFC 9110 §§5.2–5.3 permits repeated same-name field lines where the field definition allows a list, requires combination in received order, and makes that order significant; §8.4 then defines content codings in application order. Therefore the bounded ContentCodingChain must preserve one canonical encounter order across both comma-separated members and repeated Content-Encoding field lines. The depth budget applies to that combined sequence, not independently per field line.

    Implementation/test consequence after the existing realistic #327 RED is actually observed:

    • Content-Encoding: gzip, deflate and two received lines Content-Encoding: gzip followed by Content-Encoding: deflate must produce the same admitted wire-order chain and decode deflate then gzip.
    • Reversing the received field-line order is semantically different and must preserve/reverse that different chain rather than sort or normalize it.
    • Empty/unsupported/mixed-identity members and depth overflow must fail during complete-chain admission before any decoder runs, including when the invalid/depth-crossing member occurs on a later repeated field line.
    • Evidence must retain the admitted combined wire-order chain, so replay/audit does not depend on reconstructing how field lines happened to be split.

    This closes a standards-coverage gap in the proposed design; it does not claim a new source defect beyond #326, does not supersede #327 exact 64f9e4ebaea15b245d41b27c7092d1a80fc12ff4, and does not justify production implementation before that realistic test receives an executable hosted RED.

    Primary authority: Fielding, R., Nottingham, M., & Reschke, J. (2022). HTTP semantics (RFC 9110; STD 97), §§5.2, 5.3, 8.4. Internet Engineering Task Force. https://doi.org/10.17487/RFC9110

  6. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Fresh RFC 9110 + current-parent audit tightens the severity/acceptance boundary without widening #327.

    The first slice is not merely passively missing a standards-valid representation form. request.rs currently emits Accept-Encoding: gzip, deflate on every supported GET/HEAD request, while content.rs::select_content_coding accepts either coding alone but rejects any second Content-Encoding member. RFC 9110 §12.5.3 says Accept-Encoding identifies response content codings acceptable to the user agent and explicitly notes that a representation can carry multiple content codings; §8.4 requires those applied codings to be listed in application order. A server can therefore return a two-layer representation composed entirely of codings OriginWeave advertised as acceptable, and the current parser will fail closed on that response. This remains an interoperability/negotiation-consistency defect rather than an unsafe decode, but it is buyer-visible capability over-advertisement and strengthens the case for #327.

    Acceptance consequence: keep the existing realistic gzip, deflate TLS RED, but treat its desired GREEN as restoring consistency between the fixed request advertisement and the bounded decoder. Do not widen the advertisement or add new codings. If the eventual implementation cannot satisfy the bounded chain contract, the safe fallback would be to narrow Accept-Encoding rather than keep advertising a coding combination the client cannot consume.

    A second standards distinction should remain explicit in the repair. RFC 9530 defines Content-Digest over HTTP message content and Repr-Digest over selected representation data; they are different semantic targets even though, for this first slice's complete 200 response, both can legitimately be verified over the same transfer-decoded, still-content-coded byte sequence. Current integrity.rs already limits Repr-Digest verification to status 200 without Content-Range and marks unsupported contexts rather than guessing representation bytes. Stacked decoding must preserve that ordering and must not collapse the two digest concepts into a new generic post-decode digest field. HEAD/no-content remains an explicitly unsupported verification context for this implementation, not evidence that an empty body is the selected representation.

    Parent #37 subsequently received executable CI and exposed a rustfmt-only failure. Its canonical artifact was applied verbatim as ordinary-forward 7007140e95f94d1601259384bf646b8bde6a240c, and #327 adopted that repaired parent non-force. Current test-only #327 is therefore exact b7e056a781297d570c908710737028ecd8ed5abd; fresh compare against parent is 3 commits ahead / 0 behind with exactly one changed file, the +229 integration regression. New exact CI 35804887882 is live. No production/source decoding mutation is justified until that generation executes and yields the intended parser-attributable RED.

  7. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Fresh policy/negotiation review finds one inconsistency in the current Proposed #326 design before any production implementation.

    The proposed max_content_coding_depth = 2 says callers may lower the depth to 1 via HttpPolicyLimits. However, current request.rs unconditionally emits Accept-Encoding: gzip, deflate; it is not policy-derived. RFC 9110 §12.5.3 defines those tokens as response content codings the user agent accepts and explicitly allows a representation to have multiple content codings, while §8.4 records those codings in application order. Therefore a depth-1 policy combined with the unchanged request serializer would intentionally advertise both gzip and deflate yet reject the standards-valid two-layer representation that #327 is meant to support. A depth limit alone cannot express “either gzip or deflate, but never both” in Accept-Encoding.

    Acceptance repair: keep reviewed/default depth 2 for the fixed Accept-Encoding: gzip, deflate first slice. Do not expose a caller-lowerable depth of 1 unless request negotiation is also made policy-coherent. If lower depth is required later, add an explicit bounded accepted-coding/advertisement policy and derive both Accept-Encoding and decoder admission from the same immutable policy value; alternatively narrow the advertisement to one coding. Do not silently let max_content_coding_depth=1 recreate the current capability-over-advertisement defect.

    This does not widen #327 or supersede its live test-only exact head b7e056a781297d570c908710737028ecd8ed5abd. It tightens the pending policy contract only; production Rust still waits for the existing authenticated TLS RED to execute.

    Primary authority: Fielding, R., Nottingham, M., & Reschke, J. (2022). HTTP semantics (RFC 9110; STD 97), §§8.4, 12.5.3. Internet Engineering Task Force. https://doi.org/10.17487/RFC9110

  8. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Test-first successor #327 advanced ordinary-forward to exact e93020a79b9acd300f8fbb9e2a6800f82348219c on unchanged canonical parent #37 7007140e95f94d1601259384bf646b8bde6a240c.

    The realistic TLS RED now proves both sides of the buyer-facing negotiation inconsistency before accepting the parser failure: (1) the peer receives the exact expected GET request and (2) that captured request contains exact Accept-Encoding: gzip, deflate. It then serves the standards-valid two-layer Content-Encoding: gzip, deflate representation and still expects the current single-coding parser to fail at UnsupportedContentCoding until the eventual bounded repair.

    This closes a missing-fixture gap only; production code, policy budgets, evidence types, workflows, rulesets, and release surfaces are unchanged. The first-slice policy remains fixed/default depth 2 while request advertisement remains fixed to both codings; the earlier issue-body sentence allowing callers to reduce depth to 1 is superseded by the later negotiation-consistency decision and must not be used as implementation authority.

    Fresh exact CI 35812952026 exists but is currently pre-step queued, so no hosted RED or GREEN is claimed yet.

  9. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Current implementation lineage update for the stacked Content-Encoding gap: parent #37 advanced by a real hosted strict-Clippy repair to exact 219b43bfa87ab4fd90a77bb962df2797925bf661; child #327 was adopted ordinary/non-force to exact beabc7d3e27c5c407d2847ff179eb16682ad86cd.

    Fresh compare parent -> child is 5 ahead / 0 behind with merge base equal to the current parent. The aggregate child delta is still exactly crates/originweave-http/tests/content_coding_stack_integration.rs (+235/-0), so none of the bounded production design in this issue has been implemented early. Current child CI 35816779893 is fresh and non-terminal. The required next causal transition remains executable authenticated-TLS RED on this exact test-only head before adding the bounded depth-2 decoder/evidence implementation.

  10. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    #327 advanced ordinary-forward to exact 3d1409ec34a08518ecc7d215132faffeb855a903 without changing production HTTP semantics. The delta repairs CodeRabbit's current pre-merge documentation finding on the test-only lane: its summary reported 10% docstring coverage across the 10 touched functions, so all ten fixture/test functions now carry invariant-focused rustdoc covering fixture-only trust, pinned certificate validity, HTTP/1.1 ALPN, request capture, loopback authorization, authenticated TLS, coding construction, and the negotiation/decode-order oracle. Fresh compare to parent #37 219b43bfa87ab4fd90a77bb962df2797925bf661 is 8 ahead / 0 behind and still one added integration-test file only (+269 / -0).

    Fresh exact CI is 35825132181; Rust contracts 107065098376 and Production coverage 107065098532 are pre-step queued with no assigned runner and steps=[]. No hosted UnsupportedContentCoding RED or current-head GREEN is claimed yet, and production stacked decoding remains intentionally unimplemented until that executable RED exists.

  11. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Current executable RED authority — exact c1b4f7a66c32d86ac8623cc10a3d0315cc72d74e on #327.

    The RFC 9110 empty-list-element correction is now represented in the real authenticated loopback-TLS fixture, not only in this issue's acceptance prose. The one-file/test-only successor covers three wire cases under the same destination/TLS/ALPN/request-capture boundary: ordinary Content-Encoding: gzip, deflate, Content-Encoding: gzip, , deflate,, and all-empty Content-Encoding: , ,. The latter two require empty list elements to contribute zero coding depth and the all-empty form to leave content unchanged. Every fixture still proves exact request-side Accept-Encoding: gzip, deflate before attributing the RED to response coding semantics.

    No production HTTP code changed. Exact CI 35836393281 is live with Rust contracts 107100775129 and Production coverage 107100775393 pre-step queued; predecessor results are not transferable. Production stacked decoding remains blocked on an executable hosted RED from this exact lineage.

  12. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Current executable-test authority update: exact 906a6170cda8ad2874f6ba04467a4aaf8a5e784f closes a fixture gap in #327. The acceptance contract already required repeated Content-Encoding field lines to preserve encounter order, but predecessor c1b4f7a... exercised only one field line with comma-separated members. 906a6170... changes only the existing authenticated-loopback-TLS integration test: the fixture can now emit ordered Content-Encoding field lines and adds Content-Encoding: gzip followed by Content-Encoding: deflate over the same gzip→deflate wire body, while still proving the request advertised Accept-Encoding: gzip, deflate. Production Rust remains untouched. New exact CI is 35842276629; Rust contracts 107119933463 and Production coverage 107119933970 are queued/nonterminal, so the intended hosted RED has not yet been observed and no decoder repair is claimed.

  13. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Current executable authority advanced test-only to OriginWeave#327@832d9ca6077f9b2cc539f34141daf58480fc16be (parent remains #37@219b43bfa87ab4fd90a77bb962df2797925bf661).

    New bounded finding: the prior TLS fixture proved only one supported application order, gzip, deflate. RFC 9110 requires Content-Encoding to preserve the order in which codings were applied, so a repair must derive reverse decoding from the declared chain rather than hard-code one algorithm order. Exact 832d9ca... adds a real authenticated loopback case with body gzip(deflate(original)), header Content-Encoding: deflate, gzip, and the same on-wire Accept-Encoding: gzip, deflate assertion. Production Rust remains untouched.

    Current CI 35846340441 is newly materialized but Rust contracts 107133318518 and Production coverage 107133318893 are still pre-step queued. No predecessor result is promoted to this head, and no stacked-decoder repair should start before an executable hosted RED is observed on the current test-only lineage.

  14. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Current test-first authority advanced ordinary-forward to 91a089c15b3d2719e5645eb6f7b8b8056a6dcc7e on PR #327. The new delta is test-only (+20 lines in the existing authenticated TLS fixture) and closes a distinct field-combination oracle gap: RFC 9110 §5.2–5.3 requires repeated same-named list field lines to form the combined value in received order, but the prior repeated-field fixture exercised only gzip then deflate. A parser could therefore preserve both comma-list orders while still incorrectly normalizing repeated field lines to one preferred codec order. The new case sends separate Content-Encoding: deflate then Content-Encoding: gzip lines with wire bytes gzip(deflate(original)) and requires the original bytes. Combined-list and repeated-field order are now each exercised in both valid directions. Production Rust remains untouched. Exact CI 35852532579 is live; Rust contracts 107153333402 and Production coverage 107153333551 are currently pre-step queued, so no hosted RED/GREEN is claimed yet and the bounded production decoder remains unimplemented.

  15. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Fresh RFC 9110 review found one additional stacked-parser compatibility obligation: §8.4.1 states that all content-coding values are case-insensitive. Parent #37 already preserves that for a single coding through eq_ignore_ascii_case, but #327's prior stacked RED matrix used only lowercase token names, so a new multi-coding collector could accidentally regress case-insensitive admission while fixing order/list handling.

    PR #327 now advances ordinary-forward to exact 2f447e62d9f7db33bb568d03adeed57b41a8ef17 with one additional authenticated-loopback-TLS test using Content-Encoding: GZip, DeFlAtE over correctly layered gzip then deflate bytes. It still proves the request advertised Accept-Encoding: gzip, deflate. Production Rust remains untouched; the PR is still one test file only (+415/-0), 13 ahead / 0 behind parent 219b43bf....

    Current exact CI 35857929172 has Rust contracts 107170805066 and Production coverage 107170805383 both pre-step queued (runner_id=0, steps=[]). Do not implement the stacked decoder until this exact lineage produces the intended hosted RED; when repairing, token comparison must remain ASCII-case-insensitive in addition to preserving list/field encounter order and the existing depth/budget/integrity constraints.

  16. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    #327의 test-only lineage가 실제 hosted runner에 진입했습니다. Predecessor 2f447e62d9f7db33bb568d03adeed57b41a8ef17의 CI 35857929172에서 Rust contracts 107170805066은 repository contracts 통과 후 canonical rustfmt 단계에서 실패했고, Production coverage 107170805383도 실제 runner에서 measurement 단계까지 실행 후 실패했습니다. 다만 현재 확보된 workflow evidence만으로 coverage failure를 곧바로 UnsupportedContentCoding semantic RED로 승격하지 않습니다.

    Rustfmt workflow artifact 10756315791 (sha256:6ce8ecd7448d543d4d28cd278499f750001594a1e866f10bd60e106035814b7a)의 canonical formatting delta만 ordinary-forward로 적용해 current child를 9a8e0f2cc6529e7a7ee0c4ad30c33cf27f82313b로 전진시켰습니다. Parent #37은 그대로 219b43bfa87ab4fd90a77bb962df2797925bf661; fresh compare는 14 ahead / 0 behind, one test file +407/-0이며 production Rust는 여전히 untouched입니다.

    Current CI 35878437627이 이 exact head에서 새로 materialize되어 있습니다. Formatting을 통과한 뒤 realistic TLS tests가 실제 parser RED를 내는지 확인한 후에만 bounded stacked decoder repair로 넘어갑니다. No blind rerun, source-neutral wake, lint suppression, workflow/gate change, force update, production pre-fix.

  17. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Fresh test-first authority: #327 advanced ordinary-forward to exact 22621be7043ec270ba504bd050d7daa0018aa16b with one additional authenticated-loopback TLS hostile case for acceptance item 4/7 (cumulative expansion attack). The child remains test-only and still changes exactly crates/originweave-http/tests/content_coding_stack_integration.rs.

    The fixture deliberately composes eight identical RFC 1952 gzip members as the inner gzip representation, then zlib-wraps that byte sequence as the outer deflate layer and sends Content-Encoding: gzip, deflate. Before the exchange it verifies three invariants from the actual generated byte lengths: (1) outer deflate expansion by itself is <= the strict default 32x ratio, (2) inner gzip expansion would also be <=32x if an implementation incorrectly reset the denominator at the layer boundary, but (3) final decoded content is >32x of the original transfer-decoded coded body. The required terminal behavior is therefore ContentExpansionRatioExceeded with encoded_bytes equal to the original wire-body length; returning decoded content would expose ratio^depth compounding.

    Current parent code still rejects the stack earlier as UnsupportedContentCoding, so this is a causal RED oracle for the planned repair, not production implementation. Current exact CI 35886919733 has Rust contracts 107269313396 and Production coverage 107269314034 queued pre-step with no runner and steps=[]; do not claim semantic RED or GREEN until that exact head executes. No resource limit, production decoder, workflow, or gate was changed.

  18. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    #327 advanced ordinary-forward to exact 0d0fd154b6b18a9ac17da3ec647da622953f69a9 over #37 219b43bfa87ab4fd90a77bb962df2797925bf661. Aggregate child delta remains one integration-test file, now +637/-0; production HTTP/evidence code is untouched.

    The realistic authenticated-TLS matrix now implements every hostile/interoperability case enumerated in #326 item 7: both valid application orders, repeated-field forms, empty/all-empty list handling, malformed outer and inner layers, truncated inner gzip member, trailing non-coding bytes, supported depth overflow, cumulative expansion against the original coded length, zero-byte coded input, and an unsupported non-empty coding. The depth-overflow and unsupported-member fixtures deliberately use hostile non-compressed bytes and require parser-level rejection, so decoder invocation would move the result to the wrong boundary.

    This is test-contract completion, not acceptance. Current exact CI is 35893934446; Rust contracts 107293029225 and Production coverage 107293029858 are queued pre-step with no runner/steps. Until this exact matrix executes, do not claim executable RED/GREEN, stacked decoding, evidence-chain completion, merge acceptance, or release readiness. Keep #326 open.

  19. seonghobae commented on Sep 23, 2026

    @seonghobae
    ContributorAuthor

    Authority currentization — stacked HTTP successor remains unmerged and fail-closed.

    #327 is exact 0d3911e558188db805a0affbe50e53ed02b481d0, directly on canonical #37 219b43bfa87ab4fd90a77bb962df2797925bf661, 46 ahead / 0 behind with merge base exactly #37. The new delta does not change decoder ownership; it closes a performance-evidence promotion bypass discovered after the three-file packager landed.

    The governed benchmark payload is generated by deterministic_payload(). That is deterministic regression data, not a realistic commercial buyer-path fixture. Test-first cac5e1619770123d6d2b78e3ef58b9ac18647df3 requires explicit fixture authority. b66ef73dfc10c60774d8388d079be9774b3f0bdd adds fixture_authority=deterministic_synthetic_no_external_dataset and fixture_acceptance_status=UNACCEPTED_SYNTHETIC_FIXTURE as a separate fail-closed gate. 1031b45a652959bb32c2dc9acd4dcb110e36ea38 binds the same state into content-coding-fixture.json and rejects a receipt that relabels the synthetic fixture as accepted. 0d3911e558188db805a0affbe50e53ed02b481d0 binds the fixture markers into the Rust receipt contract.

    Commercial acceptance keeps six meanings distinct: budget_status, source_acceptance_status, network_acceptance_status, fixture_acceptance_status, evidence_acceptance_status, and final acceptance_status. The current path remains blocked by #50's unreleased network freshness authority, the synthetic fixture, and unreleased authenticated evidence attestation; a p95 value cannot override those gates. The fix prevents future promotion of synthetic regression data but does not claim a realistic fixture or ≤20 ms buyer acceptance.

    The realistic fixture/corpus owner is not being duplicated in this lane: issue #203 owns benchmark corpus/source/license, case identity, data classification/retention and release-grade realistic evidence. Canary comment 5817864397 requires #327 to consume an approved/versioned fixture or capture identity from #203 rather than embed an ad hoc external dataset. #50 remains Draft/Proposed at ad87cfea59db711cb29ef90559790ba77e22029f; .github#2162/#2166 remain the central attestation owner/candidate; mutable source from neither owner is consumed.

    Canonical buyer baseline #238 is current at e92917e18038fd8c2cf5979b91412ddf85d6e4ec: test-first 89c4ed255b1d2fad0deee51b541878726145f5ba/baseline 9b4b892adee1168b7fef62e6fb8afdbc084513b5 introduced the fixture gate, then bdf061a01e36ec6457ce8b91f244fae51be4a451/e92917e18038fd8c2cf5979b91412ddf85d6e4ec bound the #203 canonical benchmark owner route.

    Exact #327 CI 36025189411 remains nonterminal: Rust contracts 107719813133 and Production coverage 107719813728 are queued with runner_id=0, steps=[]. No exact-head GREEN, accepted fixture/network/evidence authority, current-head review acceptance, merge acceptance, protected integration, tag, package, or release is claimed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions