Skip to content

feat(hyperlane)!: add runtime TLS, HTTP/2 and HTTP/3 - #47

Draft
vshengbro wants to merge 6 commits into
masterfrom
feat/runtime-tls-http2-http3
Draft

vshengbro wants to merge 6 commits into
masterfrom
feat/runtime-tls-http2-http3

Conversation

@vshengbro

@vshengbro vshengbro commented Oct 18, 2026 •

Copy link
Copy Markdown
Member

DO NOT MERGE. Keep this pull request in Draft.

Functional verification passed on the delivery head, but performance acceptance has NOT PASSED. The complete R3 cohort failed its gate; its invalid and inconclusive results are retained below. R3 predates the final manifest-only correction and is not presented as performance acceptance for the corrected head.

Summary

Add real server-side TLS, HTTP/2 and HTTP/3 selected at runtime through ServerConfig. HTTP/1 without TLS remains the default. TLS is configured independently, without Cargo features for protocol selection.

Changes

  • Add ServerProtocol::{Http1,Http2,Http3} and optional TlsConfig, preserving the three-argument ServerConfig::new and defaults for omitted JSON fields.
  • Serve HTTP/1 and HTTP/2 over TCP with optional TLS and protocol-specific ALPN. Serve HTTP/3 over QUIC with TLS 1.3, rejecting missing or invalid TLS material before binding.
  • Preserve routing, middleware, request-error and panic hooks, multiplexed streams, bounded response pumps, flow control, HTTP/1 keep-alive, upgrades and progressive/SSE delivery.
  • Preserve real TLS close-notify, including unlimited read timeouts, and correct short WebSocket frame encoding.
  • Resolve historical Lombok copy-getter, field/accessor, redundant-derive and source-layout violations without weakening the rules.
  • Replace 13 long parameter lists in the reviewed changed Rust source set with responsibility-specific internal carriers. Preserve ownership, await boundaries, cancellation, Arc clone sites and streaming behavior. This structural review is not a performance claim.
  • Update 16 ctares workspace dependency declarations to 10.2.8, preserving aliases and non-version options. Current members link three of them: color-output, lombok-macros and tokio-broadcast. The other 13 are declarations not adopted by current members, not 13 additional linked package upgrades. The system-time edge belongs to color-output.
  • Set the root workspace package version to 21.13.7. A follow-up correction restores the nine local path requirements to their pre-bump values, leaving version synchronization to the release workflow. It does not undo the explicitly requested ctares upgrades.
  • Keep all nine README files byte-identical to fixed baseline d7f18106dae61dc0c48d8d10635e201e6c5a754a.

Delivery and source binding

Base: master at d7f18106dae61dc0c48d8d10635e201e6c5a754a. Branch: feat/runtime-tls-http2-http3. Delivery head: 4a93c47e214087657ba7fc2a3dffd1aab461c880.

The update adds three English commits without rewriting the existing history:

  1. 1f9362e0c8246a96c735211beefa0f30c5f25e82: group protocol arguments and update ctares dependencies.
  2. 3673ce53424018e6d388131631051e1adf82b063: bump the workspace to 21.13.7.
  3. 4a93c47e214087657ba7fc2a3dffd1aab461c880: leave local dependency version synchronization to CI.

The final accepted local input aggregate is a1f886baa9e3200fadfc762c609bcfdb380420439d125702d86a1ecae2c795cd (624 source, lock and verification-tool records). Relative to the measured R3 aggregate b1ba8136738ec0cf1c3845af47b35a65a484eb13b2e381f19798665fcdfd1ee1, only Cargo.toml changed: the nine local dependency requirements were restored. Rust sources and the locally pinned lock are unchanged. No later performance cohort was run for this manifest correction.

The local lock SHA-256 remains b258a0ebf988d6cdd2f4b5e85516d1e178086dee0ff0cf4f5dc1fc2570d25479. Four unrelated Windows dependency edges (errno, quinn-udp, socket2, winapi-util) were previously restored to windows-sys 0.61.2 without other package/checksum changes. Cargo.lock is ignored by this repository, so this is retained local reproducibility evidence, not a claim that the PR contains that lock or that a Windows-target build was run.

Local functional verification on the delivery head

  • Real Git hooks accepted all three commits, without bypasses. The source commit exercised the pre-commit gate on 25 Rust/manifest files and the prepare-commit-msg gate on 24 Rust files. The manifest-only commits exercised their applicable manifest gate; the Rust-only guard had no selected Rust files.
  • Actual post-commit full standards audits: 54/54 PASS, including a final audit after verification.
  • Canonical pipeline invoked with the fixed base and --no-fix: audit, idempotent formatting, Clippy and test compilation passed. Its auto-fixer phase was explicitly skipped, not counted as executed.
  • crate fmt --check: passed.
  • cargo check --workspace --all-targets --all-features --locked --offline: passed.
  • Strict workspace/all-target/all-feature Clippy with -D warnings: passed with zero warnings.
  • cargo test --workspace --all-features --locked --offline: 822 passed, 0 failed, 6 inherited ignored doctests, 0 filtered across 26 result sections.
  • The earlier matching-Rust-source core integration suite was independently reconciled across three rounds: 150 executed cases per round, including 87 protocol cases. The final-head workspace test run was executed again; the earlier rounds are not described as new executions at the delivery head.
  • All 624 bound records remained stable throughout final-head verification. All nine README files still match the fixed baseline.

