Skip to content

feat(net): stack() assembly + HttpConfig (Slice 2)#88

Merged
NotAProfDev merged 7 commits into
mainfrom
feat/net-http-stack-assembly
Jul 5, 2026
Merged

feat(net): stack() assembly + HttpConfig (Slice 2)#88
NotAProfDev merged 7 commits into
mainfrom
feat/net-http-stack-assembly

Conversation

@NotAProfDev

@NotAProfDev NotAProfDev commented Jul 5, 2026

Copy link
Copy Markdown
Owner

Closes #87

Slice 2 (assembly, runtime-free) of the net-http construction surface (spec: docs/superpowers/specs/2026-07-05-net-http-stack-assembly-design.md; ADR-0031 §1, ADR-0034).

  • HttpConfig — non-generic aggregate: timeout, retry, circuit_breaker, headers, rate_limit_max_wait.
  • stack<S, T, A, K>() — builds the fallible RateLimit layer first (validates coverage + concurrency-singleton), then composes Tracing(CircuitBreaker(Retry(RateLimit(Timeout(SetHeaders(Auth(leaf))))))) over any leaf. Returns Result<impl HttpClient + Clone + Send + Sync + 'static, BuildError>, so a layer regression is a compile error at stack().
  • Full-stack tests over an inline recording leaf + MockTimer (no MockClient — dev-dep cycle): CircuitBreaker-outside-Retry, RateLimit-inside-Retry, send-Timeout, per-attempt Auth re-stamp, Scope fail-closed, plus a transparency smoke and a boot-coverage BuildError.

No new dependency; no runtime; no existing-layer change. BufferOrStream is leaf-side (not a layer). Next: the hyper-backend slice — build() + hyper_leaf() + TokioTimer, delegating to this stack().

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added a standard HTTP resilience stack() configuration with an exposed HttpConfig to control timeout, retry, circuit breaker, headers, and rate limiting.
    • Requests are assembled with a canonical middleware order (including per-attempt auth and fail-closed scope handling).
    • Invalid rate-limit coverage/concurrency/singleton setup now fails during startup with a clear build error.
  • Bug Fixes
    • Ensures correct interactions between circuit breaking, retries, timeouts, rate limiting, auth re-stamping, and scope rejection.
  • Tests / Documentation
    • Added end-to-end regression tests for stack ordering and fail-closed behavior, plus updated design docs and changelog.

