feat: bound HTTP/1.1 semantics to authenticated streams - #11
feat: bound HTTP/1.1 semantics to authenticated streams#11seonghobae wants to merge 332 commits into
Conversation
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthrough인증된 TLS 연결에서 단일 HTTP/1.1 ChangesHTTP/1.1 의미론
Estimated code review effort: 5 (Critical) | ~120 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant HttpExchangePlan
participant AuthenticatedTlsConnection
participant ResponseParser
participant ContentDecoder
participant Evidence
Caller->>HttpExchangePlan: 요청 및 정책으로 계획 생성
HttpExchangePlan->>AuthenticatedTlsConnection: peer·origin·ALPN 검증
HttpExchangePlan->>AuthenticatedTlsConnection: HTTP/1.1 요청 쓰기
AuthenticatedTlsConnection->>ResponseParser: 응답 헤드와 본문 전달
ResponseParser->>ContentDecoder: framing된 본문 디코딩
ContentDecoder->>Evidence: 콘텐츠·digest·MIME 결과 기록
Evidence-->>Caller: AuthenticatedHttpResponse 반환
Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (3 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
Comment |
seonghobae
left a comment
There was a problem hiding this comment.
Standards-conformance finding on exact head 9032b5f7aeaac2626be926a05ab0252f3e8ba06d: response_head::parse_status_line currently accepts HTTP/1.1 200 without the mandatory separator SP, while rejecting HTTP/1.1 200 when the reason phrase is absent. RFC 9112 §4 defines status-line = HTTP-version SP status-code SP [ reason-phrase ] and explicitly requires the server to send the separator SP even when the reason phrase is absent. Add the regression contract first (accept the empty reason phrase after the mandatory SP; reject a missing second SP), then adjust the parser. Keep strict CRLF and field parsing unchanged. Primary source: RFC 9112 §4, https://www.rfc-editor.org/rfc/rfc9112.html#section-4
|
@coderabbitai review |
|
|
@coderabbitai review |
|
|
@coderabbitai review @opencode-agent @cwl-noema-review Review-only request for exact current head |
|
I will verify the specified HTTP semantics, security boundaries, CI evidence, and workflow restrictions. I will report only findings that reproduce on this exact head. I will not mutate the branch or merge it.
|
|
@coderabbitai review Trigger the previously requested full review for exact current head |
|
I will reassess the complete HTTP/1.1 diff. I will report only findings that reproduce on this exact head. I will not mutate the branch or merge it.
|
|
@coderabbitai review Run the previously requested full review for the exact unchanged current head |
|
I will assess only findings that reproduce on that range. I will not mutate the branch or merge the PR. This review does not provide a qualifying independent non-author approval. ✅ Action performedFull review finished. |
There was a problem hiding this comment.
Actionable comments posted: 10
🧹 Nitpick comments (10)
crates/originweave-http/src/tests/chunked_wire_budget_contract.rs (1)
4-9: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win기대 상한값의 산출 근거를 남기십시오.
라인 7은
18_104_340을 상수로 고정합니다. 이 값이 어떤 정책 기본값에서 나오는지 파일에 설명이 없습니다.DEFAULT_MAX_ENCODED_CONTENT_BYTES,DEFAULT_MAX_CHUNK_COUNT,DEFAULT_MAX_TRAILER_SECTION_BYTES중 하나가 바뀌면 이 테스트는 실패합니다. 그때 어떤 입력이 바뀌었는지, 새 기대값이 무엇이어야 하는지 알 수 없습니다.산출식을 주석으로 남기거나, 정책 기본값에서 기대값을 유도하십시오. 라인 8의 18 MiB 상한 어서션은 그대로 유지하십시오. 그 어서션이 실제 불변식을 표현합니다.
♻️ 산출 근거를 남기는 형태
#[test] fn default_chunked_wire_prefix_stays_below_eighteen_mib() { - let maximum = maximum_chunked_wire_bytes(&HttpClientPolicy::strict_defaults()); - assert_eq!(maximum, 18_104_340); + let policy = HttpClientPolicy::strict_defaults(); + let maximum = maximum_chunked_wire_bytes(&policy); + // 인코딩된 콘텐츠 상한에 청크별 크기 줄과 CRLF 오버헤드, 그리고 trailer 구간 상한을 + // 더한 값입니다. 정확한 항은 `maximum_chunked_wire_bytes`의 정의를 따릅니다. + assert_eq!(maximum, 18_104_340); + assert!(maximum > policy.max_encoded_content_bytes()); assert!(maximum < 18 * 1024 * 1024); }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/originweave-http/src/tests/chunked_wire_budget_contract.rs` around lines 4 - 9, Update default_chunked_wire_prefix_stays_below_eighteen_mib so the expected 18_104_340 value is derived from or documented against DEFAULT_MAX_ENCODED_CONTENT_BYTES, DEFAULT_MAX_CHUNK_COUNT, and DEFAULT_MAX_TRAILER_SECTION_BYTES. Preserve the 18 MiB upper-bound assertion unchanged.tests/test_repository_contract.py (2)
124-129: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win실패 메시지에 문서 이름을 포함하십시오.
이 반복문은 두 문서를 같은 어서션으로 검사합니다. 어서션에
msg인자가 없습니다. 검사가 실패하면 ADR과 설계 문서 중 어느 쪽이 원인인지 알 수 없습니다. 라인 81-88의 기존 반복문은relative를 전달하여 이 문제를 피합니다. 같은 방식을 적용하십시오.♻️ 문서 이름을 전달하는 수정
- for text in [adr, design]: - self.assertIn("originweave-http", text) - self.assertIn("HTTP/1.1", text) - self.assertIn("AuthenticatedTlsConnection", text) - self.assertIn("never follow", text.lower()) - self.assertIn("RFC 9112", text) + for relative, text in [ + ("docs/adr/0007-bounded-http11-semantics.md", adr), + ("docs/superpowers/specs/2026-08-07-http11-semantics-design.md", design), + ]: + self.assertIn("originweave-http", text, relative) + self.assertIn("HTTP/1.1", text, relative) + self.assertIn("AuthenticatedTlsConnection", text, relative) + self.assertIn("never follow", text.lower(), relative) + self.assertIn("RFC 9112", text, relative)🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_repository_contract.py` around lines 124 - 129, Update the assertions in the loop over adr and design to include a msg identifying the current document, matching the existing loop pattern that passes relative. Preserve all assertion checks and use the loop’s document-name variable so failures distinguish the ADR from the design document.
62-70: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
required_paths에 새 문서를 추가하십시오.
tests/test_repository_contract.py의required_paths에 다음 경로를 추가하십시오.
docs/adr/0008-http-reason-phrase-diagnostics.mddocs/superpowers/specs/2026-08-08-http11-reason-phrase-addendum.md현재 테스트는 두 파일이 삭제되어도 통과합니다.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/test_repository_contract.py` around lines 62 - 70, Update the required_paths collection in tests/test_repository_contract.py to include docs/adr/0008-http-reason-phrase-diagnostics.md and docs/superpowers/specs/2026-08-08-http11-reason-phrase-addendum.md, preserving the existing required path entries.crates/originweave-http/src/policy.rs (1)
79-97: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy lift동일 타입 위치 인자 14개는 builder 또는 설정 구조체로 대체하십시오.
new는usize인자 13개를 연속으로 받습니다. 인접 인자를 바꿔 전달해도 각 값이 자기 상한 이내이면 검증을 통과합니다. 따라서 잘못된 정책이 조용히 생성될 수 있습니다.#[allow(clippy::too_many_arguments)]는 이 위험을 숨깁니다.
HttpClientPolicy::strict_defaults()를 기준으로 하는 builder, 또는 이름이 있는 입력 구조체를 도입하십시오. 그러면 각 예산이 이름으로 결합되고 기존 검증 로직은 그대로 유지됩니다.♻️ 입력 구조체 방식 예시
/// Named resource budgets for one HTTP/1.1 exchange policy. pub struct HttpClientPolicyBudgets { /// Largest serialized request size. pub max_request_bytes: usize, /// Largest response status-line size. pub max_status_line_bytes: usize, // ... 나머지 예산 필드 } impl HttpClientPolicy { /// Validate every time, count, byte, and expansion budget. pub fn from_budgets( exchange_timeout: Duration, budgets: HttpClientPolicyBudgets, alpn_policy: AlpnHttp11Policy, integrity_requirement: IntegrityRequirement, ) -> Result<Self, HttpError> { // 기존 validate_limit 호출을 그대로 재사용합니다. todo!() } }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/originweave-http/src/policy.rs` around lines 79 - 97, Replace the positional usize parameters in HttpClientPolicy::new with a named budgets structure or builder, using HttpClientPolicy::strict_defaults() as the baseline. Bind each limit by field name, remove the too_many_arguments allowance, and preserve the existing validation logic by routing the new constructor through the same validate_limit checks.crates/originweave-http/src/tests/region_contract.rs (1)
67-96: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win확장자 매핑 결과를 어서션하십시오.
이 테스트는
parse_content_disposition을 호출하고 결과를 두 번 언랩한 뒤 버립니다. 어서션이 없습니다. 테스트 이름은 모든 확장자 매핑을 검증한다고 말하지만, 실제로는 수락 여부만 확인합니다.관측 MIME은
classify_observed_mime(b"plain text", None)로 고정되어 있어text/plain입니다. 따라서notes.txt와page.html은 서로 다른extension_mime_relation값을 만들어야 합니다. 현재는 두 결과가 같아져도 테스트가 통과합니다.각 확장자에 기대하는
extension_mime_relation을 함께 두고 어서션하십시오. 같은 문제로crates/originweave-http/src/tests/coverage_contract.rs의 MIME 테스트가 이전 리뷰에서 지적되었고 수정되었습니다.💚 기대 매핑을 고정하는 형태
- for filename in [ - "page.html", - "page.htm", + let cases: &[(&str, ExtensionMimeRelation)] = &[ + ("page.html", ExtensionMimeRelation::Mismatched), + ("page.htm", ExtensionMimeRelation::Mismatched), + ("notes.txt", ExtensionMimeRelation::Consistent), + ("README", ExtensionMimeRelation::Unknown), // ... 나머지 확장자에 기대 관계를 붙입니다. - ] { - let value = format!("attachment; filename={filename}"); - parse_content_disposition( - &fields(&[("content-disposition", value.as_bytes())]), - &observed, - ) - .expect("safe mapped filename") - .expect("disposition"); - } + ]; + for (filename, expected_relation) in cases { + let value = format!("attachment; filename={filename}"); + let disposition = parse_content_disposition( + &fields(&[("content-disposition", value.as_bytes())]), + &observed, + ) + .expect("safe mapped filename") + .expect("disposition"); + assert_eq!( + disposition.extension_mime_relation(), + *expected_relation, + "filename {filename}" + ); + }정확한 변형 이름과 기대값은
crates/originweave-http/src/disposition.rs의 실제 매핑 규칙에 맞추어 채우십시오.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/originweave-http/src/tests/region_contract.rs` around lines 67 - 96, Update every_filename_extension_mapping_is_exercised_before_download_handoff to pair each filename with the expected extension_mime_relation value from disposition.rs, then capture the parse_content_disposition result and assert that relation for each case. Preserve the existing successful parsing assertions while ensuring notes.txt and page.html produce distinct expected relations under the fixed text/plain observed MIME.crates/originweave-http/src/tests/coverage_contract.rs (1)
233-248: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win오류 어서션이 타입을 고정하지 않습니다. 세 곳의 반복문과 테스트가
is_err()만 확인합니다. 반환되는HttpError변형은 확인하지 않습니다. 각 입력은 서로 다른 오류 종류를 겨냥하므로, 파서가 이들을 하나의 오류로 뭉뚱그려도 테스트는 통과합니다. PR 목표는 결정적이고 타입이 지정된 실패를 요구합니다.
crates/originweave-http/src/tests/coverage_contract.rs#L233-L248: 12개 응답 입력 각각에 기대HttpError변형을 붙이고assert!(matches!(...))로 어서션하십시오. 같은 파일 라인 255-283이 이미 이 방식을 사용합니다.crates/originweave-http/src/tests/coverage_contract.rs#L293-L303: 7개 chunked 본문 입력 각각에 기대 변형을 붙이십시오. 라인 300의 금지된 trailer 필드 사례는 chunk 오류가 아니라 trailer 오류로 고정하십시오.crates/originweave-http/src/tests/region_contract.rs#L362-L371:parse_chunked_body가 trailer 구간 크기 오류를 반환하는지 어서션하십시오. 현재는Incomplete가 아닌 임의의 오류도 통과합니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/originweave-http/src/tests/coverage_contract.rs` around lines 233 - 248, Replace broad is_err() assertions with assert!(matches!(...)) assertions that verify the expected HttpError variant for every case. In crates/originweave-http/src/tests/coverage_contract.rs:233-248, assign a specific expected variant to each of the 12 parse_response_head inputs; also do so for each of the 7 chunked-body inputs at lines 293-303, classifying the prohibited trailer-field case as a trailer error. In crates/originweave-http/src/tests/region_contract.rs:362-371, assert that parse_chunked_body returns the trailer-section size error rather than merely any error, following the existing typed assertion pattern around lines 255-283.crates/originweave-http/src/evidence.rs (1)
358-362: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
response_complete는 항상true입니다.
From<EvidenceInput>가 이 필드를 상수true로 설정합니다. 증거는 성공 경로에서만 생성되므로 이 접근자는 값을 구분하지 못합니다. 공개 API 소비자는 이 값이 변할 수 있다고 오해할 수 있습니다.두 가지 중 하나를 선택하십시오. 첫째, 문서에 "이 값은 항상
true입니다"를 명시합니다. 둘째, 미래에 부분 완료 증거가 필요하지 않다면 필드와 접근자를 제거합니다.Also applies to: 437-437
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/originweave-http/src/evidence.rs` around lines 358 - 362, Update the documentation for response_complete to explicitly state that it is always true because EvidenceInput initializes the field to the constant true, or remove the field and response_complete accessor if partial completion is not intended to be supported; keep the public API consistent with the chosen behavior.crates/originweave-http/tests/error_contract.rs (1)
14-160: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win변형 목록이 컴파일 시점에 강제되지 않습니다.
새
HttpError변형을 추가해도 이 테스트는 계속 통과합니다. 목록은 수동 유지 보수에 의존합니다.목록 순회 후 각 오류에 대해 모든 변형을 나열하는
match를 수행하십시오. 그러면 변형 추가 시 컴파일이 실패하고 테스트 갱신이 강제됩니다.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/originweave-http/tests/error_contract.rs` around lines 14 - 160, Update the test around every_public_http_error_has_a_nonempty_operator_message so each error is exhaustively matched against all HttpError variants after the list is constructed. Use a wildcard-free match to enforce compile-time coverage, while retaining the existing nonempty-message assertion and requiring future variants to be added to the test cases.scripts/ci/verify_coverage.py (1)
13-13: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value진단 목록의 절단이 표시되지 않습니다.
다섯 개 함수가 결과를
MAX_REGION_DIAGNOSTICS(100)개로 자릅니다. 오류 메시지는 절단 사실을 표시하지 않습니다. 미커버 영역이 100개를 넘으면 운영자는 목록이 전부라고 오해할 수 있습니다.목록 길이가 한계에 도달하면 메시지에 "…(추가 N개 생략)"과 같은 표시를 추가하십시오. 게이트 동작은 변하지 않습니다.
Also applies to: 304-323
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@scripts/ci/verify_coverage.py` at line 13, Update the five diagnostic-producing functions that truncate results at MAX_REGION_DIAGNOSTICS to append an omission marker such as "…(추가 N개 생략)" when more entries exist, where N is the omitted count. Preserve the existing diagnostic content and gate behavior when no entries are omitted.crates/originweave-http/tests/framing_integration.rs (1)
37-236: 📐 Maintainability & Code Quality | 🔵 Trivial | 🏗️ Heavy liftloopback TLS 테스트 하니스가 다섯 파일에 중복됩니다. 인증 기관 생성, 리프 인증서 생성,
ServerConfig구성,origin_for,direct_connection,authenticated_connection, 정책 빌더가 거의 동일하게 반복됩니다. 공통 원인은 공유 테스트 지원 모듈이 없다는 점입니다. 이 때문에read_request의UnexpectedEof처리처럼 동작이 파일마다 갈라집니다.
crates/originweave-http/tests/common/mod.rs를 추가하고 각 파일이 이를 사용하도록 정리하십시오.
crates/originweave-http/tests/framing_integration.rs#L37-L236: 인증서·서버·연결·정책 헬퍼를 공용 모듈로 옮기고,read_request구현을 공용 버전으로 사용하십시오.crates/originweave-http/tests/exchange_integration.rs#L39-L179: 동일 헬퍼를 공용 모듈에서 가져오고, ALPN 값만 매개변수로 전달하십시오.crates/originweave-http/tests/exchange_region_integration.rs#L42-L203: 동일 헬퍼를 공용 모듈에서 가져오고,policy_with_timeout을 공용 정책 빌더로 대체하십시오.crates/originweave-http/tests/transport_failure_integration.rs#L44-L218: 동일 헬퍼를 공용 모듈에서 가져오고,policy_with_exchange_timeout을 공용 정책 빌더로 대체하십시오.crates/originweave-http/tests/chunked_persistence_integration.rs#L38-L243: 동일 헬퍼를 공용 모듈에서 가져오고, 서버 스레드 오류 처리를 공용ServerResult방식으로 통일하십시오.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@crates/originweave-http/tests/framing_integration.rs` around lines 37 - 236, Extract the duplicated loopback TLS test harness into a new shared tests/common/mod.rs, including certificate creation, server configuration, origin_for, direct_connection, authenticated_connection, the shared policy builder, and read_request with consistent UnexpectedEof handling. In crates/originweave-http/tests/framing_integration.rs#L37-236, replace the local helpers with the shared module; do the same in crates/originweave-http/tests/exchange_integration.rs#L39-179 while passing ALPN as a parameter, crates/originweave-http/tests/exchange_region_integration.rs#L42-203 by replacing policy_with_timeout, and crates/originweave-http/tests/transport_failure_integration.rs#L44-218 by replacing policy_with_exchange_timeout. In crates/originweave-http/tests/chunked_persistence_integration.rs#L38-243, use the shared helpers and standardize server-thread errors through ServerResult.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@crates/originweave-http/Cargo.toml`:
- Line 5: Update the workspace rust-version configuration inherited by all
crates to the exact string "1.97.1", replacing the current workspace reference
in the Cargo.toml configuration.
In `@crates/originweave-http/src/chunked.rs`:
- Around line 105-110: Update the trailer parsing path around find_crlf so an
over-budget trailer section is mapped from ChunkLineTooLarge to
TrailerSectionTooLarge, preserving the trailer budget as maximum_bytes. Keep
other find_crlf errors and incomplete parsing behavior unchanged.
In `@crates/originweave-http/src/disposition.rs`:
- Around line 316-321: The is_windows_device_name function must also reject
Windows reserved device names ending in superscript digits ¹, ², or ³ for both
COM and LPT prefixes. Extend its matching logic while preserving existing
checks, and add regression cases in the security contract tests for UTF-8
filename* values COM¹.txt and LPT².txt expecting InvalidContentDisposition.
In `@crates/originweave-http/src/exchange.rs`:
- Around line 437-460: Update read_chunked_body to preserve resumable parser
state across reads instead of passing the full wire buffer to parse_chunked_body
from offset zero each time. Track the cursor through completed chunks and resume
parsing from that position after appending new bytes, while retaining
incomplete-chunk state and existing maximum_wire_bytes and response-byte
validation behavior.
In `@crates/originweave-http/src/response_head.rs`:
- Around line 221-231: Remove the local trim_optional_whitespace function from
response_head.rs and reuse the shared crate::field::trim_optional_whitespace
instead. Extend the existing crate::field import in this module to include that
symbol, and update all local call sites to use it; do not modify the shared
implementation or unrelated parsing logic.
In `@crates/originweave-http/src/tests/exchange_error_contract.rs`:
- Around line 1-41: Update the `exchange_error_contract` test-module declaration
in `lib.rs` to apply the `coverage_nightly` `coverage(off)` attribute,
preventing its tests from affecting the exact 100% coverage gate. Also update
the governance coverage check to recognize this `#[path]` module.
In `@crates/originweave-http/tests/exchange_region_integration.rs`:
- Around line 115-121: Update the TLS request-reading loop around `tls.read` to
handle `ErrorKind::UnexpectedEof` as a normal termination, matching
`read_request` in the other integration tests. Preserve the existing behavior
for successful reads, clean EOF, and other errors so `assert_request` does not
fail when the client disconnects without `close_notify`.
In `@crates/originweave-http/tests/request_contract.rs`:
- Around line 144-162: Extend field_name_and_value_sizes_are_bounded to also
assert that RequestField::new accepts a 256-byte name and an 8,192-byte value,
while retaining the existing rejection assertions for 257 and 8,193 bytes. Cover
both sides of each boundary so the maximum values remain valid.
In `@crates/originweave-http/tests/transport_failure_integration.rs`:
- Around line 26-28: Increase EXCHANGE_TIMEOUT from 75 ms to 250 ms in the
transport failure integration tests, matching exchange_region_integration.rs,
and proportionally increase the WriteThenStall delay to 1 second so the test
still exercises the timeout behavior reliably.
In `@tests/test_verify_coverage.py`:
- Around line 149-153: Update the generic_covered region literal in the test
fixture to contain exactly eight elements by removing its trailing 0, matching
the expected LLVM region format and other region literals.
---
Nitpick comments:
In `@crates/originweave-http/src/evidence.rs`:
- Around line 358-362: Update the documentation for response_complete to
explicitly state that it is always true because EvidenceInput initializes the
field to the constant true, or remove the field and response_complete accessor
if partial completion is not intended to be supported; keep the public API
consistent with the chosen behavior.
In `@crates/originweave-http/src/policy.rs`:
- Around line 79-97: Replace the positional usize parameters in
HttpClientPolicy::new with a named budgets structure or builder, using
HttpClientPolicy::strict_defaults() as the baseline. Bind each limit by field
name, remove the too_many_arguments allowance, and preserve the existing
validation logic by routing the new constructor through the same validate_limit
checks.
In `@crates/originweave-http/src/tests/chunked_wire_budget_contract.rs`:
- Around line 4-9: Update default_chunked_wire_prefix_stays_below_eighteen_mib
so the expected 18_104_340 value is derived from or documented against
DEFAULT_MAX_ENCODED_CONTENT_BYTES, DEFAULT_MAX_CHUNK_COUNT, and
DEFAULT_MAX_TRAILER_SECTION_BYTES. Preserve the 18 MiB upper-bound assertion
unchanged.
In `@crates/originweave-http/src/tests/coverage_contract.rs`:
- Around line 233-248: Replace broad is_err() assertions with
assert!(matches!(...)) assertions that verify the expected HttpError variant for
every case. In crates/originweave-http/src/tests/coverage_contract.rs:233-248,
assign a specific expected variant to each of the 12 parse_response_head inputs;
also do so for each of the 7 chunked-body inputs at lines 293-303, classifying
the prohibited trailer-field case as a trailer error. In
crates/originweave-http/src/tests/region_contract.rs:362-371, assert that
parse_chunked_body returns the trailer-section size error rather than merely any
error, following the existing typed assertion pattern around lines 255-283.
In `@crates/originweave-http/src/tests/region_contract.rs`:
- Around line 67-96: Update
every_filename_extension_mapping_is_exercised_before_download_handoff to pair
each filename with the expected extension_mime_relation value from
disposition.rs, then capture the parse_content_disposition result and assert
that relation for each case. Preserve the existing successful parsing assertions
while ensuring notes.txt and page.html produce distinct expected relations under
the fixed text/plain observed MIME.
In `@crates/originweave-http/tests/error_contract.rs`:
- Around line 14-160: Update the test around
every_public_http_error_has_a_nonempty_operator_message so each error is
exhaustively matched against all HttpError variants after the list is
constructed. Use a wildcard-free match to enforce compile-time coverage, while
retaining the existing nonempty-message assertion and requiring future variants
to be added to the test cases.
In `@crates/originweave-http/tests/framing_integration.rs`:
- Around line 37-236: Extract the duplicated loopback TLS test harness into a
new shared tests/common/mod.rs, including certificate creation, server
configuration, origin_for, direct_connection, authenticated_connection, the
shared policy builder, and read_request with consistent UnexpectedEof handling.
In crates/originweave-http/tests/framing_integration.rs#L37-236, replace the
local helpers with the shared module; do the same in
crates/originweave-http/tests/exchange_integration.rs#L39-179 while passing ALPN
as a parameter,
crates/originweave-http/tests/exchange_region_integration.rs#L42-203 by
replacing policy_with_timeout, and
crates/originweave-http/tests/transport_failure_integration.rs#L44-218 by
replacing policy_with_exchange_timeout. In
crates/originweave-http/tests/chunked_persistence_integration.rs#L38-243, use
the shared helpers and standardize server-thread errors through ServerResult.
In `@scripts/ci/verify_coverage.py`:
- Line 13: Update the five diagnostic-producing functions that truncate results
at MAX_REGION_DIAGNOSTICS to append an omission marker such as "…(추가 N개 생략)"
when more entries exist, where N is the omitted count. Preserve the existing
diagnostic content and gate behavior when no entries are omitted.
In `@tests/test_repository_contract.py`:
- Around line 124-129: Update the assertions in the loop over adr and design to
include a msg identifying the current document, matching the existing loop
pattern that passes relative. Preserve all assertion checks and use the loop’s
document-name variable so failures distinguish the ADR from the design document.
- Around line 62-70: Update the required_paths collection in
tests/test_repository_contract.py to include
docs/adr/0008-http-reason-phrase-diagnostics.md and
docs/superpowers/specs/2026-08-08-http11-reason-phrase-addendum.md, preserving
the existing required path entries.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 29497017-d596-415c-a337-a794ef744e0b
⛔ Files ignored due to path filters (1)
Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (49)
CHANGELOG.mdCargo.tomlcrates/originweave-http/Cargo.tomlcrates/originweave-http/src/chunked.rscrates/originweave-http/src/content.rscrates/originweave-http/src/disposition.rscrates/originweave-http/src/error.rscrates/originweave-http/src/evidence.rscrates/originweave-http/src/exchange.rscrates/originweave-http/src/field.rscrates/originweave-http/src/framing.rscrates/originweave-http/src/integrity.rscrates/originweave-http/src/lib.rscrates/originweave-http/src/mime.rscrates/originweave-http/src/policy.rscrates/originweave-http/src/request.rscrates/originweave-http/src/response_head.rscrates/originweave-http/src/target.rscrates/originweave-http/src/tests/chunked_wire_budget_contract.rscrates/originweave-http/src/tests/coverage_contract.rscrates/originweave-http/src/tests/exchange_error_contract.rscrates/originweave-http/src/tests/integrity_padding_contract.rscrates/originweave-http/src/tests/mime_contract.rscrates/originweave-http/src/tests/reachability_contract.rscrates/originweave-http/src/tests/reason_phrase_contract.rscrates/originweave-http/src/tests/region_contract.rscrates/originweave-http/src/tests/security_contract.rscrates/originweave-http/tests/chunked_persistence_integration.rscrates/originweave-http/tests/error_contract.rscrates/originweave-http/tests/exchange_integration.rscrates/originweave-http/tests/exchange_region_integration.rscrates/originweave-http/tests/framing_integration.rscrates/originweave-http/tests/policy_contract.rscrates/originweave-http/tests/request_contract.rscrates/originweave-http/tests/response_failure_regressions.rscrates/originweave-http/tests/transport_failure_integration.rsdocs/adr/0007-bounded-http11-semantics.mddocs/adr/0008-http-reason-phrase-diagnostics.mddocs/doctoring.mddocs/doctoring/http-chunked-message-boundary.mddocs/doctoring/http-reason-phrase-diagnostics.mddocs/doctoring/http11-security-evidence.mddocs/superpowers/plans/2026-08-07-http11-semantics.mddocs/superpowers/specs/2026-08-07-http11-semantics-design.mddocs/superpowers/specs/2026-08-08-http11-reason-phrase-addendum.mdscripts/ci/verify_coverage.pytests/test_http_governance.pytests/test_repository_contract.pytests/test_verify_coverage.py
| loop { | ||
| match parse_chunked_body(&wire, policy)? { | ||
| ChunkParseResult::Complete(result) => { | ||
| if result.consumed != wire.len() { | ||
| return Err(HttpError::UnexpectedResponseBytes { | ||
| byte_count: wire.len() - result.consumed, | ||
| }); | ||
| } | ||
| return Ok(result); | ||
| } | ||
| ChunkParseResult::Incomplete => {} | ||
| } | ||
|
|
||
| let remaining_capacity = maximum_wire_bytes.saturating_sub(wire.len()); | ||
| let mut scratch = [0_u8; IO_BUFFER_BYTES]; | ||
| let read_limit = remaining_capacity.saturating_add(1).min(scratch.len()); | ||
| let byte_count = require_read_progress(read_with_deadline( | ||
| connection, | ||
| &mut scratch[..read_limit], | ||
| deadline, | ||
| timeout, | ||
| )?)?; | ||
| extend_chunked_wire(&mut wire, &scratch[..byte_count], maximum_wire_bytes)?; | ||
| } |
There was a problem hiding this comment.
🚀 Performance & Scalability | 🟠 Major | 🏗️ Heavy lift
청크 본문을 매 읽기마다 처음부터 다시 파싱합니다.
parse_chunked_body는 항상 커서 0에서 시작합니다. read_chunked_body는 읽기마다 누적된 전체 wire를 다시 넘깁니다. 그래서 파싱 비용이 수신 바이트 수에 대해 이차적으로 증가합니다.
기본 정책에서 maximum_chunked_wire_bytes는 수천만 바이트 규모이고, 읽기 단위는 IO_BUFFER_BYTES(8 KiB)입니다. 그러면 재파싱 횟수는 수천 회이고, 각 회차가 누적 버퍼 전체를 다시 스캔합니다. 이는 bounded exchange의 CPU 예산을 약화합니다.
재개 가능한 파서 상태를 유지하십시오. 최소한 이미 완결된 청크까지의 커서를 보존하고, 다음 호출에서 그 지점부터 스캔하십시오.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/originweave-http/src/exchange.rs` around lines 437 - 460, Update
read_chunked_body to preserve resumable parser state across reads instead of
passing the full wire buffer to parse_chunked_body from offset zero each time.
Track the cursor through completed chunks and resume parsing from that position
after appending new bytes, while retaining incomplete-chunk state and existing
maximum_wire_bytes and response-byte validation behavior.
| fn trim_optional_whitespace(value: &[u8]) -> &[u8] { | ||
| let start = value | ||
| .iter() | ||
| .position(|byte| !matches!(byte, b' ' | b'\t')) | ||
| .unwrap_or(value.len()); | ||
| let end = value | ||
| .iter() | ||
| .rposition(|byte| !matches!(byte, b' ' | b'\t')) | ||
| .map_or(start, |index| index + 1); | ||
| &value[start..end] | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
중복된 trim_optional_whitespace를 제거하고 crate::field의 공유 함수를 사용하십시오.
이 함수는 crates/originweave-http/src/field.rs 라인 238-248의 pub(crate) fn trim_optional_whitespace와 본문이 동일합니다. crates/originweave-http/src/mime.rs 라인 427-437에도 같은 사본이 있습니다. 사본은 세 개입니다.
crates/originweave-http/src/framing.rs는 이미 공유 함수를 가져와 사용합니다. 이 파일도 라인 3에서 crate::field를 가져오므로 심볼 하나만 추가하면 됩니다. 세 개의 파서가 같은 wire 데이터를 처리하므로, 사본이 서로 달라지면 OWS 처리 결과가 갈라집니다.
♻️ 공유 함수로 통합하는 수정
-use crate::field::{FieldBlock, FieldLine, FieldSyntaxError};
+use crate::field::{FieldBlock, FieldLine, FieldSyntaxError, trim_optional_whitespace};-fn trim_optional_whitespace(value: &[u8]) -> &[u8] {
- let start = value
- .iter()
- .position(|byte| !matches!(byte, b' ' | b'\t'))
- .unwrap_or(value.len());
- let end = value
- .iter()
- .rposition(|byte| !matches!(byte, b' ' | b'\t'))
- .map_or(start, |index| index + 1);
- &value[start..end]
-}
-코딩 가이드라인에 따라: "Rust crates must remain independently understandable and reusable."
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| fn trim_optional_whitespace(value: &[u8]) -> &[u8] { | |
| let start = value | |
| .iter() | |
| .position(|byte| !matches!(byte, b' ' | b'\t')) | |
| .unwrap_or(value.len()); | |
| let end = value | |
| .iter() | |
| .rposition(|byte| !matches!(byte, b' ' | b'\t')) | |
| .map_or(start, |index| index + 1); | |
| &value[start..end] | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/originweave-http/src/response_head.rs` around lines 221 - 231, Remove
the local trim_optional_whitespace function from response_head.rs and reuse the
shared crate::field::trim_optional_whitespace instead. Extend the existing
crate::field import in this module to include that symbol, and update all local
call sites to use it; do not modify the shared implementation or unrelated
parsing logic.
Source: Coding guidelines
| #![allow(clippy::expect_used)] | ||
|
|
||
| use std::io; | ||
|
|
||
| use crate::HttpError; | ||
|
|
||
| fn restoration_failure() -> HttpError { | ||
| HttpError::TimeoutRestorationFailed { | ||
| source: io::Error::other("expected restoration failure"), | ||
| } | ||
| } | ||
|
|
||
| #[test] | ||
| fn primary_exchange_failure_precedes_timeout_restoration_failure() { | ||
| let result = crate::exchange::combine_exchange_and_restoration( | ||
| Err::<usize, _>(HttpError::IncompleteResponse), | ||
| Err(restoration_failure()), | ||
| ); | ||
| assert!(matches!(result, Err(HttpError::IncompleteResponse))); | ||
| } | ||
|
|
||
| #[test] | ||
| fn restoration_failure_is_reported_after_a_successful_exchange() { | ||
| let result = crate::exchange::combine_exchange_and_restoration( | ||
| Ok::<usize, HttpError>(42), | ||
| Err(restoration_failure()), | ||
| ); | ||
| assert!(matches!( | ||
| result, | ||
| Err(HttpError::TimeoutRestorationFailed { .. }) | ||
| )); | ||
| } | ||
|
|
||
| #[test] | ||
| fn successful_exchange_and_restoration_preserve_the_response() { | ||
| assert_eq!( | ||
| crate::exchange::combine_exchange_and_restoration(Ok::<usize, HttpError>(42), Ok(())) | ||
| .expect("successful exchange and restoration"), | ||
| 42 | ||
| ); | ||
| } |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Verify the #[path]-included test modules carry cfg(test) and coverage(off).
set -euo pipefail
rg -n -B 4 -A 1 '#\[path = "tests/' crates/originweave-http/src/lib.rsRepository: ContextualWisdomLab/OriginWeave
Length of output: 1317
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- module declarations ---'
sed -n '1,65p' crates/originweave-http/src/lib.rs
printf '%s\n' '--- governance test references ---'
rg -n -A 20 -B 8 'coverage_nightly|inline test module|path.*tests/' tests crates/originweave-httpRepository: ContextualWisdomLab/OriginWeave
Length of output: 29991
🏁 Script executed:
#!/bin/bash
set -euo pipefail
printf '%s\n' '--- coverage configuration and commands ---'
rg -n -i -C 3 'llvm-cov|coverage_nightly|coverage\(off\)|grcov|tarpaulin|100%|production coverage' . \
-g '!target' -g '!node_modules'
printf '%s\n' '--- path-included test modules and coverage attributes ---'
python3 - <<'PY'
from pathlib import Path
import re
path = Path("crates/originweave-http/src/lib.rs")
lines = path.read_text(encoding="utf-8").splitlines()
for i, line in enumerate(lines):
if '#[path = "tests/' in line:
context = lines[max(0, i - 2):i + 2]
print(f"{i + 1}: " + " | ".join(context))
PYRepository: ContextualWisdomLab/OriginWeave
Length of output: 40279
exchange_error_contract를 프로덕션 커버리지에서 제외하십시오.
crates/originweave-http/src/lib.rs:26의 선언에 #[cfg_attr(coverage_nightly, coverage(off))]가 없습니다. 정확한 100% 커버리지 게이트가 이 테스트 모듈을 포함할 수 있으므로 속성을 추가하고, 거버넌스 검사에도 해당 #[path] 모듈을 포함하십시오.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/originweave-http/src/tests/exchange_error_contract.rs` around lines 1
- 41, Update the `exchange_error_contract` test-module declaration in `lib.rs`
to apply the `coverage_nightly` `coverage(off)` attribute, preventing its tests
from affecting the exact 100% coverage gate. Also update the governance coverage
check to recognize this `#[path]` module.
| while !request.windows(4).any(|window| window == b"\r\n\r\n") { | ||
| match tls.read(&mut scratch) { | ||
| Ok(0) => break, | ||
| Ok(count) => request.extend_from_slice(&scratch[..count]), | ||
| Err(error) => return Err(error.to_string()), | ||
| } | ||
| } |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
요청 읽기 루프에서 TLS UnexpectedEof를 처리하지 않습니다.
crates/originweave-http/tests/framing_integration.rs의 read_request와 crates/originweave-http/tests/transport_failure_integration.rs의 동일 루프는 ErrorKind::UnexpectedEof를 정상 종료로 처리합니다. 이 파일의 루프는 해당 분기를 생략합니다. 클라이언트가 close_notify 없이 연결을 끊으면 서버 스레드가 Err를 반환합니다. 그러면 assert_request의 expect("server exchange")가 패닉하고 테스트가 불안정해집니다.
동일한 분기를 추가하여 동작을 일치시키십시오.
🛠️ 제안 수정
while !request.windows(4).any(|window| window == b"\r\n\r\n") {
match tls.read(&mut scratch) {
Ok(0) => break,
Ok(count) => request.extend_from_slice(&scratch[..count]),
+ Err(error) if error.kind() == std::io::ErrorKind::UnexpectedEof => {
+ if request.is_empty() {
+ break;
+ }
+ return Err(error.to_string());
+ }
Err(error) => return Err(error.to_string()),
}
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| while !request.windows(4).any(|window| window == b"\r\n\r\n") { | |
| match tls.read(&mut scratch) { | |
| Ok(0) => break, | |
| Ok(count) => request.extend_from_slice(&scratch[..count]), | |
| Err(error) => return Err(error.to_string()), | |
| } | |
| } | |
| while !request.windows(4).any(|window| window == b"\r\n\r\n") { | |
| match tls.read(&mut scratch) { | |
| Ok(0) => break, | |
| Ok(count) => request.extend_from_slice(&scratch[..count]), | |
| Err(error) if error.kind() == std::io::ErrorKind::UnexpectedEof => { | |
| if request.is_empty() { | |
| break; | |
| } | |
| return Err(error.to_string()); | |
| } | |
| Err(error) => return Err(error.to_string()), | |
| } | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/originweave-http/tests/exchange_region_integration.rs` around lines
115 - 121, Update the TLS request-reading loop around `tls.read` to handle
`ErrorKind::UnexpectedEof` as a normal termination, matching `read_request` in
the other integration tests. Preserve the existing behavior for successful
reads, clean EOF, and other errors so `assert_request` does not fail when the
client disconnects without `close_notify`.
| #[test] | ||
| fn field_name_and_value_sizes_are_bounded() { | ||
| let long_name = "a".repeat(257); | ||
| assert!(matches!( | ||
| RequestField::new(&long_name, b"value"), | ||
| Err(HttpError::RequestFieldNameTooLarge { | ||
| byte_count: 257, | ||
| maximum_bytes: 256, | ||
| }) | ||
| )); | ||
| let long_value = vec![b'a'; 8_193]; | ||
| assert!(matches!( | ||
| RequestField::new("x-test", &long_value), | ||
| Err(HttpError::RequestFieldValueTooLarge { | ||
| byte_count: 8_193, | ||
| maximum_bytes: 8_192, | ||
| }) | ||
| )); | ||
| } |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
허용 경계값도 함께 검증하십시오.
이 테스트는 거부 측(257바이트 이름, 8_193바이트 값)만 확인합니다. 허용 측(256바이트 이름, 8_192바이트 값)은 확인하지 않습니다. FieldLine::new의 비교 연산자가 >에서 >=로 바뀌어도 이 테스트는 통과합니다. 라인 79-93의 요청 대상 테스트는 양쪽 경계를 모두 확인합니다. 같은 방식을 적용하십시오.
💚 경계 쌍을 추가하는 수정
fn field_name_and_value_sizes_are_bounded() {
+ let exact_name = "a".repeat(256);
+ assert!(RequestField::new(&exact_name, b"value").is_ok());
let long_name = "a".repeat(257);
assert!(matches!(
RequestField::new(&long_name, b"value"),
Err(HttpError::RequestFieldNameTooLarge {
byte_count: 257,
maximum_bytes: 256,
})
));
+ let exact_value = vec![b'a'; 8_192];
+ assert!(RequestField::new("x-test", &exact_value).is_ok());
let long_value = vec![b'a'; 8_193];📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| #[test] | |
| fn field_name_and_value_sizes_are_bounded() { | |
| let long_name = "a".repeat(257); | |
| assert!(matches!( | |
| RequestField::new(&long_name, b"value"), | |
| Err(HttpError::RequestFieldNameTooLarge { | |
| byte_count: 257, | |
| maximum_bytes: 256, | |
| }) | |
| )); | |
| let long_value = vec![b'a'; 8_193]; | |
| assert!(matches!( | |
| RequestField::new("x-test", &long_value), | |
| Err(HttpError::RequestFieldValueTooLarge { | |
| byte_count: 8_193, | |
| maximum_bytes: 8_192, | |
| }) | |
| )); | |
| } | |
| #[test] | |
| fn field_name_and_value_sizes_are_bounded() { | |
| let exact_name = "a".repeat(256); | |
| assert!(RequestField::new(&exact_name, b"value").is_ok()); | |
| let long_name = "a".repeat(257); | |
| assert!(matches!( | |
| RequestField::new(&long_name, b"value"), | |
| Err(HttpError::RequestFieldNameTooLarge { | |
| byte_count: 257, | |
| maximum_bytes: 256, | |
| }) | |
| )); | |
| let exact_value = vec![b'a'; 8_192]; | |
| assert!(RequestField::new("x-test", &exact_value).is_ok()); | |
| let long_value = vec![b'a'; 8_193]; | |
| assert!(matches!( | |
| RequestField::new("x-test", &long_value), | |
| Err(HttpError::RequestFieldValueTooLarge { | |
| byte_count: 8_193, | |
| maximum_bytes: 8_192, | |
| }) | |
| )); | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/originweave-http/tests/request_contract.rs` around lines 144 - 162,
Extend field_name_and_value_sizes_are_bounded to also assert that
RequestField::new accepts a 256-byte name and an 8,192-byte value, while
retaining the existing rejection assertions for 257 and 8,193 bytes. Cover both
sides of each boundary so the maximum values remain valid.
| const TRUSTED_TIME_SECONDS: u64 = 1_767_225_600; | ||
| const TEST_TIMEOUT: Duration = Duration::from_secs(3); | ||
| const EXCHANGE_TIMEOUT: Duration = Duration::from_millis(75); |
There was a problem hiding this comment.
🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win
75 ms 교환 타임아웃은 부하가 큰 CI에서 불안정할 수 있습니다.
EXCHANGE_TIMEOUT은 execute() 시작 시점부터 계산합니다. 러너 부하가 크면 TLS 요청 쓰기 단계에서 데드라인이 만료될 수 있습니다. 그 경우 서버는 완전한 요청을 받지 못하고 assert_server_received_request의 expect("server exchange")가 패닉합니다.
crates/originweave-http/tests/exchange_region_integration.rs는 같은 이유로 이미 250 ms를 사용합니다. 이 파일도 같은 값으로 맞추고 WriteThenStall 지연을 비례해서 늘리십시오. 예: 250 ms 타임아웃과 1초 지연.
🛠️ 제안 수정
-const EXCHANGE_TIMEOUT: Duration = Duration::from_millis(75);
+const EXCHANGE_TIMEOUT: Duration = Duration::from_millis(250);- ServerBehavior::WriteThenStall(response, Duration::from_millis(300)),
+ ServerBehavior::WriteThenStall(response, Duration::from_secs(1)),
policy_with_exchange_timeout(EXCHANGE_TIMEOUT),Also applies to: 259-288
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@crates/originweave-http/tests/transport_failure_integration.rs` around lines
26 - 28, Increase EXCHANGE_TIMEOUT from 75 ms to 250 ms in the transport failure
integration tests, matching exchange_region_integration.rs, and proportionally
increase the WriteThenStall delay to 1 second so the test still exercises the
timeout behavior reliably.
| { | ||
| "name": "generic_covered", | ||
| "filenames": ["src/partial.rs"], | ||
| "regions": [[42, 9, 42, 15, 3, 0, 0, 0, 0]], | ||
| }, |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
영역 리터럴의 원소 개수가 다릅니다.
generic_covered의 영역은 원소가 9개입니다. 다른 모든 영역 리터럴은 8개입니다. _function_region_locations는 region[:8]만 사용하므로 테스트는 통과합니다. 그러나 이 리터럴은 LLVM 영역 형식과 맞지 않고 오타로 보입니다.
마지막 0을 제거하여 8개 원소로 맞추십시오.
🛠️ 제안 수정
- "regions": [[42, 9, 42, 15, 3, 0, 0, 0, 0]],
+ "regions": [[42, 9, 42, 15, 3, 0, 0, 0]],📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| { | |
| "name": "generic_covered", | |
| "filenames": ["src/partial.rs"], | |
| "regions": [[42, 9, 42, 15, 3, 0, 0, 0, 0]], | |
| }, | |
| { | |
| "name": "generic_covered", | |
| "filenames": ["src/partial.rs"], | |
| "regions": [[42, 9, 42, 15, 3, 0, 0, 0]], | |
| }, |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/test_verify_coverage.py` around lines 149 - 153, Update the
generic_covered region literal in the test fixture to contain exactly eight
elements by removing its trailing 0, matching the expected LLVM region format
and other region literals.
Buyer-visible problem
OriginWeave now authenticates a canonical HTTPS service on the exact previously authorized TCP stream, but it cannot yet perform a bounded HTTP exchange. Ambiguous framing, conflicting lengths, malformed chunks, unbounded content, decompression expansion, incomplete responses, misleading MIME metadata, unsafe filenames, or automatic redirect behavior would break the authority and evidence chain.
Approved design
This draft implements issue #9 as an independently reusable
originweave-httpRust crate. The approved design and task-level TDD plan are committed at:docs/superpowers/specs/2026-08-07-http11-semantics-design.mddocs/superpowers/plans/2026-08-07-http11-semantics.mdIntended vertical slice
GETorHEADexchange over an existingAuthenticatedTlsConnection;TDD state
The design and implementation plan are committed first. Production code and failing contract tests will be added task by task. Keep this pull request in Draft until the complete exact head passes CI, Security Scan, SAST, independent review, and all coverage/doc gates.
Closes #9
Summary by CodeRabbit
새로운 기능
문서
테스트