docs(tasks): re-validate bracketed follow-up into 3 tasks (OAI-18 decision, streaming-coverage residue, doc-gate fix)
The bracketed planning task's five candidates, re-validated against
the post-bulk tree (0a932e5, all 23 bulk tasks done, 446/568 green):
1. OAI-18 -> review-002-fu-oai18-decision: still key-allowlist-only;
bulk blockers (yaml/path-item) both landed. Task records the
enforce-vs-scope-the-advert decision framework from review 002.
2. CON-08/CON-09 close() lever: deferred still (documented v1
contracts unchanged, no consumer pressure) — not tasked.
3. Cross-crate: CF-001..004 all open in alkcall, no alkhttp-side task;
PRJ-16 guard already documents its defense-in-depth re-scope
disposition (no work when CF-004 lands).
4. Stale-comment sweep: mostly absorbed by the bulk (SRV-11 comment
rewritten in-fix); residue = 3 cargo-doc warnings + WsTimeouts
redundant Default -> review-002-fu-doc-warnings.
5. ADR-045 version audit: clean (1.4.0 + annotations + test pin).
Post-bulk coverage re-pass (95.89% regions, bulk's new code fully
covered: PRJ-16 guard, body cap, router reorder, batch cap, WS
knobs, OAI-11 node budget all exercised) surfaced one unanticipated
residue -> review-002-fu-stream-error-coverage (forward_stream
build-error arm never exercised on a Sub op; PEM read-failure arms;
over-cap poll_write; SSE split-CRLF edge; from_value structural
rejects; WsTimeouts Default).
Bracketed pass itself marked completed (planning consumed).
taskgraph: 69 valid, no cycles; 3 pending.
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
---
|
||||
id: review-002-fu-stream-error-coverage
|
||||
name: Streaming error-arm coverage — forward_stream invalid input, PEM read-failure, over-cap poll_write mirror (post-bulk coverage gap)
|
||||
status: pending
|
||||
depends_on: []
|
||||
scope: narrow
|
||||
risk: low
|
||||
impact: component
|
||||
level: implementation
|
||||
tags: [infra, review-002, follow-up, coverage]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
Bracketed follow-up discovery from the post-bulk coverage re-pass
|
||||
(95.89% regions overall; the review-002 bulk's own new code verified
|
||||
fully covered — PRJ-16 guard, body cap, router reorder, batch cap,
|
||||
WS-13/18/19, the OAI-11 memo node-budget all exercised). The residue
|
||||
is small but one item matters more than its line count:
|
||||
|
||||
- **`forward_stream` build-request error arm** (forward.rs:1085-1090):
|
||||
a Sub op invoked with an invalid input (undeclared key, non-scalar
|
||||
placeholder value) must produce exactly one error envelope from the
|
||||
stream — the streaming analog of the Once-path error handling. No
|
||||
test drives it: every SSE test (from_jsonschema `integration_sse_subscription…`,
|
||||
forward.rs's stream family) sends valid input. A regression returning
|
||||
an empty stream (silently swallowing the error) would be invisible —
|
||||
and an empty-200-subscribe is the worst failure shape for a
|
||||
subscriptions consumer.
|
||||
- **PEM read-failure arms** (http_client.rs CaBundleRead/ClientCertRead,
|
||||
sync + async): the *parse*-failure arms are covered
|
||||
(`corrupt_ca_bundle_fails_ca_bundle_parse_with_path`,
|
||||
`garbage_client_cert_fails_…` in client_tls.rs, landed in 6490d15),
|
||||
but the **unreadable-file** arms (nonexistent path, unreadable
|
||||
permissions) have no test on either build path. The error taxonomy
|
||||
half-documented at `HttpClientBuildError`'s doc block (:214) is
|
||||
half-specified.
|
||||
- **Over-cap `poll_write` rejection** (byte_adapter.rs:789-798): WS-14's
|
||||
moved check rejects writes *above* `PENDING_BUFFER_CAP` with
|
||||
`InvalidData` before entry to the queue — the "at cap" boundary is
|
||||
tested (`tungstenite_write_at_the_cap_is_accepted`, 1158) and the
|
||||
framing-level cap-trip is tested both flavors
|
||||
(`axum_framing_cap_trip…`), but the single-call over-cap rejection
|
||||
itself (the WS-14 acceptance test's own criterion) never runs: no
|
||||
test writes `PENDING_BUFFER_CAP + 1`.
|
||||
- **`forward_stream` SSE-parser residual edges**: split-CRLF-across-
|
||||
chunks (the `\r` + `"\n…"` case), invalid-UTF8-line drop — the
|
||||
parser edges the bulk's stream arms work next to.
|
||||
- **`from_value` structural rejections** (openapi_spec.rs:391-398,
|
||||
416-418): a non-object document, a missing-`info`, a non-object
|
||||
`paths` — none ever exercised (all other structural rejects are).
|
||||
- **Connection-failure arms**: `protocol_handler` accept-path
|
||||
`stream_error_to_handler` (adapter.rs:597-599) and the read-pump
|
||||
demux-gone `break` (byte_adapter.rs:374-381) — both are
|
||||
connection-failure semantics with zero direct coverage.
|
||||
- **Dead-ish**: `impl Default for WsTimeouts` (upgrade.rs:344-351)
|
||||
has zero callers (the extension is constructed explicitly in the
|
||||
one test that uses it) — delete or `#[allow(dead_code)]` with the
|
||||
reason.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Wire test: Sub op + undeclared key (or non-scalar placeholder
|
||||
value) → the subscriber receives exactly one `INVALID_INPUT`
|
||||
envelope and the stream ends (upstream receives zero requests)
|
||||
- [ ] Two PEM read-failure tests: `SharedHttpClient::new` with a
|
||||
nonexistent CA path → `CaBundleRead` carrying the path;
|
||||
`reload` with a nonexistent client-cert path → `ClientCertRead`
|
||||
- [ ] One over-cap `poll_write` test: `write_all(PENDING_BUFFER_CAP+1)`
|
||||
→ `InvalidData` error naming the cap (asserts the WS-14 moved
|
||||
check's rejection leg; the = cap test exists)
|
||||
- [ ] SSE parser edge tests: CRLF split across chunks (`…\r` ends
|
||||
chunk 1, `\n…` opens the next), invalid-UTF8 line dropped
|
||||
- [ ] from_value structural tests: non-object doc, missing-`info`,
|
||||
non-object `paths` → `SchemaParse` naming the missing member
|
||||
- [ ] `WsTimeouts` redundant `Default` deleted (or justified+allowed)
|
||||
- [ ] `cargo llvm-cov --all-features`: named arms no longer dark;
|
||||
`cargo test --all-features`, clippy, fmt pass
|
||||
|
||||
## References
|
||||
|
||||
- docs/reviews/002-post-remediation-review.md (Part G' test-gaps; post-bulk re-analysis finding list)
|
||||
- src/adapters/forward.rs:1085-1090 (stream build-error arm), src/client/http_client.rs:484-545 (read-failure arms), src/websocket/byte_adapter.rs:789-798 (over-cap poll_write)
|
||||
- tests/client_tls.rs (the PEM harness: parse-failure tests at :226-448 are the pattern to mirror for read-failures)
|
||||
- tasks/infra/review-002-cov-deployment-knobs.md (the pre-bulk coverage task these extend)
|
||||
- tasks/infra/review-002-cov13-dead-code.md (the dead-code convention for the WsTimeouts Default)
|
||||
|
||||
## Notes
|
||||
|
||||
Tests-only + one deletion. The streaming-build-error test's
|
||||
load-bearing assertion is the *single envelope then end* semantics —
|
||||
mirror `oversized_upstream_sse_line_terminates_with_one_internal_envelope`'s
|
||||
assert structure but trigger pre-send instead (invalid input, no
|
||||
responder needed for the reject case — wire it against a live-responder
|
||||
anyway if the harness makes it cheap; the zero-upstream-contact assert
|
||||
is the point). The `spawn_responder`-family harnesses in
|
||||
forward.rs/from_jsonschema.rs cover the seam.
|
||||
Reference in New Issue
Block a user