Local tooling limitation

The standalone legacy test-layout fixer is not accepted here as a workspace-wide idempotence proof. Invoked at the repository root it does not recurse into member test trees. A read-only member-scope probe selected 103 files and proposed changes to 52, including non-whitespace changes to six. Those transformations were not applied. The independent full audit and functional results above remain separately reported; the broader fixer-idempotence predicate is unresolved, not silently marked passed. No verifier or rule was weakened for this PR.

Exact-head CI

Rust workflow run 39117653245 completed successfully at exact head 4a93c47e214087657ba7fc2a3dffd1aab461c880: setup, check, tests, build and Clippy passed; publish and release were skipped. Mirror workflow run 39117650728 also completed successfully at that same head. These are current-head results, not the earlier green run for 3673ce5. CI success does not override the performance or supplemental tooling limitations below, and it does not authorize a merge or release.

Retained R3 performance result: NOT PASSED

R3 measured the preceding frozen 21.13.7 manifest and Rust sources, against baseline d7f18106dae61dc0c48d8d10635e201e6c5a754a (21.13.4). It collected all 257 planned client observations: 255 valid and two invalid, with four failed requests. The controller exited with status 1. Completeness is not performance acceptance.

Phase Planned / collected observations Valid Invalid Result
Closed-loop HTTP/1 comparison 120 / 120 118 2 NOT PASSED: 4 cells passed, 3 inconclusive, 1 invalid
Scheduled-rate comparison 80 / 80 80 0 NOT PASSED: 3 cells passed, 1 inconclusive
New-protocol matrix 42 / 42 42 0 Valid collection; absolute capability measurements
One/two-generator diagnostics 15 / 15 15 0 Valid collection; scaling observations, not a server-ceiling proof

Blocking comparison cells

The intervals below are percentage changes of candidate relative to baseline. The frozen screening margins were a 5% throughput loss and a 10% p99 increase, with zero request failures. A statistically established slowdown would block delivery even below a screening margin. Decisions used full precision; displayed bounds are rounded.

Phase Cell Throughput p99 latency
closed h1-keepalive-c64 INCONCLUSIVE, 95% CI [-5.10%, +6.58%] PASS
closed h1-short-c64 INVALID INVALID
closed h1-keepalive-c64-reqbody64k INCONCLUSIVE, 95% CI [-6.68%, +8.30%] INCONCLUSIVE, 95% CI [-14.78%, +11.00%]
closed h1-keepalive-c64-body64k INCONCLUSIVE, 95% CI [-6.37%, +1.31%] INCONCLUSIVE, 95% CI [-6.88%, +21.16%]
open h1-short-c64 at 500 requests/s PASS INCONCLUSIVE, 95% CI [-66.97%, +422.20%]

INCONCLUSIVE neither demonstrates a slowdown nor establishes non-inferiority. No failed or slow observation was discarded, no failed pair was replaced, no threshold was relaxed and no repetitions were appended to obtain a pass.

The invalid observations were closed h1-short-c64, candidate repetition 2 (three failed requests), and baseline repetition 8 (one failed request). Both recorded io: read: Connection reset by peer (os error 54). The entire cell remains invalid rather than recomputing an interval from survivors.

Diagnosis and measurement limits

  • Reset origin and mechanism remain unknown. Both arms being affected and READY-only server logs do not exclude a shared server defect.
  • Open short-cell p99 correlates with schedule-lag p99, but correlation and separately ranked percentiles do not establish causality or exonerate the server. A compilation snapshot more than five minutes before the first short-cell window does not establish compilation as the cause. The stronger delegated host/harness-only explanation was independently rejected.
  • The matrix covers 14 workloads, three repetitions each. Newly implemented TLS, HTTP/2 and HTTP/3 capabilities have no same-capability baseline in the comparison commit; these are absolute measurements, not invented A/B comparisons.
  • Saturation diagnostics cover all five protocol variants, including existing HTTP/1, with one and two concurrent client processes. They are candidate-only scaling observations, not A/B comparisons or a proven universal server ceiling. Some paired aggregate rates rose slightly and others fell; no blanket claim that the second generator always reduced throughput is made.
  • Fixed 500-connection/s short runs are rate-control settings, not maximum-throughput claims. Scheduled-rate latency includes schedule lag and connection establishment; closed-loop latency is not a fixed-load latency SLO.
  • The fixed plan used ten-second windows and two-second warmup, 20 closed-loop pairs at C256, ten closed short-connection pairs, five pairs for other closed workloads, and ten interleaved pairs for each scheduled-rate workload.
  • Source/tool/artifact fingerprints, complete observation populations and actual per-phase executable copies were independently read back. Benchmark-owned processes and listeners were gone at closure.
  • Historical 21.13.6 timing is not inherited. The failed R3 cohort remains intact and is not rebound to the corrected manifest. Further diagnosis and any new acceptance cohort need separately declared, controlled plans. A finite local matrix cannot guarantee universal zero regression.

