docs(research): correct layer vocabulary — alkcall has no transport code

- Verified against alkcall 0.8.1: no networking deps; Connection wraps
  a caller-provided established stream (ADR-012 dial/call decoupling)
- 'transport' was being used loosely for 'wire/ops protocol'; now
  reserved for endpoints/dialing/byte-moving, which is in neither
  crate. Ops/framing/ACL surface = wire/ops protocol (alkcall's layer)
- Vision sentence, scope line, OQ-BL-01 argument, and alkcall
  prior-art entry rewritten with the accurate layering; alkcall entry
  now states the transport-free fact explicitly
- iroh-blobs-eval.md: 'welded to their transport' -> 'welded to their
  protocol stack (endpoints/transport weld on above it)'

Verification: cargo test / clippy -D warnings / fmt --check clean
This commit is contained in:
glm-5.3-flash committed 2026-10-01 13:37:09 +00:00
1 parent b0b385d94e
commit 7d9ac8a6ec
2 files changed
+40 -27

No files matched your search

+4 -2
View File
@@ -31,7 +31,9 @@ Lessons for alkblobs:
- **The command-enum-as-contract is a working pattern** (it is what
makes iroh-blobs' remote/local symmetry possible), but it carries the
whole irpc machinery into the store layer and *is* the reason their
store is welded to their transport. POC #1's lean `Backend` trait is
store is welded to their protocol stack (theirs also welds transport
endpoints above that; the store-actor weld alone is what kills
backend swappability). POC #1's lean `Backend` trait is
the smaller hammer for our split: the trait stays dumb (opaque bytes),
and any ops surface above it (alkcall) speaks its own protocol.
- **Re-borrowed conclusion, not mechanism: per-hash serialized actors.**
@@ -175,7 +177,7 @@ findings (first-party, measured).
## Do-not-inherit list (re-confirmed against 0.103)
- The `Command`-actor + irpc store abstraction (welds store to their
transport stack).
protocol stack; endpoints/transport weld on above it).
- redb-specific entry-state modeling if we go sqlite (their tables and
`EntryState` postcard encoding are theirs; our sqlite schema is
`key → (value, size)` and our dispatch is store-layer policy).
+36 -25
View File
@@ -29,8 +29,9 @@ documents (`poc-trait-dispatch-findings.md`, `poc-largeblob-findings.md`,
a put/get/verify store keyed under one canonical content hash (the
git-family derivation; legacy SHA-1-tolerant), with pluggable backends
(small blobs in a kv/sqlite-ish store, large blobs on a filesystem
fallback), split from any transport/protocol layer, with auth-gated
network operations riding the alkcall seam (OQ-BL-01).
fallback), split from any wire/ops-protocol layer (framing, op family,
ACL ride the alkcall substrate when they exist — OQ-BL-01), which is
itself transport-free (alkcall is a pure protocol crate).
**Why this crate exists (the converging consumers):**
@@ -82,15 +83,16 @@ The implications for this crate:
alkcall substrate (OQ-BL-01), whether it lives in this crate or a
sibling.
**The scope line:** this crate is the *store*, not the *transport*.
iroh-blobs welds store + provider protocol + tickets + postcard into
one crate; the defining posture here is the opposite split —
put/get/verify against a hash is its own layer, and any
provider/protocol/ops surface lives above it or in feature-gated
modules (the alk* inversion-point pattern). "Above it" does not mean
"without alkcall": the ops surface *is* alkcall-shaped (OQ-BL-01) —
what the store layer itself must never grow is transport, framing, or
auth internals. What stays *above* the crate regardless: repos/
**The scope line:** this crate is the *store*, not the *wire/ops
protocol*. iroh-blobs welds store + provider protocol + tickets +
postcard into one crate; the defining posture here is the opposite
split — put/get/verify against a hash is its own layer, and any
ops/protocol surface lives above it or in feature-gated modules (the
alk* inversion-point pattern). "Above it" does not mean "without
alkcall": the ops surface *is* alkcall-shaped (OQ-BL-01) — what the
store layer itself must never grow is wire framing, op dispatch, ACL,
or transport (alkcall carries none of the last either; the connection
is handed to it). What stays *above* the crate regardless: repos/
workspaces as reference sets (trees/manifests), path→hash mapping,
git semantics, the contract/gossip/replicator policy layer.
@@ -304,16 +306,22 @@ appfile pattern this crate now owns by its own validated design.
### alkcall — the substrate (and the ops surface's foundation)
`/workspace/@alkdev/alkcall` (the call + channels RPC crate). The ops
surface rides it (OQ-BL-01, settled): JSON-shaped control ops with
JSON Schema validation and typed error schemas (ADR-016), binary
streaming via the `channel_open` marker (ADR-047) in both directions
(`Sub` ADR-021 for verified fetch, `Pub`/`HandlerKind::Sink` ADR-046
for put), ACL via `AccessControl` + ownership checks (ADR-011) under
the ADR-017 privilege model, and the established data-path patterns
`/workspace/@alkdev/alkcall` (the call + channels RPC crate). **It
contains no transport code** — no networking dependencies (README:
"a pure protocol crate — no networking, no transport dependencies");
a `Connection` wraps an already-established byte stream that the
*caller* provides (dialing/listening happens above it, per ADR-012's
dial/call decoupling). What it owns is the wire/ops protocol: JSON
op family with JSON Schema validation and typed error schemas
(ADR-016), binary streaming via the `channel_open` marker (ADR-047)
in both directions (`Sub` ADR-021 for verified fetch, `Pub`/
`HandlerKind::Sink` ADR-046 for put), ACL via `AccessControl` +
ownership checks (ADR-011) under the ADR-017 privilege model, service
discovery, and N-channel multiplexing; established data-path patterns
(`BiStream`, two-pump `pump_bidi` ADR-050). The store layer itself
stays alkcall-free (principle 1: substrate-agnostic); alkcall enters
only at the ops module/sibling boundary.
only at the ops module/sibling boundary — which is where transport,
if p2p git ever needs a specific one, enters above *that*.
## Open Questions
@@ -330,11 +338,12 @@ are now settled separately.
decision rather than an inherited assumption.) The original draft's
"undecided pending the first consumer's shape" conflated two things:
iroh-blobs' *actual* weld (no Store trait — its message-actor store is
inseparable from the irpc transport machinery, the thing convention 7
inseparable from the irpc protocol machinery, the thing convention 7
rejects) and the presence of a protocol substrate under the ops layer,
which is a different layer entirely and is family-standard. The
inverted-point posture constrains the *store layer only*: the store
grows no transport, framing, or auth internals. It does not argue for
grows no wire framing, op dispatch, ACL, or transport internals. It
does not argue for
an ops layer that reinvents them.
Why alkcall specifically, rather than an in-band op scheme:
@@ -362,10 +371,12 @@ Why alkcall specifically, rather than an in-band op scheme:
- **The store stays substrate-agnostic regardless.** alkcall enters
only at the ops module/sibling layer, behind the store's public
surface — the same relationship alkhttp's handlers have to their
storage. If alkcall were ever unavailable, the store layer loses
nothing (that independence is principle 1); the point is that the
ops surface, when it exists, does *not* re-implement what the
substrate provides.
storage. If the ops surface were ever re-homed, the store layer
loses nothing (that independence is principle 1); the point is that
the ops surface, when it exists, does *not* re-implement what the
substrate provides — and neither layer grows transport, which has
no home in either crate (alkcall's `Connection` is handed in, not
dialed).
**The crate-boundary question — reduced to placement only:** given an
alkcall-shaped op family, the remaining choice is where the