NotAProfDev and others added 6 commits July 5, 2026 08:09
Adds the runtime-free assembly design (stack() + HttpConfig) derived from the
construction-surface spec and ADR-0031, and commits the previously-untracked
Slice 0 PR4 (rate-coverage) implementation plan that shipped as #72.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Adds the task-by-task stack()/HttpConfig plan and folds in the design
refinements surfaced while planning against the shipped layer APIs:
HttpConfig gains rate_limit_max_wait (RateLimitLayer::new's 3rd arg),
validation is delegated to RateLimitLayer::new (no separate call), and
tests use an inline recording leaf (not MockClient, a dev-dep cycle).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add the non-generic HttpConfig aggregate and the stack() function that
validates pacing coverage (RateLimitLayer::new) before composing the
ADR-0031 canonical resilience order over any leaf:
Tracing(CircuitBreaker(Retry(RateLimit(Timeout(SetHeaders(Auth(leaf))))))).

Includes a transparency smoke test (request flows through all layers,
body untouched) and a boot-coverage test proving a non-total
RateLimitConfig fails closed as a BuildError before anything is built.

Deviations from the brief, needed to compile/lint clean:
- Added `S::Body: Send` to stack()'s where clause: RateLimit's Service
  impl requires the body to be Send, which the bare HttpClient bound
  does not imply.
- Test module imports `oath_adapter_net_api::Timer` (needed for
  ScriptLeaf's Step::Hang arm to call `timer.sleep`).
- `#[allow(clippy::needless_pass_by_value)]` on stack(): rate_limits is
  only borrowed internally, but the public signature intentionally
  takes ownership to mirror HttpConfig's "consumed once at boot" shape.
- Second test uses `let-else` instead of `.unwrap_err()`, which would
  require Debug on the opaque `impl HttpClient + ...` Ok type.
- `#[allow(dead_code)]` on Step::Err/Hang, ScriptLeaf::calls/seen_auth,
  and CounterAuth: scaffolding consumed by Task 2's full-stack tests
  landing later in this same file.

Closes #87
Final whole-branch review flagged the amendment enumerated the bound
refinements but omitted S::Body: Send (transitively required by
Retry/RateLimit's B: Send). Records it so the ADR matches the shipped
stack() signature.

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

coderabbitai Bot commented Jul 5, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 6685b137-4519-4275-afbe-d8609b83f9a7

📥 Commits

Reviewing files that changed from the base of the PR and between ccf9ffd and 17ff586.

📒 Files selected for processing (1)
  • docs/superpowers/specs/2026-07-05-net-http-stack-assembly-design.md
✅ Files skipped from review due to trivial changes (1)
  • docs/superpowers/specs/2026-07-05-net-http-stack-assembly-design.md

📝 Walkthrough

Walkthrough

Adds HttpConfig and stack() to oath-adapter-net-http-api, assembling the canonical resilience order with fail-closed validation, regression tests, public exports, ADR/changelog updates, and planning/spec documentation.

Changes

stack() implementation and wiring

Layer / File(s) Summary
HttpConfig struct and stack() assembly
crates/adapter/net/http/api/src/stack.rs
Defines non-generic HttpConfig and implements stack(), validating rate-limit coverage first then composing the remaining layers via ServiceBuilder in canonical order.
Public module wiring and exports
crates/adapter/net/http/api/src/lib.rs
Adds pub mod stack; and re-exports HttpConfig/stack, updating crate docs.
Full-stack regression tests
crates/adapter/net/http/api/src/stack.rs
Adds inline recording leaf, mock auth, and MockTimer-based tests for ordering invariants, timeouts, retries, and fail-closed scope handling.
Changelog and ADR documentation
CHANGELOG.md, docs/adr/0034-http-construction-surface-auth-guarded-boot-coverage.md
Documents the new stack()/HttpConfig behavior, ordering invariants, and testing approach.

Planning and design documentation

Layer / File(s) Summary
RateKey boot-coverage plan
docs/superpowers/plans/2026-07-04-net-http-rate-coverage.md
Adds the Slice 0 implementation plan for RateKey, RateLimitConfig, BuildError, and validate_coverage.
stack() assembly plan
docs/superpowers/plans/2026-07-05-net-http-stack-assembly.md
Adds the Slice 2 task plan for stack.rs creation, wiring, tests, ADR/changelog steps, and self-review.
stack() design spec
docs/superpowers/specs/2026-07-05-net-http-stack-assembly-design.md
Adds the design spec defining HttpConfig, stack() contract, layer nesting table, and test/ADR reconciliation requirements.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

Possibly related PRs

  • NotAProfDev/oath#72: stack() construction depends on the RateKey/RateLimitConfig/BuildError/validate_coverage API introduced here.
  • NotAProfDev/oath#76: stack() relies on RateLimitLayer/RateScope behavior and fail-closed invariants from this PR.
  • NotAProfDev/oath#66: stack() wires the AuthSource/Auth/SetHeaders layers with per-attempt re-stamping introduced here.

Suggested labels: enhancement

🚥 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 Conventional Commits with a clear feat scope and accurately names the main change.
Linked Issues check ✅ Passed The PR implements HttpConfig, stack() ordering, boot-time validation, and the required tests, matching #87.
Out of Scope Changes check ✅ Passed The changes are focused on the requested stack-assembly slice and supporting docs/tests, with no clearly unrelated code.
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 feat/net-http-stack-assembly

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: 1

🤖 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/superpowers/specs/2026-07-05-net-http-stack-assembly-design.md`:
- Around line 120-131: The public stack() contract is missing a required body
bound for the composed client to remain Send. Update the stack() signature and
its where-clause to include S::Body: Send alongside the existing S, T, A, and K
constraints, so the HttpClient composition requirements are fully reflected in
the API spec.
🪄 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: 6dad1b22-17cb-42d8-920c-2559600874d9

📥 Commits

Reviewing files that changed from the base of the PR and between 2c6e9b5 and ccf9ffd.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • crates/adapter/net/http/api/src/lib.rs
  • crates/adapter/net/http/api/src/stack.rs
  • docs/adr/0034-http-construction-surface-auth-guarded-boot-coverage.md
  • docs/superpowers/plans/2026-07-04-net-http-rate-coverage.md
  • docs/superpowers/plans/2026-07-05-net-http-stack-assembly.md
  • docs/superpowers/specs/2026-07-05-net-http-stack-assembly-design.md

Comment thread docs/superpowers/specs/2026-07-05-net-http-stack-assembly-design.md Outdated
CodeRabbit (PR #88) flagged the spec's stack() where-clause still showed
the pre-implementation sketch bounds. Sync it to the shipped signature:
S::Body: Send, T/A + 'static, K + Debug (already in ADR-0034 #11).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@NotAProfDev NotAProfDev merged commit d3911a6 into main Jul 5, 2026
5 checks passed
@NotAProfDev NotAProfDev deleted the feat/net-http-stack-assembly branch July 5, 2026 09:50
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.

feat(net): stack() assembly + HttpConfig (Slice 2)

1 participant