Skip to content

[adr] Behavioral contract for the low-level WebDriver BiDi layer#17786

Open
titusfortner wants to merge 7 commits into
SeleniumHQ:trunkfrom
titusfortner:adr-bidi-low-level-contract
Open

[adr] Behavioral contract for the low-level WebDriver BiDi layer#17786
titusfortner wants to merge 7 commits into
SeleniumHQ:trunkfrom
titusfortner:adr-bidi-low-level-contract

Conversation

@titusfortner

@titusfortner titusfortner commented Jul 15, 2026

Copy link
Copy Markdown
Member

📄 The decision, its rationale, considered options, and consequences are in the record file
this PR adds; read it there. The sections below are proposal notes and review logistics.

🔗 Related

📝 Proposal notes

  • Why this record. The low-level BiDi layer is being built across several bindings (see references)
    and drifts on wire-observable behavior without a shared contract. This record fixes that behavior
    once, so every binding is held to the same bar and a review can cite one place instead of re-deciding.
  • Out of scope by design: how conformance is verified (tests/suites), the production method
    (generation is one way to satisfy the contract, not a requirement), the checked-in-vs-build-time
    generation choice, and per-binding adoption. The record fixes behavior only.
  • What's actually decided. Only 4 of the 12 behaviors are spec-forced (Compliance); the other 8 are
    Decisions this record owns — a strict, typed, validated design the spec permits but does not compel, so
    review should focus there. Exactly one Decision turns on the internal-implementation premise: scoping
    preserved extras tightly (item 8), affordable because an internal layer can widen later at no cost. The
    rest — local outbound validation (3), strict-by-default inbound with reactive cross-binding relaxation
    (6, 9), extensibility off the spec's per-type signal (4), typed and read-only objects (11, 12),
    spec-mirroring names (10) — stand on their own merits, not on the premise.

📊 Conformance snapshot (point-in-time)

Measured against seven existing implementations of this layer. Columns — independent: net, wdio.
Selenium on trunk: rb (generated, merged in #17731),
py trunk, .NET (hand-written). In-flight PRs:
py 17761 (#17761),
java 17777 (#17777). A snapshot only — it changes
as bindings converge, and moves to the tracking issue on acceptance.

Legend: ✅ meets it · ❌ does not (includes partial) · ①–② diverges by a deliberate design choice
(numbered below), not a defect.

# Behavior net wdio rb py trunk .NET py 17761 java 17777
1 Verbatim wire token
2 Omit ≠ null
3 Outbound validated
4 Per-type extensibility
5 Variant/vocabulary resolution
6 Field strictness
7 Unknown properties tolerated
8 Extras scoped to re-sendable
9 Reactive relaxation
10 Names mirror spec
11 Typed, not raw maps
12 Read-only to callers

net = webdriverbidi-net · wdio = WebdriverIO

Lenient inbound parsing (wdio). WebdriverIO tolerates off-spec responses rather than raising —
reasonable for a public library facing a churning spec. This record raises instead, on merit rather than
because it is internal: a clear error beats silently misrepresenting the response. Note that net, also
public, is strict here (✅ on 5, 6, 9) — so strictness is a design choice, not a public-vs-internal one.

Broad extras handling (net, wdio). Both public implementations keep unknown fields broadly, so they
never silently drop a vendor field a user relies on — the right call for a surface that can't narrow
later. This record scopes tightly because the layer is internal and can widen later at no cost. This is
the one decision that actually turns on internal-vs-public.
(net stores extras broadly; wdio doesn't
build a store at all — same root, different degree.)

How to read it

  • Selenium's bindings have no latitude to diverge deliberately (they share the internal premise), so a ❌ is a gap against this new contract — to be closed as each binding adopts it — not a defensible alternative choice. Some ❌s are old designs predating the contract (py trunk's raw dicts, .NET's leniency); the in-flight generated bindings (rb, py 17761) close most of theirs with one shared-schema fix.
  • The two independent implementations diverge in exactly two places, and only one is about being public. On extras breadth (②) both net and wdio go broad — the genuine internal-vs-public decision (a public surface can't narrow later; an internal one can). On inbound strictness (①) only wdio is lenient; net, also public, is strict — so strictness is a per-implementation design choice, not a public-vs-internal split.
  • A non-numbered ❌ in an independent implementation is an ordinary gap, not a deliberate difference — WebdriverIO on read-only, for example.
  • ❌ can mean "close," not "absent": rb and py 17761 on Detect Windows 8 in Platform #5 pass every sub-behavior except the object-only-union rejection; java 17777 on Added the new "requireWindowFocus" capability to CapabilityType. #6 raises on missing-required and null-in-non-nullable, lenient only on wrong-primitive-type.

🗣 Discussion

Notes from Slack and TLC minutes are recorded here as the proposal is discussed.

📌 Tracking

Tracking issue: (linked on acceptance)

@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Add ADR defining behavioral contract for low-level WebDriver BiDi layer

📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Add an ADR that standardizes wire-observable behaviors for the BiDi low-level layer.
• Distinguish spec-mandated compliance rules from binding-owned design decisions.
• Document rationale, rejected alternatives, and consequences to align all bindings.
Diagram

graph TD
  E["High-level API"] --> B["Low-level BiDi layer"]
  A["BiDi Spec (CDDL)"] --> B["Low-level BiDi layer"] --> C["Transport"] --> D["Remote end"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Mandate code generation as the contract mechanism
  • ➕ Can reduce per-binding implementation divergence by centralizing production
  • ➕ Potentially lowers ongoing maintenance for typed models
  • ➖ Does not guarantee runtime behaviors (validation/strictness/immutability) without additional rules
  • ➖ Imposes tooling and workflow constraints that may not fit every binding
2. Define a conformance test suite as the primary artifact
  • ➕ Makes the contract executable and objectively verifiable across bindings
  • ➕ Encodes edge cases precisely (e.g., nullability, union resolution, strictness relaxations)
  • ➖ Harder to review and discuss design intent without a written rationale
  • ➖ Still needs a normative written source for why tests exist and what’s intentional vs. incidental
3. Publish the contract as binding-specific guidelines instead of one ADR
  • ➕ Lets each binding tailor wording and examples to its language/runtime
  • ➕ May reduce friction for teams with different idioms
  • ➖ Reintroduces drift risk and repeated re-litigation of decisions across bindings
  • ➖ Makes cross-binding review and enforcement significantly harder

Recommendation: Keep the ADR as the single binding-neutral normative source of behavioral requirements (as this PR does). Consider following up with a shared conformance suite that directly exercises the ADR’s decision points (strict inbound validation, extensibility handling, extras preservation scope) to make adherence measurable without making generation or tooling a requirement.

Files changed (1) +188 / -0

Documentation (1) +188 / -0
nnnnn-bidi-low-level-behavioral-contract.mdAdd ADR specifying low-level BiDi behavioral contract +188/-0

Add ADR specifying low-level BiDi behavioral contract

• Introduces a proposed architecture decision record defining a binding-neutral behavioral contract for the low-level WebDriver BiDi layer. The document enumerates compliance vs. binding-owned decisions across outbound, inbound, extensibility, and surface design, and records considered alternatives and consequences.

docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md

@qodo-code-review

qodo-code-review Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Placeholder ADR number ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
The new ADR is added with placeholder ID "NNNNN" in both the filename and document heading and uses
"Discussion: _PR pending_" instead of a PR link, which violates the documented ADR numbering/linking
rules and harms traceability for future citations.
Code

docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md[R1-5]

+# NNNNN. Behavioral contract for the low-level WebDriver BiDi layer
+
+- Status: Proposed
+- Discussion: _PR pending_
+
Evidence
The ADR process documentation in this repo requires decision records to be numbered by the proposing
PR number and renamed before merge, and the template indicates the number should be the PR number
and the discussion field should link to the PR. The newly added ADR still contains placeholders
instead.

docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md[1-5]
docs/decisions/README.md[3-5]
docs/decisions/README.md[42-45]
docs/decisions/README.md[90-91]
docs/decisions/0000-template.md[1-8]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The ADR record is still using placeholders (`nnnnn-...` filename, `# NNNNN.` header, and `Discussion: _PR pending_`). The `docs/decisions` README defines ADR numbering as the proposing PR number and requires renaming before merge, and the template expects the discussion field to link to the PR.

## Issue Context
If merged with placeholders, this record will be harder to cite consistently and will not follow the project’s documented decision-record process.

## Fix Focus Areas
- docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md[1-5]
- docs/decisions/README.md[42-45]

## Proposed fix
1. Rename `docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md` to `<PR_NUMBER>-bidi-low-level-behavioral-contract.md`.
2. Update the first heading to `# <PR_NUMBER>. Behavioral contract for the low-level WebDriver BiDi layer`.
3. Replace `Discussion: _PR pending_` with a link to this PR (and optionally additional relevant threads under Context, per the template).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Ambiguous const/null example 🐞 Bug ⚙ Maintainability ⭐ New
Description
In item 3, the parenthetical example “a true/null field rejects false” is mildly ambiguous
shorthand and can read like a generic boolean-validation example rather than explicitly “allowed set
is {literal, null}” for nullable constants. Tightening this wording would make the intended rule (as
defined in item 2) unambiguous for adopters implementing outbound validation.
Code

docs/decisions/17786-bidi-low-level-behavioral-contract.md[R63-64]

+   as does a value neither the literal nor `null` for a nullable constant (a `true`/`null` field rejects
+   `false`; see item 2). A static
Evidence
Item 3’s example uses the true/null shorthand while item 2 is where the contract precisely
defines nullable-constant behavior (“literal or null”). Making item 3’s example explicitly reflect
that membership rule removes the ambiguity.

docs/decisions/17786-bidi-low-level-behavioral-contract.md[59-65]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[50-57]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The example in item 3 uses shorthand (“`true`/`null` field rejects `false`”) that can be read as a general boolean-type validation example, instead of explicitly conveying the nullable-constant membership rule.

### Issue Context
Item 2 already defines the rule for nullable constants (“send the literal or `null`”), and item 3 is illustrating that outbound validation should reject anything outside that allowed set.

### Fix Focus Areas
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[59-64]

### Suggested edit
Replace the parenthetical with wording that explicitly states the allowed set, e.g.
- "… (e.g., for a nullable constant whose literal is `true`, the only valid values are `true` and `null`; `false` must be rejected; see item 2)."

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Mis-cited extras rules ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
The ADR cites item 7 when describing closed types “accepts-but-ignores” unknown inbound properties
and when saying other types “tolerates and drops”, but item 7 only requires that unknown inbound
properties must not error while the preserve/drop rules are defined by item 8. This can mislead
adopters into treating “drop/ignore” as part of Compliance (item 7) rather than a Decision scoped by
item 8, increasing the risk of divergent extras handling across bindings.
Code

docs/decisions/17786-bidi-low-level-behavioral-contract.md[R74-75]

+   while a closed type rejects unknown properties outbound (item 3) and accepts-but-ignores them inbound
+   (item 7). The one prohibition is never injecting arbitrary properties into a *closed* type, which would
Evidence
Item 7 defines only that unknown inbound properties must not cause an error, while item 8 defines
when extras are preserved vs dropped; the changed lines cite item 7 in contexts that describe
ignore/drop behavior.

docs/decisions/17786-bidi-low-level-behavioral-contract.md[74-75]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[96-98]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[100-103]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[113-113]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The ADR cross-references **item 7** (“Unknown inbound properties never cause an error”) in places where the text is actually describing **whether unknown properties are ignored/dropped vs preserved**, which is governed by **item 8** (“Preserving extras is scoped…”).

### Issue Context
- Item 7 is the *tolerance/no-error* rule.
- Item 8 is the *preserve vs drop* scoping rule.

### Fix Focus Areas
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[69-78]
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[109-114]

### Suggested edit direction
- In item 4, change the parenthetical so it distinguishes tolerance (item 7) from preservation/drop behavior (item 8), e.g. “...tolerates unknown inbound properties (item 7) and drops them unless scoped for preservation (item 8).”
- In item 8, change “tolerates and drops (item 7)” to reference item 8 (or “item 7 for tolerance; item 8 for drop/preserve scope”).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Ambiguous section reference 🐞 Bug ⚙ Maintainability
Description
The Decision intro says “the next section marks which is which,” but the Compliance/Decision labels
are applied inline on each numbered behavior and the next section primarily explains the tagging
scheme. This is a minor ambiguity that can be fixed by rephrasing the sentence to refer to the items
below being tagged (or the next section explaining the tags).
Code

docs/decisions/17786-bidi-low-level-behavioral-contract.md[R18-20]

+**Any implementation of this layer must exhibit the behaviors below.** Some follow from conforming to the
+WebDriver BiDi specification; the rest are choices this record standardizes so bindings don't diverge —
+the next section marks which is which.
Evidence
Lines 18–20 claim the “next section marks which is which,” while the subsequent “How to read”
section defines the tiers and the actual tier markers appear inline on the numbered behaviors (e.g.,
item 1 includes “*(Compliance.)*”).

docs/decisions/17786-bidi-low-level-behavioral-contract.md[18-20]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[28-36]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[46-48]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Decision intro refers to “the next section” as doing the marking, but the Compliance/Decision markers are attached inline to each numbered item; the following section mainly explains what those tags mean.

### Issue Context
This is a minor clarity/readability fix to align the intro text with the structure readers see.

### Fix Focus Areas
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[18-20]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Previous review results

Review updated until commit 412d9f2

Results up to commit 613cd02


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Remediation recommended
1. Placeholder ADR number ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
The new ADR is added with placeholder ID "NNNNN" in both the filename and document heading and uses
"Discussion: _PR pending_" instead of a PR link, which violates the documented ADR numbering/linking
rules and harms traceability for future citations.
Code

docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md[R1-5]

+# NNNNN. Behavioral contract for the low-level WebDriver BiDi layer
+
+- Status: Proposed
+- Discussion: _PR pending_
+
Evidence
The ADR process documentation in this repo requires decision records to be numbered by the proposing
PR number and renamed before merge, and the template indicates the number should be the PR number
and the discussion field should link to the PR. The newly added ADR still contains placeholders
instead.

docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md[1-5]
docs/decisions/README.md[3-5]
docs/decisions/README.md[42-45]
docs/decisions/README.md[90-91]
docs/decisions/0000-template.md[1-8]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The ADR record is still using placeholders (`nnnnn-...` filename, `# NNNNN.` header, and `Discussion: _PR pending_`). The `docs/decisions` README defines ADR numbering as the proposing PR number and requires renaming before merge, and the template expects the discussion field to link to the PR.

## Issue Context
If merged with placeholders, this record will be harder to cite consistently and will not follow the project’s documented decision-record process.

## Fix Focus Areas
- docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md[1-5]
- docs/decisions/README.md[42-45]

## Proposed fix
1. Rename `docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md` to `<PR_NUMBER>-bidi-low-level-behavioral-contract.md`.
2. Update the first heading to `# <PR_NUMBER>. Behavioral contract for the low-level WebDriver BiDi layer`.
3. Replace `Discussion: _PR pending_` with a link to this PR (and optionally additional relevant threads under Context, per the template).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit dfe1c07


🐞 Bugs (1) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Informational
1. Ambiguous section reference 🐞 Bug ⚙ Maintainability
Description
The Decision intro says “the next section marks which is which,” but the Compliance/Decision labels
are applied inline on each numbered behavior and the next section primarily explains the tagging
scheme. This is a minor ambiguity that can be fixed by rephrasing the sentence to refer to the items
below being tagged (or the next section explaining the tags).
Code

docs/decisions/17786-bidi-low-level-behavioral-contract.md[R18-20]

+**Any implementation of this layer must exhibit the behaviors below.** Some follow from conforming to the
+WebDriver BiDi specification; the rest are choices this record standardizes so bindings don't diverge —
+the next section marks which is which.
Evidence
Lines 18–20 claim the “next section marks which is which,” while the subsequent “How to read”
section defines the tiers and the actual tier markers appear inline on the numbered behaviors (e.g.,
item 1 includes “*(Compliance.)*”).

docs/decisions/17786-bidi-low-level-behavioral-contract.md[18-20]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[28-36]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[46-48]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The Decision intro refers to “the next section” as doing the marking, but the Compliance/Decision markers are attached inline to each numbered item; the following section mainly explains what those tags mean.

### Issue Context
This is a minor clarity/readability fix to align the intro text with the structure readers see.

### Fix Focus Areas
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[18-20]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 5b77f31


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Informational
1. Mis-cited extras rules ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
The ADR cites item 7 when describing closed types “accepts-but-ignores” unknown inbound properties
and when saying other types “tolerates and drops”, but item 7 only requires that unknown inbound
properties must not error while the preserve/drop rules are defined by item 8. This can mislead
adopters into treating “drop/ignore” as part of Compliance (item 7) rather than a Decision scoped by
item 8, increasing the risk of divergent extras handling across bindings.
Code

docs/decisions/17786-bidi-low-level-behavioral-contract.md[R74-75]

+   while a closed type rejects unknown properties outbound (item 3) and accepts-but-ignores them inbound
+   (item 7). The one prohibition is never injecting arbitrary properties into a *closed* type, which would
Evidence
Item 7 defines only that unknown inbound properties must not cause an error, while item 8 defines
when extras are preserved vs dropped; the changed lines cite item 7 in contexts that describe
ignore/drop behavior.

docs/decisions/17786-bidi-low-level-behavioral-contract.md[74-75]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[96-98]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[100-103]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[113-113]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The ADR cross-references **item 7** (“Unknown inbound properties never cause an error”) in places where the text is actually describing **whether unknown properties are ignored/dropped vs preserved**, which is governed by **item 8** (“Preserving extras is scoped…”).

### Issue Context
- Item 7 is the *tolerance/no-error* rule.
- Item 8 is the *preserve vs drop* scoping rule.

### Fix Focus Areas
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[69-78]
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[109-114]

### Suggested edit direction
- In item 4, change the parenthetical so it distinguishes tolerance (item 7) from preservation/drop behavior (item 8), e.g. “...tolerates unknown inbound properties (item 7) and drops them unless scoped for preservation (item 8).”
- In item 8, change “tolerates and drops (item 7)” to reference item 8 (or “item 7 for tolerance; item 8 for drop/preserve scope”).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Qodo Logo

Comment thread docs/decisions/nnnnn-bidi-low-level-behavioral-contract.md Outdated
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 98e1858

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new ADR to the cross-binding decision log that defines a behavioral contract for Selenium’s internal, low-level WebDriver BiDi protocol layer (validation, extensibility, parsing strictness, and surface shape), intended to keep binding implementations aligned on wire-observable behavior.

Changes:

  • Introduces a decision record enumerating required outbound/inbound behaviors for the BiDi low-level layer.
  • Defines a two-tier taxonomy (Compliance vs Decision) to separate spec-forced requirements from Selenium-standardized choices.
  • Records rationale, alternatives, and consequences to support consistent adoption across bindings.

Comment thread docs/decisions/17786-bidi-low-level-behavioral-contract.md Outdated
Comment thread docs/decisions/17786-bidi-low-level-behavioral-contract.md Outdated
Comment thread docs/decisions/17786-bidi-low-level-behavioral-contract.md
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit dfe1c07

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 1 comment.

Comment thread docs/decisions/17786-bidi-low-level-behavioral-contract.md Outdated
Comment thread docs/decisions/17786-bidi-low-level-behavioral-contract.md Outdated
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 5b77f31

Comment thread docs/decisions/17786-bidi-low-level-behavioral-contract.md
@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit e965829

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code review by qodo was updated up to the latest commit 1b0e91a

@qodo-code-review

qodo-code-review Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Undefined error-code surfacing 🐞 Bug ⚙ Maintainability
Description
Item 9 requires unknown ErrorResponse enum tokens to be “surfaced, not thrown” but does not define
the minimum observable semantics (e.g., raw-token preservation and how callers access it), which can
lead to divergent binding behavior despite the ADR’s stated goal of uniform wire-observable
behavior.
Code

docs/decisions/17786-bidi-low-level-behavioral-contract.md[R127-130]

+   applied to every binding at once — never one alone, and never by starting lenient. One exception is
+   sanctioned from the start: an enum that reports an error (an unrecognized error code in an
+   `ErrorResponse`), where raising would swallow the error being reported; there, an unknown token is
+   surfaced, not thrown.
Evidence
The ADR states its purpose is to standardize wire-observable behavior across bindings; leaving
“surfaced” undefined for unknown error codes reintroduces the same cross-binding drift risk the ADR
is meant to eliminate.

docs/decisions/17786-bidi-low-level-behavioral-contract.md[13-15]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[18-20]
docs/decisions/17786-bidi-low-level-behavioral-contract.md[122-130]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
Item 9 says an unknown `ErrorResponse` error-code token must be “surfaced, not thrown”, but that leaves implementers room to diverge on what is required (whether the raw token is preserved verbatim, and what shape it takes when exposed to callers).

### Issue Context
This ADR is explicitly intended to prevent cross-binding drift on wire-observable behavior; underspecified requirements defeat that goal.

### Fix Focus Areas
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[122-130]

### Suggested change (one possible wording)
Amend item 9 to define the binding-neutral minimum:
- parsing must not throw on unknown `ErrorResponse` code tokens
- the exact raw wire token must be preserved verbatim
- callers must be able to retrieve that raw token (via an idiomatic “unknown/other” representation)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Broken Consequences sentence 🐞 Bug ⚙ Maintainability
Description
The final Consequences bullet ends with an ungrammatical fragment (“the items that signal feeds”),
which reduces clarity for future readers quoting or implementing the summary.
Code

docs/decisions/17786-bidi-low-level-behavioral-contract.md[R189-190]

+- The per-type signals items 5/6/8 need are all derivable from the spec; a binding that discards one, or
+  parses into a lenient runtime, falls out of conformance on exactly the items that signal feeds.
Evidence
The typo is present in the final bullet of the ADR’s Consequences section.

docs/decisions/17786-bidi-low-level-behavioral-contract.md[185-190]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The last sentence in Consequences is grammatically incorrect (“the items that signal feeds”), making the summary unclear.

### Issue Context
This is the concluding summary statement and is likely to be quoted in reviews.

### Fix Focus Areas
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[189-190]

### Suggested change
Rewrite to something like:
- “...falls out of conformance on exactly the items those signals feed.”
 or
- “...falls out of conformance on exactly items 5, 6, or 8.”

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

misrepresenting the response, and it is cheaper to loosen a strict contract than to tighten a lenient
one. When a real remote end is seen sending off-spec data, the specific field or command is relaxed
through a documented, reversible change (citing the offending implementation and the spec issue),
applied to every binding at once — never one alone, and never by starting lenient. One exception is

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remediation recommended

1. Undefined error-code surfacing 🐞 Bug ⚙ Maintainability

Item 9 requires unknown ErrorResponse enum tokens to be “surfaced, not thrown” but does not define
the minimum observable semantics (e.g., raw-token preservation and how callers access it), which can
lead to divergent binding behavior despite the ADR’s stated goal of uniform wire-observable
behavior.
Agent Prompt
### Issue description
Item 9 says an unknown `ErrorResponse` error-code token must be “surfaced, not thrown”, but that leaves implementers room to diverge on what is required (whether the raw token is preserved verbatim, and what shape it takes when exposed to callers).

### Issue Context
This ADR is explicitly intended to prevent cross-binding drift on wire-observable behavior; underspecified requirements defeat that goal.

### Fix Focus Areas
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[122-130]

### Suggested change (one possible wording)
Amend item 9 to define the binding-neutral minimum:
- parsing must not throw on unknown `ErrorResponse` code tokens
- the exact raw wire token must be preserved verbatim
- callers must be able to retrieve that raw token (via an idiomatic “unknown/other” representation)

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


- The contract holds for any implementation regardless of language or production method; conformance is
checkable independently of how the layer was built.
- The per-type signals items 5/6/8 need are all derivable from the spec; a binding that discards one, or

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Informational

2. Broken consequences sentence 🐞 Bug ⚙ Maintainability

The final Consequences bullet ends with an ungrammatical fragment (“the items that signal feeds”),
which reduces clarity for future readers quoting or implementing the summary.
Agent Prompt
### Issue description
The last sentence in Consequences is grammatically incorrect (“the items that signal feeds”), making the summary unclear.

### Issue Context
This is the concluding summary statement and is likely to be quoted in reviews.

### Fix Focus Areas
- docs/decisions/17786-bidi-low-level-behavioral-contract.md[189-190]

### Suggested change
Rewrite to something like:
- “...falls out of conformance on exactly the items those signals feed.”
  or
- “...falls out of conformance on exactly items 5, 6, or 8.”

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

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

Labels

A-needs decision TLC needs to discuss and agree

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants