Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
77aa507
test(network): require operational teardown assessment
seonghobae Aug 30, 2026
b5396ee
test(network): format teardown assessment regression
seonghobae Aug 30, 2026
7b0880a
feat(network): separate protocol ack from teardown evidence
seonghobae Aug 30, 2026
1dbf3a8
feat(network): expose teardown assessment boundary
seonghobae Aug 30, 2026
bfd2044
test(network): require every teardown observation
seonghobae Aug 30, 2026
0fff981
test(network): require typed BiDi transport closure evidence
seonghobae Aug 30, 2026
4bc7c3c
style(network): apply canonical transport-close test formatting
seonghobae Aug 30, 2026
916f6d4
feat(network): observe typed BiDi transport closure
seonghobae Aug 30, 2026
eed38a3
feat(network): export bounded BiDi transport closure evidence
seonghobae Aug 30, 2026
69cfe4c
style(network): apply canonical transport-closure formatting
seonghobae Aug 30, 2026
6612af7
test(network): satisfy strict transport-closure contracts
seonghobae Aug 30, 2026
fa68bb9
test(network): cover fail-closed transport closure errors
seonghobae Aug 30, 2026
c691d07
chore(network): converge teardown evidence on current session.end res…
seonghobae Aug 30, 2026
5654d0c
chore(network): converge transport closure on current teardown stack
seonghobae Aug 30, 2026
f956341
test(network): require pong-tolerant BiDi transport close
seonghobae Aug 30, 2026
80f5000
fix(network): tolerate bounded pong before BiDi transport close
seonghobae Aug 30, 2026
01cfce2
test(network): bound pong handling during BiDi transport close
seonghobae Aug 30, 2026
a45812d
style(network): apply canonical rustfmt to transport close tests
seonghobae Aug 30, 2026
5ff8ae1
test(network): require typed transport evidence for BiDi teardown
seonghobae Aug 30, 2026
baba701
style(network): apply canonical rustfmt to typed teardown regression
seonghobae Aug 30, 2026
4d43cba
feat(network): bind typed transport closure to teardown
seonghobae Aug 30, 2026
7d72370
style(network): apply canonical teardown formatting
seonghobae Aug 30, 2026
ef1b4a9
test(network): reject forgeable teardown completion
seonghobae Aug 30, 2026
72449de
fix(network): fail closed on teardown placeholders
seonghobae Aug 30, 2026
ce7c40e
test(network): reject process profile teardown placeholders
seonghobae Aug 30, 2026
43c9ae7
fix(network): remove forgeable teardown placeholders
seonghobae Aug 31, 2026
cf5fd42
fix(network): restack teardown assessment on typed session.end
seonghobae Sep 1, 2026
2a93e7e
merge(network): restack transport closure on typed session.end
seonghobae Sep 1, 2026
b1712b8
merge(network): restack teardown binding on typed transport closure
seonghobae Sep 1, 2026
964c5b1
merge(network): restack teardown evidence on repaired status response
seonghobae Sep 2, 2026
cb49cda
merge(network): restack transport closure on repaired status response
seonghobae Sep 2, 2026
626026c
fix(network): repair typed teardown exact-head regression
seonghobae Sep 2, 2026
88e68f3
fix(network): encode validated BiDi response routing structurally
seonghobae Sep 3, 2026
ab1dea7
docs(doctoring): refresh WebDriver BiDi published baseline
seonghobae Sep 3, 2026
870cb39
fix(network): make BiDi response routing structurally valid
seonghobae Sep 3, 2026
4c112e7
merge(parent): refresh teardown evidence base
seonghobae Sep 4, 2026
463859f
merge(parent): refresh transport closure base
seonghobae Sep 4, 2026
d60e986
merge(parent): refresh teardown transport binding base
seonghobae Sep 4, 2026
5e2b17c
merge(parent): refresh teardown evidence base
seonghobae Sep 5, 2026
a484101
merge(parent): refresh transport close evidence base
seonghobae Sep 5, 2026
f8edec3
merge(parent): refresh teardown transport binding base
seonghobae Sep 5, 2026
0d72082
merge: restack teardown evidence on current response
seonghobae Sep 5, 2026
cbaf50d
merge: restack transport close on teardown evidence
seonghobae Sep 5, 2026
a13de5f
merge: restack teardown binding on close evidence
seonghobae Sep 5, 2026
f816be5
test(network): reject cross-connection teardown closure evidence
seonghobae Sep 5, 2026
f1f9664
fix(network): fail closed on connection-generation exhaustion
seonghobae Sep 5, 2026
fc61df5
fix(network): mint non-forgeable BiDi connection generations
seonghobae Sep 5, 2026
c7ce08a
test(network): cover BiDi connection-generation allocator
seonghobae Sep 5, 2026
ef62a4e
fix(network): retain connection provenance in BiDi correlation
seonghobae Sep 5, 2026
04f066c
fix(network): bind session.end correlation to exact connection
seonghobae Sep 5, 2026
54265a2
fix(network): bind session.end acknowledgments to connection provenance
seonghobae Sep 5, 2026
8a1b9ee
test(network): require session.end transport provenance
seonghobae Sep 5, 2026
dddb93c
fix(network): retain exact connection on transport closure evidence
seonghobae Sep 5, 2026
9452fc3
fix(network): reject teardown evidence from another connection
seonghobae Sep 5, 2026
77b294a
test(network): verify exact transport generation at teardown
seonghobae Sep 5, 2026
23eea66
fix(network): expose teardown provenance mismatch error
seonghobae Sep 5, 2026
92392b2
test(network): cover same-session reconnect and cross-session teardow…
seonghobae Sep 5, 2026
4bb85c2
test(network): prove same-endpoint reconnect provenance isolation
seonghobae Sep 5, 2026
ae6495e
refactor(network): type BiDi connection-generation provenance
seonghobae Sep 5, 2026
9115fd8
test(network): type connection-generation allocator evidence
seonghobae Sep 5, 2026
ddc1082
refactor(network): carry typed BiDi generation through correlation
seonghobae Sep 5, 2026
2b77143
refactor(network): type session.end connection provenance
seonghobae Sep 5, 2026
4255eb4
refactor(network): type transport-closure connection provenance
seonghobae Sep 5, 2026
0a94765
test(network): reproduce foreign BiDi response correlation
seonghobae Sep 5, 2026
1c2749e
feat(network): bind received BiDi messages to connection
seonghobae Sep 5, 2026
256f6b3
fix(network): reject foreign BiDi response transports
seonghobae Sep 5, 2026
9037db8
fix(network): require received connection provenance for session.end
seonghobae Sep 5, 2026
b35a248
feat(network): expose connection-bound BiDi message reader
seonghobae Sep 5, 2026
98fe192
test(network): bind session.end responses to receive stream
seonghobae Sep 5, 2026
d4cd2de
test(network): assert exact received transport mismatch
seonghobae Sep 5, 2026
ccefd01
refactor(network): return transport after complete BiDi message
seonghobae Sep 5, 2026
59e92c6
test(network): preserve transport through bound response read
seonghobae Sep 5, 2026
e7bfec4
test(network): cover connection-bound message reader
seonghobae Sep 5, 2026
f4e18ec
docs(network): trace received BiDi connection provenance
seonghobae Sep 5, 2026
feba41f
test(network): cover uncorrelatable connection-bound responses
seonghobae Sep 5, 2026
89e3975
fix(network): satisfy teardown provenance lint
seonghobae Sep 5, 2026
6f6d49f
fix(network): remove impossible BiDi provenance fallback
seonghobae Sep 5, 2026
ddfac5b
fix(network): expose generation exhaustion to connection tests
seonghobae Sep 5, 2026
78ffe1c
test(network): cover connection generation exhaustion
seonghobae Sep 5, 2026
8315eed
test(network): activate generation exhaustion coverage
seonghobae Sep 5, 2026
defa1a0
test(network): restore session.end response formatting
seonghobae Sep 5, 2026
00e007b
test(network): restore response provenance formatting
seonghobae Sep 5, 2026
2c8e9e2
test(network): restore teardown assessment formatting
seonghobae Sep 5, 2026
64b88e6
docs(network): record BiDi provenance quality-gate repair
seonghobae Sep 5, 2026
63cbca0
docs(network): align provenance note with Rust MSRV
seonghobae Sep 5, 2026
ebac126
fix(network): remove unused correlation accessor
seonghobae Sep 5, 2026
afb623e
merge: adopt current response in teardown assessment
seonghobae Sep 5, 2026
b11b6c9
chore: integrate current teardown parent into closure evidence
seonghobae Sep 5, 2026
3e70574
chore(network): integrate current closure provenance parent
seonghobae Sep 5, 2026
6865faa
chore(stack): bind repaired teardown successor to response base
seonghobae Sep 6, 2026
32b5615
test(network): reject replacement status replies in teardown stack
seonghobae Sep 7, 2026
c7ccb0c
merge: preserve teardown provenance while adopting current response p…
seonghobae Sep 7, 2026
be85f04
merge(stack): adopt current session-end response parent
seonghobae Sep 7, 2026
b97f57e
test(network): reject peer-close-only transport evidence
seonghobae Sep 7, 2026
8d63ec8
test(network): require Pong before bounded close completion
seonghobae Sep 7, 2026
1cb76a6
fix(network): complete bounded WebSocket closing handshake
seonghobae Sep 7, 2026
1376f4c
test(network): complete teardown close fixture
seonghobae Sep 7, 2026
2db547c
Merge remote-tracking branch 'origin/feat/webdriver-bidi-teardown-tra…
seonghobae Sep 8, 2026
4305ff8
style(network): apply rustfmt to close frame
seonghobae Sep 8, 2026
1dcaaf8
fix(network): retain connection-bound response correlation
seonghobae Sep 8, 2026
ec16b33
fix(network): restore shared response routing
seonghobae Sep 8, 2026
bae183e
test(network): cover teardown mask-key failures
seonghobae Sep 8, 2026
f060bf1
test(network): cover peer-close mask-key failure
seonghobae Sep 8, 2026
4a7cc03
test(network): cover bounded pre-close control branch
seonghobae Sep 8, 2026
ac5cb34
test(network): cover close timeout validation
seonghobae Sep 8, 2026
2fb1b59
test(network): cover excessive close timeout
seonghobae Sep 8, 2026
a17914a
fix(network): separate frame timeout guards
seonghobae Sep 8, 2026
9033fbc
fix(network): make timeout validation exhaustive
seonghobae Sep 8, 2026
2bbdc02
fix(network): avoid timeout guard short circuit
seonghobae Sep 8, 2026
6cdf674
test(network): verify close writer deadline rejection directly
seonghobae Sep 8, 2026
7a88551
test(network): preserve exact close deadline assertions
seonghobae Sep 8, 2026
d126242
test(network): exercise complete close writer contract
seonghobae Sep 8, 2026
07ef43e
test(network): synchronize mask rejection peers
seonghobae Sep 8, 2026
f8df02e
fix(network): bound the complete closure exchange deadline
seonghobae Sep 8, 2026
292d73b
test(network): verify deadline and protocol paths together
seonghobae Sep 8, 2026
8716b9d
fix(network): reject unassigned protocol close codes
seonghobae Sep 8, 2026
383f157
fix(network): admit bounded repeated closure controls
seonghobae Sep 8, 2026
3a8e6f4
test(network): reuse arrays in repeated control fixtures
seonghobae Sep 8, 2026
10d5e1f
test(network): reject server Close 1010
seonghobae Sep 8, 2026
6b6c90e
fix(network): reject server Close 1010
seonghobae Sep 8, 2026
ce4ef71
test(network): require role-specific server Close error
seonghobae Sep 8, 2026
39f054f
fix(network): separate peer Close role error
seonghobae Sep 8, 2026
cc3bf6d
test(network): assert typed peer Close role error
seonghobae Sep 8, 2026
30b4587
fix(test): retain peer Close error for assertions
seonghobae Sep 8, 2026
9e51537
fix(test): satisfy strict clippy in Close role regression
seonghobae Sep 8, 2026
a437163
test(network): remove duplicate Close role fixture
seonghobae Sep 8, 2026
ca49031
test(network): share close-role regression with unit coverage
seonghobae Sep 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,27 @@ A skipped security, GPU, browser, TLS, or statistical test is not passing eviden
- Run reasoning-effort and orchestration-depth ablations before claiming an LLM path is superior.
- Scheduled agents may create bounded reviewed PRs but may not merge, tag, publish, alter workflows, add secrets, or weaken checks.

