docs(tasks): decompose review 001 remediation Units 1-5 into taskgraph tasks
21 review-001 tasks across server/adapters/client/gateway/websocket/infra, chunked from the 7-unit remediation plan in docs/reviews/001-initial-implementation-review.md. - Scope split by mechanism, not one-per-finding: 15 tasks in generation 1 (parallelizable), 6 sequenced after their file-sharing precursors - Deliberately deferred until dependent fixes land: projection/doc fidelity partial (Unit 6 beyond dependency hygiene), coverage backfills (COV-01..07 via in-task acceptance for forward.rs), and per-finding minors (OAI-06/07, HY-02/04/06/10/11, CON-08) - Cross-crate WS-12 (alkcall demux 4 GiB discard alloc) noted for filing in alkcall, not here taskgraph: validate clean, no cycles, 6 generations
This commit is contained in:
@@ -0,0 +1,67 @@
|
||||
---
|
||||
id: review-001-client-timeout-retry
|
||||
name: Client redirect/Retry-After policy — idempotency, timeouts, caps (FWD-03, FWD-04, FWD-05, FWD-11, FWD-09)
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: moderate
|
||||
risk: medium
|
||||
impact: component
|
||||
level: implementation
|
||||
tags: [client, review-001]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Review 001 findings on the outbound client host
|
||||
(`src/client/http_client.rs`, `retry_after.rs`), grouped because they all
|
||||
shape the shared client's request policy:
|
||||
|
||||
- **FWD-03**: no explicit redirect policy → reqwest's default
|
||||
cross-host redirect scrub removes only `Authorization`/`Cookie`/etc;
|
||||
`HttpAuthScheme::ApiKey { header_name }` credentials and
|
||||
`default_headers` follow a 302 to an attacker host intact (verified
|
||||
against reqwest 0.13 source). Fix: explicit policy — none, or limited
|
||||
same-host.
|
||||
- **FWD-04**: `RetryTransientMiddleware` retries POSTs (5xx/408/429/
|
||||
timeout classified retryable regardless of method — verified in
|
||||
reqwest-retry 0.9.1) → duplicate upstream side effects; backoff has no
|
||||
total-duration cap. Fix: skip retries for non-idempotent methods (or
|
||||
make idempotency a per-adapter policy) and cap total retry wall time.
|
||||
- **FWD-05**: `HttpClientConfig::default()` sets `request_timeout: None`
|
||||
and no connect timeout anywhere; `retry_after.rs:27-37` accepts any u64
|
||||
`Retry-After` with no maximum — a hostile backend's 10-year deadline
|
||||
stalls calls to that URL indefinitely. Fix: default request + connect
|
||||
timeouts (the gateway's 30 s deadline is the natural anchor) and a
|
||||
`Retry-After` ceiling (e.g. 300 s, configurable).
|
||||
- **FWD-11**: `Retry-After` is keyed on the pre-redirect URL, eviction
|
||||
drops the *earliest* deadline (keeping year-long entries), and all
|
||||
waiters wake together with no jitter. Key on the effective URL, evict
|
||||
sensibly, add jitter.
|
||||
- **FWD-09**: blocking `std::fs::read` in `build_client`, reachable via
|
||||
the public documented hot-reload path `SharedHttpClient::reload` —
|
||||
`tokio::fs`/`spawn_blocking` the reads.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Cross-host redirect test with an API-key credential header — key must not reach the redirect target
|
||||
- [ ] Non-idempotent method is never retried (test); total retry duration bounded (test)
|
||||
- [ ] Default request + connect timeouts exist in `HttpClientConfig::default()`; `Retry-After` capped (tests)
|
||||
- [ ] Retry-After keyed post-redirect; eviction and wake behavior fixed or documented (tests)
|
||||
- [ ] No blocking fs reads on the async path (FWD-09)
|
||||
- [ ] `HttpClientConfig` defaults documented; review-001-forward-url-safety and this task together close the deployment-facing gate
|
||||
- [ ] `cargo test` and `cargo clippy --all-targets -- -D warnings` pass
|
||||
|
||||
## References
|
||||
|
||||
- docs/reviews/001-initial-implementation-review.md (Part D, FWD-03, FWD-04, FWD-05, FWD-09, FWD-11)
|
||||
- docs/architecture/decisions/039-http-server-and-client-host-colocated.md
|
||||
|
||||
## Notes
|
||||
|
||||
> Agent fills during implementation. Independent of
|
||||
> review-001-forward-url-safety (different file); they form the
|
||||
> deployment gate together.
|
||||
|
||||
## Summary
|
||||
|
||||
> Filled on completion.
|
||||
Reference in New Issue
Block a user