Compatibility and scope

  • HTTP/3 requires TLS 1.3. Plain HTTP/3, automatic protocol detection/fallback, HTTP/2 extended CONNECT and HTTP/3 WebSocket CONNECT are not implemented. WebSocket remains an HTTP/1 upgrade, including WSS.
  • Stream::new(TcpStream, RequestConfig, bool) is preserved, but the transport field and generated accessors expose Box<dyn Transport>; TCP-specific callers must migrate. Addressless transports report Unsupported, not fabricated addresses.
  • WebSocketFrame::get_fin() and get_mask() return bool instead of &bool; Proxy::get_port() returns u16 instead of &u16. Remove obsolete dereferences and explicitly borrowed bindings. Previously restricted fields with public generated accessors becoming public also add direct access/move capabilities; this is not universally API-compatible.
  • Upstream publication alone does not prove source compatibility for currently unused dependency consumers.
  • The localhost-only TLS fixtures are deliberately public test material, not production credentials; no CA signing key is included.
  • An earlier worker violated its no-Git-write boundary by restoring 19 files and wrote task files under system /tmp. That disclosed violation is not retracted. Five specifically questioned tests match HEAD and the preserved starting snapshot; there is no complete immediately pre-restore byte snapshot, so no stronger claim about intermediate uncommitted changes is made. Subsequent repairs received fresh verification.
  • The local documentation-fixer repair belongs to the tooling repository, not this Hyperlane PR.

Retained local evidence

These paths identify local files, not public downloads or uploaded CI artifacts:

  • Final-head verification, real hook logs, input binding and supplemental tooling probe: /Users/sqs/.hermes/cache/scratch/hyperlane-pr47-delivery-21.13.7-o1psl185/root-only-correction/
  • Source-commit and version-commit hook logs: /Users/sqs/.hermes/cache/scratch/hyperlane-pr47-delivery-21.13.7-o1psl185/
  • Prior functional acceptance: /Users/sqs/.hermes/cache/scratch/hyperlane-parent-corrected-acceptance-sr5q22mq/accepted.json
  • R3 assessment: /Users/sqs/.hermes/cache/scratch/hyperlane-r3-parent-assessment-xrls5u0e/REPORT.md
  • Raw R3 cohort: /Users/sqs/.hermes/cache/scratch/hyperlane-pr-performance-21.13.7-r1/formal-cohort-21.13.7-1f799e0u/measurement/

This update does not authorize merging, enabling auto-merge, or publishing a release. The PR remains a draft with performance acceptance blocked.

Select server protocols at runtime with independent TLS configuration.
Keep HTTP/1 without TLS as the default and reject HTTP/3 without TLS.

- Reuse routing and middleware through streaming protocol adapters.
- Own listener state and preserve bounded TLS shutdown and upgrades.
- Add real-network framing, flow-control and lifecycle regressions.
- Clear historical accessor-contract debt without weakening the audit.
- Bump the published workspace from 21.13.4 to 21.13.5.

BREAKING CHANGE: Stream stores a boxed Transport rather than TcpStream.
WebSocketFrame fin/mask and Proxy port getters now return values instead
of references. Downstream TCP-specific access and dereferences must be
updated. Public accessor fields also gain direct field access.
@ghfind-review ghfind-review Bot added the review: high ghfind author score; see https://ghfind.com label Oct 18, 2026
vshengbro added 5 commits October 18, 2026 09:49
Replace protocol type annotations with crate-private aliases and remove
function-body blank lines without changing execution behavior.

Restore the root and core READMEs byte-for-byte to the fixed PR baseline.
The complete 21.13.6 worktree passed check, strict Clippy, 822 tests and
three parallel runs of all 87 protocol tests. The matching isolated
committed tree passed all 54 standards checks through real hooks.

Formal performance acceptance is still pending; keep PR 47 as a draft.
Update the shared package version and all nine local dependency versions.
All nine workspace packages inherit the same version. README bytes remain
unchanged from the fixed PR baseline.

Formal performance acceptance is still pending; this does not authorize
a merge or publication.
…dencies

Replace long internal signatures with responsibility-specific carriers.
Update the 16 ctares workspace dependency declarations to 10.2.8.
Preserve runtime protocol selection, independent TLS and streaming.

The fixed R3 performance cohort is complete but did not pass its gate.
Retain the invalid and inconclusive observations; keep PR #47 a draft.
Synchronize all nine local package requirements with the workspace version.
Keep every README unchanged and retain the performance merge blocker.
Keep the workspace package version at 21.13.7 and retain the explicit
ctares 10.2.8 upgrades. Restore the nine local path requirements to
their pre-bump values; the release workflow owns synchronization.

The failed R3 cohort remains historical evidence for the earlier
manifest. No current-source performance acceptance is claimed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

review: high ghfind author score; see https://ghfind.com

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant