Skip to content

docs(adr): network adapter stack design (ADR-0029–0031)#56

Merged
NotAProfDev merged 2 commits into
mainfrom
docs/adr-network-adapter-stack
Jun 28, 2026
Merged

docs(adr): network adapter stack design (ADR-0029–0031)#56
NotAProfDev merged 2 commits into
mainfrom
docs/adr-network-adapter-stack

Conversation

@NotAProfDev

@NotAProfDev NotAProfDev commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Captures the request/reply (HTTP) net-stack design for the first Broker — IBKR Client Portal Web API — grilled end-to-end. Design record only; implementation is tracked separately.

ADRs

  • ADR-0029 — Network adapter stack. Split the net layer by transport: net-api kernel (composition + ErrorKind + Timer, std-only) → net-http-api / future net-ws-api → leaf backends. Service lives in net-http-api because request/reply isn't universal (WS is subscribe→stream); Timer is a kernel contract; compile-time / no-dyn binding per ADR-0007.
  • ADR-0030 — HTTP transport contract. Untyped Request<Bytes>Response<ResponseBody<B>> with serialization in the adapter (ADR-0003); streaming-by-composition via ResponseBody<B> (Either<Full, B>) + per-request BufferMode so buffering sits inside the retry boundary; one concrete HttpError for service and body; blanket HttpClient seam; hyper-util+rustls backend; build() default stack + data config + three-tier override.
  • ADR-0031 — HTTP resilience & venue pacing. Default layer order; order-safe retry (retransmission deferred to Core reconciliation, ADR-0022/0006/0026); merged keyed RateLimit (token-bucket + concurrency-as-policy, Scope state space, frozen-map/per-bucket-lock) grounded in the real IBKR pacing table; 3-state CircuitBreaker + 429 penalty-box backstop; Tracing → ADR-0014 Telemetry.

Notes

  • House style matches ADR-0027 (Decision / Considered Options / Consequences / Relationships); cross-references ADR-0003/0007/0009/0014/0022/0006/0026.
  • CONTEXT.md untouched — all implementation vocabulary, no domain terms changed.
  • No CHANGELOG entry (docs-only; consistent with the existing 28 ADRs).

Closes #55

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Added architecture notes describing the transport-neutral network adapter stack layout and compile-time service composition approach.
    • Defined the HTTP transport contract for end-to-end wire bytes, streaming-capable response bodies, and a unified HTTP error model.
    • Documented HTTP resilience and IBKR venue pacing behavior, including middleware ordering, retryability rules, rate/concurrency limits with throttling behavior, circuit breaking, and tracing coverage across retries and pacing waits.

Capture the request/reply (HTTP) net-stack design for the first Broker
(IBKR Client Portal Web API), grilled end-to-end:

- 0029 transport-split crates + compile-time Service/Layer composition;
  Service in net-http-api (request/reply isn't universal), Timer in the
  kernel, compile-time/no-dyn binding per ADR-0007.
- 0030 HTTP transport contract: untyped Request<Bytes> -> Response<ResponseBody<B>>
  (serialization stays in the adapter, ADR-0003), streaming-by-composition,
  one HttpError, blanket HttpClient seam, hyper-util+rustls backend.
- 0031 HTTP resilience & venue pacing: order-safe retry (retransmission
  deferred to Core reconciliation, ADR-0022/0006/0026), merged keyed
  RateLimit (token-bucket + concurrency-as-policy) grounded in the real
  IBKR pacing table, 3-state CircuitBreaker + 429 penalty-box backstop,
  Tracing -> ADR-0014 Telemetry.

Design record only; implementation tracked separately. Refs #55

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Three ADRs are added for the network adapter stack design. ADR-0029 defines the transport-neutral kernel and compile-time composition model. ADR-0030 specifies the HTTP wire-bytes contract, body model, and backend composition. ADR-0031 defines the HTTP resilience middleware order and pacing behavior.

Changes

Network Adapter Stack ADRs (0029–0031)

Layer / File(s) Summary
ADR-0029: Transport-split kernel and compile-time composition
docs/adr/0029-network-adapter-stack-transport-split-compile-time-composition.md
Defines the net-api kernel primitives, moves Service to net-http-api, adds Timer, rejects dyn and boxed futures, and states crate repartitioning and ADR relationships.
ADR-0030: HTTP transport contract, body model, and hyper backend
docs/adr/0030-http-transport-contract-wire-bytes-streaming-composition.md
Specifies bytes-only HTTP transport, the ResponseBody<B> asymmetric body model, unified HttpError, the HttpClient convenience trait, the default hyper and rustls backend, and the HttpConfig-based stack override model.
ADR-0031: HTTP resilience middleware, RateLimit, CircuitBreaker, and Tracing
docs/adr/0031-http-resilience-venue-pacing.md
Defines IBKR pacing constraints, the default middleware order, retry behavior, the keyed RateLimit layer, the multi-state CircuitBreaker, the outer Tracing layer, and the related consequences and ADR links.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title uses a valid Conventional Commits type/scope and clearly matches the ADR-only network adapter stack changes.
Linked Issues check ✅ Passed ADRs 0029–0031 cover the requested transport split, HTTP contract, and pacing/resilience design for [#55].
Out of Scope Changes check ✅ Passed The PR adds only ADR documents and no implementation or unrelated artifacts, matching the stated scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch docs/adr-network-adapter-stack

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 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 `@docs/adr/0030-http-transport-contract-wire-bytes-streaming-composition.md`:
- Around line 133-137: The public constructor currently hard-codes Tok ioTimer
in build(), which leaks a concrete backend and breaks the timer seam. Update the
build() signature to accept a generic Timer parameter (for example impl Timer or
T: Timer) and thread that abstraction through the assembled HTTP stack, while
keeping HttpConfig as plain data. Use the build() symbol and the Timer trait as
the main reference points, and ensure tests or alternate clocks can inject their
own timer implementation without changing the rest of the constructor.
- Around line 93-105: The `HttpClient` contract is inconsistent with the claim
that both the raw leaf and layered backend fit the same seam, because the
blanket `impl` on `HttpClient` still hard-requires `Body::Error = HttpError`.
Update the `HttpClient` trait/blanket impl wording so the leaf backend is either
normalized before it reaches `HttpClient` or the contract explicitly allows the
backend’s native body error and translates it inside the backend; keep the
`HttpClient`, `send`, and blanket `impl<S, B>` symbols aligned with that
behavior.

In `@docs/adr/0031-http-resilience-venue-pacing.md`:
- Around line 89-92: The ADR wording for the bucket-resolution behavior should
be changed to fail closed instead of silently skipping missing buckets. Update
the text around the pacing resolution rules so that any referenced bucket absent
from the map is treated as a configuration error or as Throttled, rather than
“no limit,” and keep the guidance aligned with the existing terminology in the
pacing section (e.g. Global, Local, Both, None).
🪄 Autofix (Beta)

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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 020a7ed0-227e-44cf-b3ec-6ef04dbdb839

📥 Commits

Reviewing files that changed from the base of the PR and between 42a8771 and 8f69e24.

📒 Files selected for processing (3)
  • docs/adr/0029-network-adapter-stack-transport-split-compile-time-composition.md
  • docs/adr/0030-http-transport-contract-wire-bytes-streaming-composition.md
  • docs/adr/0031-http-resilience-venue-pacing.md

Comment thread docs/adr/0030-http-transport-contract-wire-bytes-streaming-composition.md Outdated
Comment thread docs/adr/0031-http-resilience-venue-pacing.md Outdated
- 0030 §6/§7: the HttpClient leaf must normalize the backend body error to
  HttpError (HyperBody = MapErr<Incoming>), not raw Incoming — aligns the
  blanket-impl contract with the "leaf satisfies HttpClient" claim.
- 0030 §8: build<T: Timer>(...) instead of a hardcoded TokioTimer, so the
  Timer seam stays mockable per ADR-0029/0031.
- 0031 §3: a missing referenced RateLimit bucket fails closed (config error,
  validated at construction; rejected as Throttled at runtime) rather than
  silently fail-open into IBKR's 429 penalty box. Only explicit None is unlimited.

Refs #55

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
docs/adr/0030-http-transport-contract-wire-bytes-streaming-composition.md (1)

76-80: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Use the backend-native error wording here. hyper_util::client::legacy::Client exposes hyper_util::client::legacy::Error at the request boundary, while Incoming still maps body-side failures from hyper::Error; avoid naming only hyper::Error in this section.

🤖 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 `@docs/adr/0030-http-transport-contract-wire-bytes-streaming-composition.md`
around lines 76 - 80, Update the error-mapping description in the HTTP transport
contract ADR to use backend-native error wording instead of naming only
hyper::Error. In the section describing the request boundary and body-side
failures, reference hyper_util::client::legacy::Error for the client request
path and keep hyper::Error only for Incoming body errors, using the existing
HttpError and Body::Error discussion as the anchor.

Source: MCP tools

🤖 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.

Outside diff comments:
In `@docs/adr/0030-http-transport-contract-wire-bytes-streaming-composition.md`:
- Around line 76-80: Update the error-mapping description in the HTTP transport
contract ADR to use backend-native error wording instead of naming only
hyper::Error. In the section describing the request boundary and body-side
failures, reference hyper_util::client::legacy::Error for the client request
path and keep hyper::Error only for Incoming body errors, using the existing
HttpError and Body::Error discussion as the anchor.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 25a62202-e729-4164-b3e8-6547769b4871

📥 Commits

Reviewing files that changed from the base of the PR and between 8f69e24 and 64f92ac.

📒 Files selected for processing (2)
  • docs/adr/0030-http-transport-contract-wire-bytes-streaming-composition.md
  • docs/adr/0031-http-resilience-venue-pacing.md
✅ Files skipped from review due to trivial changes (1)
  • docs/adr/0031-http-resilience-venue-pacing.md

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Design: network adapter stack (net/http) for the IBKR broker — ADR-0029–0031

1 participant