docs(tasks): decompose wave 7 — the ops surface, the alkcall-backed op family behind the default-off feature
This commit is contained in:
1 parent
e84a874715
commit
c9829836b1
8 files changed
+852
-2
No files matched your search
@@ -0,0 +1,101 @@
|
||||
---
|
||||
id: ops-fetch
|
||||
name: blobs/fetch — the verified Sub op and the fanout seam's consumer side
|
||||
status: pending
|
||||
depends_on: [ops-foundation, ops-call-harness]
|
||||
scope: moderate
|
||||
risk: medium
|
||||
impact: component
|
||||
level: implementation
|
||||
tags: [wave-7, ops, fetch, fanout, verification]
|
||||
---
|
||||
|
||||
## Description
|
||||
|
||||
`blobs/fetch` (ops-surface.md §Op family) — the server→client
|
||||
streaming op: `{namespace, digest, ranges?}` in; **verified bytes
|
||||
out** over the binary data channel.
|
||||
|
||||
- **The op shape**: `OperationType::Sub` (alkcall ADR-021's streaming
|
||||
handler kind) with the **`channel_open` marker** (alkcall ADR-047)
|
||||
— the binary data plane rides a `channel_open`-allocated channel;
|
||||
the establishment phase (alkcall ADR-049) carries the fetch's ack
|
||||
shape in the `Establishment` reply fields as the wire requires. The
|
||||
**read** action (ACL exactly like stat/have — closed-by-default).
|
||||
- **Verified streaming** (ADR-006; ops-surface.md): the *consumer*
|
||||
hash-checks the received whole against the carried digest —
|
||||
whole-blob verification; there are no per-chunk or per-range checks
|
||||
derivable under the canonical digest. The handler streams from the
|
||||
facade only: `Store::get` (the whole) or `Store::read_range` (the
|
||||
ranged form). **Ranged fetch** (`ranges?`): the response carries
|
||||
the same ADR-006 slice-digest convention `read_range` returns —
|
||||
SHA-256 over exactly the returned bytes, out-of-band.
|
||||
- **The fanout seam's consumer side** (ops-surface.md; POC #3 finding
|
||||
A3): the fetch handler consults the foundation's fanout registry —
|
||||
a live broadcast for the digest → a **subscriber arm** taps it; no
|
||||
live broadcast, or one that ended (a **late joiner**) → the normal
|
||||
post-commit verified `get` — identical bytes under CAS. The
|
||||
slow-subscriber policy (drop-and-late-join) is ops-layer policy,
|
||||
not a store concern. Named design point: **the producer side's
|
||||
shape** — the put handler's stream reader as the canonical producer
|
||||
(serve-while-persisting, A3's shape), and whether fetches also
|
||||
produce read-side broadcasts (concurrent fetchers of one stored
|
||||
digest sharing one store read) — decide and record against the A3
|
||||
text.
|
||||
- **The miss shape**: a fetch of an absent digest is the typed
|
||||
missing-error schema (the need announcement *is* the fetch miss —
|
||||
the have/need diff is caller-side; no separate need op exists).
|
||||
- **Tests through the harness**: the whole-blob verified round-trip
|
||||
(byte-exact; the client's hash-check passes); the ranged form
|
||||
(bytes + slice digest matching `read_range`'s convention); the
|
||||
fanout consumer side (a live broadcast tapped — the subscriber
|
||||
receives while the producer runs; a late joiner degrades to the
|
||||
get path — asserted by which path served); the miss shape; the ACL
|
||||
denial (no read grant on the namespace → denied).
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] fetch exported as a Sub spec/handler pair with the
|
||||
`channel_open` marker + ALPN; the establishment reply fields
|
||||
carry the specced ack shape
|
||||
- [ ] Whole-blob verification: the received whole hash-checks against
|
||||
the carried digest (the consumer-side discipline documented on
|
||||
the op; the server streams verified-store bytes)
|
||||
- [ ] Ranged fetch carries the ADR-006 slice-digest convention
|
||||
(out-of-band, over exactly the returned bytes)
|
||||
- [ ] The fanout consumer side: a live broadcast → subscriber arm; a
|
||||
late joiner → the verified get path; the producer-side design
|
||||
point decided and recorded
|
||||
- [ ] The miss shape is the typed missing error; the have/need diff
|
||||
stays caller-side (no need op invented)
|
||||
- [ ] ACL: the read action; closed-by-default verified by test
|
||||
- [ ] Handlers touch only the store facade (no backend side-door)
|
||||
- [ ] Harness tests green; `cargo test` (default) green;
|
||||
`cargo test --features ops` green; clippy/fmt green on both
|
||||
shapes; `cargo doc --no-deps` clean
|
||||
|
||||
## References
|
||||
|
||||
- docs/architecture/ops-surface.md (§Op family — the fetch bullet +
|
||||
the fanout text; the need-half note)
|
||||
- docs/architecture/decisions/006-verification-posture-and-transfer-encoding.md
|
||||
(whole-blob verification; the slice-digest convention)
|
||||
- docs/architecture/decisions/008-trait-size-probe-fleet-gc-and-large-engines.md
|
||||
§3 (the re-routing topology this op serves — large-blob access
|
||||
through a storage node)
|
||||
- docs/research/poc-largeblob-findings.md finding A3 (the fanout
|
||||
seam: one reader, store arm + subscriber arms; late joiners
|
||||
degrade to get-after-commit)
|
||||
- alkcall (upstream checkout): ADR-021 (streaming handler for
|
||||
subscriptions), ADR-046/047/049 (the sink kind, the channel_open
|
||||
marker, the establishment phase), `src/channels/client.rs`
|
||||
- tasks/ops-foundation.md (the fanout registry's mechanics),
|
||||
tasks/ops-call-harness.md (the harness)
|
||||
|
||||
## Notes
|
||||
|
||||
> To be filled by implementation agent
|
||||
|
||||
## Summary
|
||||
|
||||
> To be filled on completion
|
||||
Reference in new issue
Block a user