### Coverage diagnosis lesson

Keep generic wire-code validation separate from endpoint-role validation. For
WebSocket Close, reject server-sent client-only 1010 in the client closure state
machine before echoing it, and pair that RED case with valid server 1011 so a
blanket rejection cannot satisfy the regression.

Repeated control-frame support must preserve the total deadline and per-write masking authority. Supply a separate caller-owned key per Ping, consume none for unsolicited Pong, and keep the Close key independent. Test exact-budget success, budget overflow, exhausted keys, and reused keys with a peer that verifies no rejected reply. The 64-control budget is local resource policy, not an RFC limit.

For Close-code validation, check the current IANA registry as well as RFC 6455: the protocol-reserved range is not an allowance for unassigned values. Keep application/private ranges separate, test assigned and reserved boundaries, and verify rejected peer codes produce neither an echo nor closure evidence. Record the registry date; future assignments need a reviewed update, not ambient network lookup during frame parsing.

For a multi-step socket deadline, reproduce a sequence whose individual waits fit the limit but whose sum does not. Carry one monotonic expiry through every step and recheck before admitting final evidence. Pair real delayed-peer tests with a controlled clock at each read/write/evidence transition; a pre-I/O check alone cannot reject late completion. This is not a hard real-time host scheduling guarantee.

Aggregate LLVM code regions by source coordinates across function instantiations before identifying a missing path. An invalid-input test at a public entry point may stop at an earlier guard; it does not prove a later private writer's error return executed. Exercise that writer directly, assert the exact error, and verify the peer received no bytes. Do not rewrite production predicates based only on a file-level coverage deficit.

Coordinate union alone does not reproduce LLVM's region summary: `RegionCoverageInfo::merge` takes maximum covered/total counts across instantiations. Complementary unit-test and integration-test executions can therefore leave a deficit. Exercise successful status-bearing and empty Close writes, invalid deadlines, and adjacent masking-key rejection in the same unit-test binary; compare literal wire bytes and join the peer. Reference: LLVM Project. (n.d.). *CoverageSummaryInfo.h* [Source code]. https://github.com/llvm/llvm-project/blob/main/llvm/tools/llvm-cov/CoverageSummaryInfo.h

Inspect uncovered coordinates inside test assertions too: guarded `matches!` expressions can contribute never-taken failure branches to the file summary. Preserve exact variant and field checks rather than broadening the accepted error to make coverage pass.

Mask-reuse socket tests must consume the preceding text/Pong frame before sending the frame that triggers rejection. Assert the exact reuse error, literal preceding bytes, and EOF with no rejected response; propagate peer thread errors. A broad transport-error assertion plus an ignored join can pass because the peer rejected the fixture's own wrong opcode. An intervening fresh-key Pong also changes the adjacent-key history, so an older text key does not test adjacent Close-key reuse.

