- The two residuals recorded as accepted-uncovered availability notes, each with its bound: broadcast squatting under the unverified offered digest (the put's broadcast begins pre-read, keyed under the offered digest; integrity intact via the consumer-side ADR-006 hash-check, the residual wasted re-fetches) and the `Stall` policy's read-peg (a read-granted fetcher stops reading, backpressuring the broadcast; bounded by the tap's channel lifecycle, the put's completion, and the subscriber bound). - Homes: the full record on the fetch fanout section of src/ops/mod.rs and the `FanoutRegistry` doc in src/ops/fetch.rs, a pointer on the `Stall` variant doc, a pointer sentence on the `blobs/fetch` serving-paths paragraph. - Doc-only: no behavior change, no tests touched. - One pre-existing `cargo doc` warning fixed doc-only (src/local.rs's module doc linked private `walk_committed`). Verification: cargo test (default, green), cargo test --all-features against the live pglo-poc harness (green), clippy --all-targets -- -D warnings (both feature variants), cargo fmt --check, cargo doc --no-deps (zero warnings).
7.1 KiB
id, name, status, depends_on, scope, risk, impact, level, tags
| id | name | status | depends_on | scope | risk | impact | level | tags | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| s7-fanout-residuals-doc | S-7 — the fanout griefing residuals named on the module doc (broadcast squatting; the Stall read-peg) | completed |
|
single | trivial | component | implementation |
|
Description
Review-001 S-7 [observation] — doc-only. Two fanout griefing residuals are real, bounded, and accepted-uncovered; they must read as decisions, not oversights:
- Broadcast squatting under the unverified offered digest: the broadcast begins before any byte is read (the put pipe's producer half — src/ops/put.rs; the registry side src/ops/fetch.rs:75-105) — a hostile putter squats a digest's broadcast and feeds garbage to concurrent fetchers' taps, whose hash-check then fails them into re-fetching. Integrity is intact (the consumer-side ADR-006 check is the barrier); the blast radius is wasted re-fetches.
- The Stall policy's read-peg: under
Stall(src/ops/fetch.rs:43-58), a read-granted fetcher can tap a live put and simply stop reading — the bounded channel backpressures the broadcast and with it the producer's streaming; no deadline anywhere in the put path. Bounded by alkcall's channel lifecycle (the tap's channel closing on disconnect/teardown unblocks the arm) and the put's own completion — but the peg is real while it lasts.
The fix: name both residuals as accepted-uncovered availability notes on the module doc — the fetch fanout section of src/ops/mod.rs (the serving-paths/fanout seam section) and/or the src/ops/fetch.rs module doc (the registry/publisher docs) — each with its bound named (integrity intact via the consumer-side hash-check; the channel lifecycle + subscriber bound; the put's completion). No behavior change anywhere.
Depends on s1-s3 and s2 only because they edit the same doc sections (the model statement; the ranged-form mechanics) — this task lands last so the notes sit on the final text.
Acceptance Criteria
- Both residuals named on the module doc as accepted-uncovered availability notes, each with its bound stated
- No behavior change (doc-only diff)
- Gates green:
cargo test(default),cargo test --all-featuresserver-less, clippy--all-targets -- -D warnings,cargo fmt --check,cargo doc --no-depszero warnings
References
- docs/reviews/001-storage-surface-general-review.md (S-7 — pre-split coordinates)
- docs/plans/implementation.md (§Wave 10; §Review gates — the security gate's S-7 clause)
- src/ops/mod.rs (the fetch fanout section)
- src/ops/fetch.rs (the module doc;
SlowSubscriberPolicy; the registry/publisher docs) - src/ops/put.rs (the producer half — where the broadcast begins)
Notes
- Doc-only diff verified:
src/ops/fetch.rsandsrc/ops/mod.rsprose only — no signature, code, or test change anywhere; the code-level facts the notes state were read off the source before writing (the broadcast's begin at put establishment, pre-read, keyed under the offered digest — src/ops/put.rs'sput_handle; theStallarm's awaitedsendand the closed-arm removal — src/ops/fetch.rs'sFanoutPublisher::broadcast; the miss/refusals unchanged). - Placement (the task's and/or taken as both homes, one full
copy): the full accepted-uncovered record (both residuals, each
with its bounds named) rides the fetch fanout section of
src/ops/mod.rs (after the registry's producer/consumer wiring
paragraph, before the fetch-is-not-a-producer design point) — the
seam's central doc. src/ops/fetch.rs carries the same record on the
FanoutRegistrydoc (the registry/publisher home) plus a one-sentence pointer on theSlowSubscriberPolicy::Stallvariant (where a reader of the peg policy lands). A short pointer sentence added at theblobs/fetch§serving-paths paragraph (the tap-path consult) so the fetch reader finds the record. The three placements state the same thing once each, no machinery-naming drift possible (each is the same accepted-coverage sentence set). - The bounds as stated (review-001 S-7's "accepted-uncovered
availability notes; both bounded by alkcall's channel lifecycle",
sharpened against the code): squatting → integrity intact (the
consumer-side ADR-006 hash-check is the barrier, garbage never
verifies; a failed check degrades to the verified re-fetch), the
residual the wasted re-fetches; the read-peg → the tap's own
channel lifecycle (a disconnect/teardown closes the channel and
broadcast's awaited send unblocks, the dead arm removed), the put's own completion (the entry drops; arms see channel end), and the subscriber bound capping who can tap. The "read-granted" qualifier rides the ACL (the fetch read action), not the fanout — stated. - One out-of-scope line touched, doc-only:
cargo doc --no-depson unmodified main carried a pre-existing warning (src/local.rs's module doc linked privatewalk_committedin intra-doc syntax). The S-7 gate demands zero doc warnings, so the link brackets were dropped (plain backticks, same text) — no behavior change, no markdown semantics change. - The residual-notes rule: neither note names a TODO. The text says explicitly that a verified broadcast key and a put-path deadline would both be hardening if a threat model asks — the decision-record form the security gate wanted ("decisions, not oversights"), not new work items.
Summary
S-7 landed, doc-only. The two fanout griefing residuals are named as
accepted-uncovered availability notes on the module doc, each with
its bound: (1) broadcast squatting under the unverified offered
digest — the put's broadcast begins pre-read keyed under the
offered digest while verification is still ahead of the stream, so a
hostile putter feeds garbage to concurrent fetchers' taps; integrity
intact (the consumer-side ADR-006 hash-check is the barrier), the
residual is wasted re-fetches; (2) the Stall policy's read-peg —
a read-granted fetcher can tap a live put and stop reading,
backpressuring the broadcast and the producer's streaming, no put-path
deadline; bounded by the tap's channel lifecycle (disconnect/teardown
closes it, the send unblocks, the arm is removed), the put's own
completion, and the subscriber bound. Homes: the fetch fanout section
of src/ops/mod.rs (the full record), the FanoutRegistry doc + the
Stall variant doc in src/ops/fetch.rs (the same record + pointer),
and a pointer sentence on the blobs/fetch serving-paths paragraph.
No behavior change; no unwrap, no signatures, no tests touched. One
pre-existing cargo doc warning (src/local.rs's private-item
intra-doc link) fixed doc-only to satisfy the zero-warnings gate.
Gates: cargo test (default: 149 lib + 54 conformance + 4
git-interop, green), cargo test --all-features against the live
pglo-poc harness (327 lib + 125 conformance + 4 git-interop, green),
clippy --all-targets -- -D warnings across both feature variants,
cargo fmt --check, cargo doc --no-deps zero warnings.