Repository navigation
[HTTP interoperability] Bound stacked Content-Encoding chains without budget bypass #326
Description
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:
- Fielding, R., Nottingham, M., & Reschke, J. (2022). HTTP semantics (RFC 9110; STD 97). Internet Engineering Task Force. https://doi.org/10.17487/RFC9110
- Deutsch, P. (1996). DEFLATE compressed data format specification version 1.3 (RFC 1951). Internet Engineering Task Force. https://doi.org/10.17487/RFC1951
- Deutsch, P. (1996). GZIP file format specification version 4.3 (RFC 1952). Internet Engineering Task Force. https://doi.org/10.17487/RFC1952
- Polli, R., & Pardue, L. (2024). Digest fields (RFC 9530). Internet Engineering Task Force. https://doi.org/10.17487/RFC9530
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
- 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, deflatebefore the test attributes buyer impact to negotiation inconsistency. - Use reviewed fixed/default
max_content_coding_depth = 2for this first slice while request serialization remains fixed toAccept-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. - 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 towardmax_content_coding_depth. Reject unknown non-empty codings, mixedidentity, and non-empty depth overflow before any decoder runs. Decode admitted layers in reverse application order. Preserve a sole explicitContent-Encoding: identityonly as the existing compatibility behavior; an all-empty list is zero codings/no-op. - 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^depthamplification. Use checked or fail-closed arithmetic and fail before observable success. - Preserve gzip multi-member semantics within a single gzip layer. Do not confuse concatenated RFC 1952 members with multiple HTTP content-coding layers.
- 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.
- Realistic hostile/interoperability cases must cover: valid
gzip, deflateanddeflate, gzipchains; the equivalent repeated-field-line form in encounter order; RFC 9110 empty-list-element tolerance such asgzip, , 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. Content-Digest/Repr-Digestsemantics 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.- Evidence must retain the exact admitted wire-order chain of non-empty codings plus each layer's actual decoder outcome (
standardor 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. - 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.
- 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
seonghobae commentedon Sep 22, 2026
Test-first successor is now materialized as #327 on exact canonical HTTP parent #37
15e7c97dc1102934fa1e3ca8517b86938a808565.Exact child head
6f9614513a1d5abce918739e52129dd9c8cfd7c7adds only one realistic authenticated loopback TLS integration regression: the representation is encodedgzipfirst and then zlib-wrappeddeflate, the wire advertisesContent-Encoding: gzip, deflate, and the exchange must recover the original payload by decoding in reverse application order. The current parentselect_content_codingrejects 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
35795592798exists for the test-only head, but its Rust contracts106974026475and Production coverage106974026446are 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.seonghobae commentedon Sep 22, 2026
Implementation decision candidate while #327 RED waits for runner admission, derived from the current parent code rather than from a protocol-validity claim:
max_content_coding_depth = 2for 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.ContentCodingChain; missingContent-Encodingremains identity/no transform. Preserve a sole explicitContent-Encoding: identityonly as current compatibility behavior: RFC 9110 §8.4 reservesidentityfor its special role inAccept-Encodingand says it SHOULD NOT be included inContent-Encoding. Rejectidentitycombined with any other member, empty members, unknown codings, and depth overflow before any decoder runs. Repeatedgzip/deflateare not rejected merely for repetition because RFC 9110 allows codings to be listed in application order; the depth budget is the controlling product bound.deflatelayer, not a wire coding and not a second candidate branch after a size/ratio failure.ratio^depth.standardvs raw-DEFLATE compatibility). Do not infer wire order later from the final decoder result. RFC 9110 §§8.1 and 8.4 define representation metadata, includingContent-Encoding, against the coded form. RFC 9530 §§2-3 keepsContent-Digest/Repr-Digesttied 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.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^depthallowance; 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.
seonghobae commentedon Sep 22, 2026
#327 test-only head advanced ordinary-forward to
64f9e4ebaea15b245d41b27c7092d1a80fc12ff4before 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 expectedUnsupportedContentCodingrejection from unrelated setup/network failures, and keep desired success as the test oracle. New native CI is35796140817, currently nonterminal; predecessor queued evidence does not transfer. Production code remains untouched.seonghobae commentedon Sep 22, 2026
Fresh parent-source audit on #37 exact
15e7c97dc1102934fa1e3ca8517b86938a808565narrows the implementation shape before #327 leaves RED:HttpPolicyLimits/HttpClientPolicycurrently have encoded-byte, decoded-byte and expansion-ratio budgets but no coding-depth budget. Addmax_content_coding_depthto the named limits path and immutableHttpResourceBudgets;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 usefrom_limits. This avoids creating a new parameter-transposition hazard merely to expose the bound.DecodedContentandHttpExchangeEvidencecurrently collapse decoding to oneContentCoding, andcontent_coding()returns that single value. That cannot truthfully representgzip, deflateplus 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_readercurrently 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.identityis reserved for its special role inAccept-Encodingand SHOULD NOT appear inContent-Encoding. The parent currently accepts a sole explicitContent-Encoding: identity; retaining that behavior in this successor is therefore a deliberate compatibility leniency, not a standards requirement. Mixedidentitychains 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
64f9e4ebaea15b245d41b27c7092d1a80fc12ff4remains test-only until its current native run executes the intended parser rejection.seonghobae commentedon Sep 23, 2026
Fresh RFC 9110 review adds one parser/evidence acceptance detail without changing the live #327 test-only head.
Content-Encodingis 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 boundedContentCodingChainmust preserve one canonical encounter order across both comma-separated members and repeatedContent-Encodingfield 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, deflateand two received linesContent-Encoding: gzipfollowed byContent-Encoding: deflatemust produce the same admitted wire-order chain and decodedeflatethengzip.identitymembers 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.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
seonghobae commentedon Sep 23, 2026
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.rscurrently emitsAccept-Encoding: gzip, deflateon every supported GET/HEAD request, whilecontent.rs::select_content_codingaccepts either coding alone but rejects any secondContent-Encodingmember. RFC 9110 §12.5.3 saysAccept-Encodingidentifies 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, deflateTLS 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 narrowAccept-Encodingrather than keep advertising a coding combination the client cannot consume.A second standards distinction should remain explicit in the repair. RFC 9530 defines
Content-Digestover HTTP message content andRepr-Digestover 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. Currentintegrity.rsalready limitsRepr-Digestverification to status 200 withoutContent-Rangeand 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 exactb7e056a781297d570c908710737028ecd8ed5abd; fresh compare against parent is 3 commits ahead / 0 behind with exactly one changed file, the +229 integration regression. New exact CI35804887882is live. No production/source decoding mutation is justified until that generation executes and yields the intended parser-attributable RED.seonghobae commentedon Sep 23, 2026
Fresh policy/negotiation review finds one inconsistency in the current Proposed #326 design before any production implementation.
The proposed
max_content_coding_depth = 2says callers may lower the depth to 1 viaHttpPolicyLimits. However, currentrequest.rsunconditionally emitsAccept-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 bothgzipanddeflateyet 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” inAccept-Encoding.Acceptance repair: keep reviewed/default depth 2 for the fixed
Accept-Encoding: gzip, deflatefirst 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 bothAccept-Encodingand decoder admission from the same immutable policy value; alternatively narrow the advertisement to one coding. Do not silently letmax_content_coding_depth=1recreate 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
seonghobae commentedon Sep 23, 2026
Test-first successor #327 advanced ordinary-forward to exact
e93020a79b9acd300f8fbb9e2a6800f82348219con unchanged canonical parent #377007140e95f94d1601259384bf646b8bde6a240c.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-layerContent-Encoding: gzip, deflaterepresentation and still expects the current single-coding parser to fail atUnsupportedContentCodinguntil 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
35812952026exists but is currently pre-step queued, so no hosted RED or GREEN is claimed yet.seonghobae commentedon Sep 23, 2026
Current implementation lineage update for the stacked
Content-Encodinggap: parent #37 advanced by a real hosted strict-Clippy repair to exact219b43bfa87ab4fd90a77bb962df2797925bf661; child #327 was adopted ordinary/non-force to exactbeabc7d3e27c5c407d2847ff179eb16682ad86cd.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 CI35816779893is 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.seonghobae commentedon Sep 23, 2026
#327 advanced ordinary-forward to exact
3d1409ec34a08518ecc7d215132faffeb855a903without 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 #37219b43bfa87ab4fd90a77bb962df2797925bf661is 8 ahead / 0 behind and still one added integration-test file only (+269 / -0).Fresh exact CI is
35825132181; Rust contracts107065098376and Production coverage107065098532are pre-step queued with no assigned runner andsteps=[]. No hostedUnsupportedContentCodingRED or current-head GREEN is claimed yet, and production stacked decoding remains intentionally unimplemented until that executable RED exists.seonghobae commentedon Sep 23, 2026
Current executable RED authority — exact
c1b4f7a66c32d86ac8623cc10a3d0315cc72d74eon #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-emptyContent-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-sideAccept-Encoding: gzip, deflatebefore attributing the RED to response coding semantics.No production HTTP code changed. Exact CI
35836393281is live with Rust contracts107100775129and Production coverage107100775393pre-step queued; predecessor results are not transferable. Production stacked decoding remains blocked on an executable hosted RED from this exact lineage.seonghobae commentedon Sep 23, 2026
Current executable-test authority update: exact
906a6170cda8ad2874f6ba04467a4aaf8a5e784fcloses a fixture gap in #327. The acceptance contract already required repeatedContent-Encodingfield lines to preserve encounter order, but predecessorc1b4f7a...exercised only one field line with comma-separated members.906a6170...changes only the existing authenticated-loopback-TLS integration test: the fixture can now emit orderedContent-Encodingfield lines and addsContent-Encoding: gzipfollowed byContent-Encoding: deflateover the same gzip→deflate wire body, while still proving the request advertisedAccept-Encoding: gzip, deflate. Production Rust remains untouched. New exact CI is35842276629; Rust contracts107119933463and Production coverage107119933970are queued/nonterminal, so the intended hosted RED has not yet been observed and no decoder repair is claimed.seonghobae commentedon Sep 23, 2026
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 requiresContent-Encodingto 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. Exact832d9ca...adds a real authenticated loopback case with bodygzip(deflate(original)), headerContent-Encoding: deflate, gzip, and the same on-wireAccept-Encoding: gzip, deflateassertion. Production Rust remains untouched.Current CI
35846340441is newly materialized but Rust contracts107133318518and Production coverage107133318893are 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.seonghobae commentedon Sep 23, 2026
Current test-first authority advanced ordinary-forward to
91a089c15b3d2719e5645eb6f7b8b8056a6dcc7eon 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 onlygzipthendeflate. 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 separateContent-Encoding: deflatethenContent-Encoding: gziplines with wire bytesgzip(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 CI35852532579is live; Rust contracts107153333402and Production coverage107153333551are currently pre-step queued, so no hosted RED/GREEN is claimed yet and the bounded production decoder remains unimplemented.seonghobae commentedon Sep 23, 2026
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
2f447e62d9f7db33bb568d03adeed57b41a8ef17with one additional authenticated-loopback-TLS test usingContent-Encoding: GZip, DeFlAtEover correctly layeredgzipthendeflatebytes. It still proves the request advertisedAccept-Encoding: gzip, deflate. Production Rust remains untouched; the PR is still one test file only (+415/-0), 13 ahead / 0 behind parent219b43bf....Current exact CI
35857929172has Rust contracts107170805066and Production coverage107170805383both 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.seonghobae commentedon Sep 23, 2026
#327의 test-only lineage가 실제 hosted runner에 진입했습니다. Predecessor
2f447e62d9f7db33bb568d03adeed57b41a8ef17의 CI35857929172에서 Rust contracts107170805066은 repository contracts 통과 후 canonical rustfmt 단계에서 실패했고, Production coverage107170805383도 실제 runner에서 measurement 단계까지 실행 후 실패했습니다. 다만 현재 확보된 workflow evidence만으로 coverage failure를 곧바로UnsupportedContentCodingsemantic 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.seonghobae commentedon Sep 23, 2026
Fresh test-first authority: #327 advanced ordinary-forward to exact
22621be7043ec270ba504bd050d7daa0018aa16bwith one additional authenticated-loopback TLS hostile case for acceptance item 4/7 (cumulative expansion attack). The child remains test-only and still changes exactlycrates/originweave-http/tests/content_coding_stack_integration.rs.The fixture deliberately composes eight identical RFC 1952 gzip members as the inner
gziprepresentation, then zlib-wraps that byte sequence as the outerdeflatelayer and sendsContent-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 thereforeContentExpansionRatioExceededwithencoded_bytesequal to the original wire-body length; returning decoded content would exposeratio^depthcompounding.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 CI35886919733has Rust contracts107269313396and Production coverage107269314034queued pre-step with no runner andsteps=[]; do not claim semantic RED or GREEN until that exact head executes. No resource limit, production decoder, workflow, or gate was changed.seonghobae commentedon Sep 23, 2026
#327 advanced ordinary-forward to exact
0d0fd154b6b18a9ac17da3ec647da622953f69a9over #37219b43bfa87ab4fd90a77bb962df2797925bf661. 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 contracts107293029225and Production coverage107293029858are 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.seonghobae commentedon Sep 23, 2026
Authority currentization — stacked HTTP successor remains unmerged and fail-closed.
#327 is exact
0d3911e558188db805a0affbe50e53ed02b481d0, directly on canonical #37219b43bfa87ab4fd90a77bb962df2797925bf661, 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-firstcac5e1619770123d6d2b78e3ef58b9ac18647df3requires explicit fixture authority.b66ef73dfc10c60774d8388d079be9774b3f0bddaddsfixture_authority=deterministic_synthetic_no_external_datasetandfixture_acceptance_status=UNACCEPTED_SYNTHETIC_FIXTUREas a separate fail-closed gate.1031b45a652959bb32c2dc9acd4dcb110e36ea38binds the same state intocontent-coding-fixture.jsonand rejects a receipt that relabels the synthetic fixture as accepted.0d3911e558188db805a0affbe50e53ed02b481d0binds 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 finalacceptance_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
5817864397requires #327 to consume an approved/versioned fixture or capture identity from #203 rather than embed an ad hoc external dataset. #50 remains Draft/Proposed atad87cfea59db711cb29ef90559790ba77e22029f;.github#2162/#2166remain the central attestation owner/candidate; mutable source from neither owner is consumed.Canonical buyer baseline #238 is current at
e92917e18038fd8c2cf5979b91412ddf85d6e4ec: test-first89c4ed255b1d2fad0deee51b541878726145f5ba/baseline9b4b892adee1168b7fef62e6fb8afdbc084513b5introduced the fixture gate, thenbdf061a01e36ec6457ce8b91f244fae51be4a451/e92917e18038fd8c2cf5979b91412ddf85d6e4ecbound the #203 canonical benchmark owner route.Exact #327 CI
36025189411remains nonterminal: Rust contracts107719813133and Production coverage107719813728are queued withrunner_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.