## Release contract

A release requires all current-head checks, complete coverage and docs, updated `CHANGELOG.md`, SBOM and provenance, reproducible artifacts, compatibility evidence, security review, and an explicit version decision. Pre-alpha commits are not releases.
23 changes: 23 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,34 @@ All notable changes to OriginWeave are documented in this file. The format follo

## [Unreleased]

### Changed

- Browser transport shutdown rejects the client-only Close status 1010 when received from a server, before sending a reply or recording completion; server status 1011 remains supported.

- Browser transport shutdown now handles repeated keepalive traffic within one time budget, using a separate supplied key for each reply and rejecting exhausted keys or excess traffic without reporting completion.

- Browser transport shutdown rejects unassigned protocol close codes before replying or recording completion; application and private-use code ranges remain supported.

- Browser transport shutdown now shares one time budget across control replies and final connection closure; late closure cannot become successful completion evidence.

- Restored the simple frame-timeout validation after correcting coverage diagnosis; direct Close-writer tests verify invalid deadlines send no bytes and return the expected error.
- Kept exact invalid-deadline error checks without compound test-only guards in the coverage measurement.
- Verified literal masked Close bytes with and without a status code, and that a reused masking key emits no Close bytes after the preceding text frame.
- Corrected three masking-rejection test peers so unrelated socket errors cannot masquerade as key-reuse protection; each now verifies the preceding frame, the exact rejection, and no subsequent bytes.

