You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Follow-up to PR #66 (ADR-0034, Slice 0 PR 3). A design review surfaced four refinements to the net-http construction surface. This issue tracks recording them (ADR-0034 append-only amendments + spec update) and the one code change they imply.
Refinements
Absent RateLimit<K> directive fails closed — tightens ADR-0031 §3's "absent directive defaults to Global", which was the last silent under-pacing path (a forgotten stamp flies global-paced only, invisible to the boot-coverage check). A request with no RateLimit<K> extension is now rejected fail-closed; "global only" is an explicit Scope::Global, opt-out is Scope::None. Lands with the RateLimit slice (unbuilt).
Guarded releases the permit on a mid-stream error too — release rule becomes "the earliest of terminal frame, mid-stream error, or drop". A /history transfer that dies mid-stream must not pin one of the 5 concurrency permits while a consumer holds the errored body. Touches the Guarded body shipped in feat(net): AuthSource + Auth/SetHeaders layers + Guarded body (Slice 0 PR 3) #66 — the one concrete code change.
async-lock rationale re-based on the stated multi-backend goal — smol/async-std backends are a stated goal, so option R (async-lock) over P (tokiofeatures=["sync"]) has a concrete payoff (a non-tokio stack that is genuinely tokio-free), not a "thin margin". Doc-only.
MockTimer lives in its own dev-only oath-adapter-net-mock crate beside the Timer contract in net-api (not net-http-mock), so the WS stack (ADR-0032/0033) shares one fake clock without an HTTP dep edge. Lands when the mock crates are built.
Follow-up to PR #66 (ADR-0034, Slice 0 PR 3). A design review surfaced four refinements to the net-http construction surface. This issue tracks recording them (ADR-0034 append-only amendments + spec update) and the one code change they imply.
Refinements
RateLimit<K>directive fails closed — tightens ADR-0031 §3's "absent directive defaults toGlobal", which was the last silent under-pacing path (a forgotten stamp flies global-paced only, invisible to the boot-coverage check). A request with noRateLimit<K>extension is now rejected fail-closed; "global only" is an explicitScope::Global, opt-out isScope::None. Lands with theRateLimitslice (unbuilt).Guardedreleases the permit on a mid-stream error too — release rule becomes "the earliest of terminal frame, mid-stream error, or drop". A/historytransfer that dies mid-stream must not pin one of the 5 concurrency permits while a consumer holds the errored body. Touches theGuardedbody shipped in feat(net): AuthSource + Auth/SetHeaders layers + Guarded body (Slice 0 PR 3) #66 — the one concrete code change.async-lockrationale re-based on the stated multi-backend goal — smol/async-std backends are a stated goal, so option R (async-lock) over P (tokiofeatures=["sync"]) has a concrete payoff (a non-tokio stack that is genuinelytokio-free), not a "thin margin". Doc-only.MockTimerlives in its own dev-onlyoath-adapter-net-mockcrate beside theTimercontract innet-api(notnet-http-mock), so the WS stack (ADR-0032/0033) shares one fake clock without an HTTP dep edge. Lands when the mock crates are built.Scope of this PR
Guardedmid-stream-error release (code) — decide whether to include here or split.Full reasoning in
docs/superpowers/specs/2026-06-30-net-http-construction-surface-design.mdand ADR-0034.