- Removed an unused private correlated-response accessor while retaining connection-generation validation at the receiving-message boundary, and corrected the Rust `AtomicU64` standard-library reference to its canonical type-alias page.
- Integrated the current teardown prerequisites into transport-closure observation, including the previously uncollected release-record check, while retaining the unresolved connection-provenance finding and its downstream repair ownership.
- Integrated the verified opening-exchange and closure prerequisites into the connection-bound response repair, preserving its sender, receiver and closure provenance checks while restoring the inherited executable release contract; process and profile cleanup remain unproven.

### Added

- Session-ending replies from a replacement connection can no longer complete the original pending request. The original reply remains usable, and a protocol acknowledgment still does not prove browser shutdown or cleanup.
- The session-ending command stack now retains the status-reply protections from its current parent. A reply from a replacement connection is rejected while the original pending status request remains recoverable; sending the end command still does not prove that the browser session ended.
- Typed outbound WebDriver BiDi `session.end` over the bounded client WebSocket stream: it serializes only the standards-defined method with empty params, rejects invalid frame deadlines before correlation registration, retires only the just-registered id when frame preflight proves no command bytes were emitted, preserves exact command-kind correlation across ambiguous writes, and does not treat frame-write success as proof that the browser session ended.
- Typed `session.end` response admission that consumes only the exact outstanding command-kind correlation after complete envelope validation, preserves remote protocol errors as failures, and does not claim browser-process exit or resource cleanup from a protocol acknowledgment.
- Fail-closed `session.end` teardown assessment that binds only the typed observation produced by consuming the exact transport, keeps browser-process-exit and task-profile-removal evidence unavailable until their runtime owners exist, and therefore cannot report operational completion from caller-supplied booleans.
- Bounded WebDriver BiDi transport-closure observation that consumes the established stream, accepts only a validated peer Close frame or clean pre-frame EOF, permits at most one unsolicited Pong, and keeps transport closure separate from process-exit and profile-cleanup claims.

- Regression checks now exercise fragmented browser replies, interleaved control messages, and rejected replies without losing a pending request. These checks do not establish browser readiness or release acceptance.
- The typed browser-status response stack now includes its verified command and opening-exchange prerequisites, including the release-record check that previously did not execute; parsing remains bounded and does not grant browser authority or prove operational readiness.
- Bounded RFC 6455 WebDriver BiDi opening-response validation on the exact peer-verified stream: it admits only HTTP/1.1 `101`, case-insensitive `Upgrade`/`Connection` tokens, and the client-key-correlated `Sec-WebSocket-Accept` value within monotonic time and header-size ceilings; it restores blocking mode and still does not implement WebSocket frames or grant browser/Agent authority.
Expand Down Expand Up @@ -62,6 +84,7 @@ All notable changes to OriginWeave are documented in this file. The format follo

### Changed

- Carried current response prerequisites and the executable release-record check into the teardown-assessment stack; caller-supplied cleanup claims remain unverified and cannot establish operational acceptance.
- Carried verified command prerequisites and the executable release-record check into session-end response validation without changing response admission or treating an acknowledgment as proof of resource cleanup.
- Carried the verified status-response prerequisites into the session-end sender, preserving its command behavior and making the inherited release-record check execute in the existing test suite.
- Kept the `session.status` frame-failure coverage contract focused on observable correlation state, avoiding assertion-internal uncovered branches without weakening preflight retirement or ambiguous-write retention checks.
Expand Down
30 changes: 26 additions & 4 deletions crates/originweave-network/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@
//! `originweave-core` into one bounded exact TCP connection, binds and validates
//! the RFC 6455 opening exchange, provides bounded masked client writes and
//! unmasked server-frame reads, assembles bounded WebDriver BiDi text messages,
//! classifies complete local-end JSON envelopes, tracks bounded command-response
//! correlation, sends narrowly typed `session.status` and `session.end` commands,
//! and admits typed correlated status and end responses without exposing generic
//! JSON bodies or granting browser, TLS, policy, secret, or Agent authority.
//! binds received fragmented text to one exact verified connection, classifies
//! complete local-end JSON envelopes, tracks bounded command-response correlation,
//! sends narrowly typed `session.status` and `session.end` commands, admits typed
//! correlated status and end responses, binds `session.end` ACK and closure evidence
//! to one private process-local connection generation, observes bounded peer Close
//! or clean-EOF transport cessation, and keeps protocol/transport evidence separate
//! from explicit operational teardown observations without exposing generic JSON
//! bodies or granting browser, TLS, policy, secret, process, profile, or Agent authority.

#![forbid(unsafe_code)]
#![deny(missing_docs)]
Expand All @@ -24,14 +28,24 @@ mod webdriver_bidi_session_end_command;
mod webdriver_bidi_session_end_response;
mod webdriver_bidi_session_status_command;
mod webdriver_bidi_session_status_response;
mod webdriver_bidi_session_teardown;
mod webdriver_bidi_websocket_frame;
mod webdriver_bidi_websocket_handshake;
mod webdriver_bidi_websocket_message;
mod webdriver_bidi_websocket_opening_recovery;
mod webdriver_bidi_websocket_transport_closure;

#[cfg(test)]
mod webdriver_bidi_json_envelope_public_boundary_tests;

// LLVM coverage keeps the crate unit-test instantiation separate from integration-test binaries,
// so compile the same realistic 1010/1011 loopback contract here instead of maintaining a copy.
#[cfg(test)]
extern crate self as originweave_network;
#[cfg(test)]
#[path = "../tests/webdriver_bidi_transport_close_role_validation.rs"]
mod webdriver_bidi_transport_close_role_validation_unit;

pub use connection::{
ConnectionPlan, DirectTcpConnection, MAX_CONNECT_TIMEOUT, MAX_CONNECTION_ATTEMPTS,
NetworkError, SocketConnectionEvidence,
Expand Down Expand Up @@ -67,6 +81,10 @@ pub use webdriver_bidi_session_status_response::{
MAX_WEBDRIVER_BIDI_SESSION_STATUS_MESSAGE_SIZE, WebDriverBiDiSessionStatusResponseError,
WebDriverBiDiSessionStatusResult,
};
pub use webdriver_bidi_session_teardown::{
WebDriverBiDiSessionTeardownAssessment, WebDriverBiDiSessionTeardownAssessmentError,
WebDriverBiDiSessionTeardownDisposition, WebDriverBiDiSessionTeardownObservations,
};
pub use webdriver_bidi_websocket_frame::{
MAX_WEBSOCKET_FRAME_PAYLOAD_SIZE, MAX_WEBSOCKET_FRAME_TIMEOUT,
WebDriverBiDiWebSocketEstablished, WebDriverBiDiWebSocketFrame,
Expand All @@ -86,3 +104,7 @@ pub use webdriver_bidi_websocket_message::{
WebDriverBiDiWebSocketTextMessage,
};
pub use webdriver_bidi_websocket_opening_recovery::WebDriverBiDiWebSocketOpeningWriteRecoveryDisposition;
pub use webdriver_bidi_websocket_transport_closure::{
WebDriverBiDiWebSocketTransportClosureError, WebDriverBiDiWebSocketTransportClosureKind,
WebDriverBiDiWebSocketTransportClosureObservation,
};
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,25 @@ struct OutstandingCommand {
connection_generation: Option<WebDriverBiDiConnectionGeneration>,
}

fn response_route(
envelope: &WebDriverBiDiJsonEnvelope,
) -> Result<(u64, WebDriverBiDiCorrelatedResponseOutcome), WebDriverBiDiCommandCorrelationError> {
match envelope.routing() {
WebDriverBiDiJsonEnvelopeRouting::Event => {
Err(WebDriverBiDiCommandCorrelationError::EventIsNotResponse)
}
WebDriverBiDiJsonEnvelopeRouting::CommandError { command_id: None } => {
Err(WebDriverBiDiCommandCorrelationError::UncorrelatableErrorResponse)
}
WebDriverBiDiJsonEnvelopeRouting::CommandError {
command_id: Some(command_id),
} => Ok((command_id, WebDriverBiDiCorrelatedResponseOutcome::Error)),
WebDriverBiDiJsonEnvelopeRouting::CommandSuccess { command_id } => {
Ok((command_id, WebDriverBiDiCorrelatedResponseOutcome::Success))
}
}
}

/// Outcome of a response after it has consumed the matching outstanding command identifier.
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
pub enum WebDriverBiDiCorrelatedResponseOutcome {
Expand Down Expand Up @@ -239,8 +258,26 @@ impl WebDriverBiDiCommandCorrelation {
envelope: &WebDriverBiDiJsonEnvelope,
expected_kind: WebDriverBiDiCommandKind,
) -> Result<WebDriverBiDiCorrelatedResponse, WebDriverBiDiCommandCorrelationError> {
let (command_id, outcome) = response_route(envelope)?;
self.complete(command_id, expected_kind, outcome)
match envelope.routing() {
WebDriverBiDiJsonEnvelopeRouting::Event => {
Err(WebDriverBiDiCommandCorrelationError::EventIsNotResponse)
}
WebDriverBiDiJsonEnvelopeRouting::CommandError { command_id: None } => {
Err(WebDriverBiDiCommandCorrelationError::UncorrelatableErrorResponse)
}
WebDriverBiDiJsonEnvelopeRouting::CommandError {
command_id: Some(command_id),
} => self.complete(
command_id,
expected_kind,
WebDriverBiDiCorrelatedResponseOutcome::Error,
),
WebDriverBiDiJsonEnvelopeRouting::CommandSuccess { command_id } => self.complete(
command_id,
expected_kind,
WebDriverBiDiCorrelatedResponseOutcome::Success,
),
}
}

pub(crate) fn correlate_response_for_connection(
Expand Down Expand Up @@ -317,25 +354,6 @@ impl WebDriverBiDiCommandCorrelation {
}
}

fn response_route(
envelope: &WebDriverBiDiJsonEnvelope,
) -> Result<(u64, WebDriverBiDiCorrelatedResponseOutcome), WebDriverBiDiCommandCorrelationError> {
match envelope.routing() {
WebDriverBiDiJsonEnvelopeRouting::Event => {
Err(WebDriverBiDiCommandCorrelationError::EventIsNotResponse)
}
WebDriverBiDiJsonEnvelopeRouting::CommandError { command_id: None } => {
Err(WebDriverBiDiCommandCorrelationError::UncorrelatableErrorResponse)
}
WebDriverBiDiJsonEnvelopeRouting::CommandError {
command_id: Some(command_id),
} => Ok((command_id, WebDriverBiDiCorrelatedResponseOutcome::Error)),
WebDriverBiDiJsonEnvelopeRouting::CommandSuccess { command_id } => {
Ok((command_id, WebDriverBiDiCorrelatedResponseOutcome::Success))
}
}
}

#[cfg(test)]
mod tests {
use super::{WebDriverBiDiCommandCorrelationError, WebDriverBiDiCommandKind};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ impl WebDriverBiDiSessionEndCommand {
/// Register and write this exact command on an already established verified BiDi stream.
///
/// Locally invalid frame deadlines fail before correlation registration and before any remote
/// side effect. Correlation then binds the command to this connection before the first possible
/// frame write. Only a reply received on this same connection can complete that registration.
/// A frame-owner preflight rejection that proves no write began retires this exact command
/// again. Once frame emission can have begun, a later failure leaves the identifier outstanding
/// because partial or full emission is ambiguous. A successful write also leaves the identifier
/// outstanding until a later correlated response proves completion.
/// side effect. Correlation then binds the command id and command family to the private
/// process-local generation of this exact established connection before the first possible
/// frame write. A frame-owner preflight rejection that proves no write began retires this exact
/// command again. Once frame emission can have begun, a later failure leaves the identifier
/// outstanding because partial or full emission is ambiguous. A successful write also leaves
/// the identifier outstanding until a later correlated response proves completion.
pub fn send(
self,
established: WebDriverBiDiWebSocketEstablished,
Expand All @@ -62,11 +62,12 @@ impl WebDriverBiDiSessionEndCommand {
},
});
}
let connection_generation = established.transport_evidence().connection_generation();
correlation
.register_command_for_connection(
self.command_id,
WebDriverBiDiCommandKind::SessionEnd,
established.transport_evidence().connection_generation(),
connection_generation,
)
.map_err(|source| WebDriverBiDiSessionEndCommandError::Correlation { source })?;
let message = self.serialized();
Expand Down
Loading
Loading