docs: resolve OQ-TN-08 — far-side ownership, ops-listing discovery, -D as socks5 tunnel

Untangles the 'host owns the resource and proxies on top' posture for
tunnels:
- Protocol-crate levels assume the resource is owned by the other side
  of the connection; alkcall's existing op-level ACL applies as-is. No
  new policy layer, target allowlists, or tunnel-specific ownership
  machinery. Proxy/overlay is a downstream (assembly-layer) concern
  (hub workers expose tunnels; hub overlays them per-ACL).
- Discovery resolved: openable channels are operations (alkcall
  ADR-047), so the existing bidirectional ACL-filtered ops listing IS
  tunnel-resource discovery. A consumer learns a socks5/postgres/redis
  tunnel is available from the same listing it already uses for ops.
- -D simplifies to 'just tunnel a socks5 connection': socks5 server
  lives on the producing side; target selection happens in the socks5
  protocol, not tunnel params; the dynamic-target policy residue
  dissolves (socks5 resource ACL governs reachability).

Residue for Phase 1: per-resource metadata in the ops listing
(substrate type, name/description) — an alkcall ADR-047 interaction,
not a new mechanism. OQ-TN-01 discovery residue and the hub-model
residue list cross-linked accordingly.
This commit is contained in:
2026-09-06 08:41:34 +00:00
parent 069350bd51
commit 0397194fe6
+61 -22
View File
@@ -120,11 +120,13 @@ it; direction, bind, and ACL scoping are assembly-layer concerns
wrapped around that pair.
**Residue (folded into other OQs):**
- How does a consumer *discover* produced resources — call-level
listing op, out-of-band config, or resource names? → OQ-TN-01
(params/resource naming).
- Dynamic-target policy for `-D`-style opens (which identities may open
channels to which targets) → OQ-TN-08.
- How does a consumer *discover* produced resources — resolved
2026-09-05: the existing bidirectional ACL-filtered ops listing
(openable channels are operations, alkcall ADR-047). See OQ-TN-08.
- Dynamic-target policy for `-D`-style opens — dissolved 2026-09-05:
`-D` is "just tunnel a socks5 connection"; target selection lives in
the socks5 protocol at the producing side, governed by the same
op-level ACL. See OQ-TN-08.
- Whether the hub proxy needs anything from this crate (a
re-produce helper? typed open-handler composition?) or composes from
the public producer/consumer surface as-is → spec question for
@@ -248,9 +250,11 @@ and discovery residue). Direction of travel:
- `params` identify a produced resource + substrate discriminator;
producer owns the backing. No URL-style general addressing.
- Residue: stable resource name vs target address as the identifier
shape; discovery mechanism (call-level listing op vs out-of-band
config); exact JSON field layout (Phase 1 spec, ADR before first
consumer — wire-stable once published).
shape; discovery resolved 2026-09-05 — see OQ-TN-08 (the existing
ACL-filtered ops listing IS tunnel-resource discovery, since
openable channels are operations per alkcall ADR-047); exact JSON
field layout (Phase 1 spec, ADR before first consumer — wire-stable
once published).
### OQ-TN-02: Datagram substrates (UDP) — boundary preservation
@@ -456,18 +460,46 @@ path gets `AccessControl` wiring for free via
sets), and does it live in `AccessControl` or in the open handler's
params validation?
**Status:** open — needs alkcall ADR-050 review + a survey of how
alktty scoped its gate. Half-answer (hunch): scope-gate for the open
plus an open-handler-level target policy hook; ownership for
*registered/listened* tunnels (which are persistent resources), not for
ephemeral dials. Strengthened 2026-09-05 by the hub model (§Prior art):
the "virtual port" IS an ACL-scoped registered resource — so
`register_openable` per-resource registration is the primary gate
shape, and ownership naturally attaches to produced resources
(persistent), not to ephemeral dials. Remaining: the dynamic-target
policy hook for `-D`-style opens (which identities may open channels to
which targets when targets arrive per-channel), and whether that policy
lives in `AccessControl` or in the open handler's params validation.
**Status: mostly resolved 2026-09-05** — this OQ pointed at a general
conceptual tangle ("the host owns the resource and proxies on top of
that" — how does that manifest for tunnels?), and the resolution is
the same posture alktty already uses:
- **Assume the resource is owned by the other side of the connection.**
At these protocol-crate levels (alktunnels, like alktty), the
protocol works under the assumption that a produced resource belongs
to the far side — so the ACL story is exactly alkcall's existing
op-level ACL. No new policy layer, no target allowlists, no
tunnel-specific ownership machinery. The actual proxy/overlay
mechanism (hub workers connecting in and exposing tunnels, the hub
providing an overlay to those resources based on the other side's
ACL) is a *downstream* (assembly-layer) concern.
- **Discovery is the existing bidirectional ops listing.** alkcall
already has an underlying bidirectional discovery mechanism — each
side can obtain the list of ops available to it (ACL-filtered). Since
openable channels *are* operations (alkcall ADR-047), that listing
*is* tunnel-resource discovery: a consumer asks "what ops are
available to me" and produced tunnel resources appear there, scoped
by identity. This is exactly how a consumer learns a socks5 tunnel,
a postgres TCP tunnel, or a redis tunnel is an available resource.
Examples of the pattern: services typically served over a VPN or
SSH tunnels (postgres, redis, gitea HTTP) — workers connect to a
hub, expose those tunnels, and the hub proxies them per-ACL.
- **`-D` simplifies to "just tunnel a socks5 connection."** The socks5
server lives on the producing side; the consumer opens an ordinary
tunnel channel to that resource and speaks socks5 inside it. Target
selection happens in the socks5 protocol at the far side — *not* in
tunnel params — so the previously-tracked "dynamic-target policy
hook for `-D`-style opens" residue dissolves: whatever ACL governs
the socks5 resource governs everything reachable through it, plus
whatever policy the socks5 implementation itself applies downstream.
Residue for Phase 1 (spec-shape, not research): confirm the
ops-listing surface carries enough per-resource metadata (substrate
type, resource name/description) for a consumer UI to distinguish
produced tunnels — or whether `params`-describing metadata rides
alongside the operation spec. That is an alkcall ADR-047 interaction,
not a new mechanism.
### OQ-TN-09: Lifecycle, teardown, and error reporting
@@ -556,14 +588,21 @@ Candidate reading for the research specialist (to be expanded):
object identifying a produced resource + substrate
discriminator (`tcp`/`udp`/extensible); producer owns the
backing; no URL-style general addressing. Residue: resource
naming shape, discovery mechanism, exact JSON layout (Phase 1
ADR)
naming shape, exact JSON layout (Phase 1 ADR); discovery
resolved (OQ-TN-08)
- [x] Direction model resolved (OQ-TN-03) — hub-owns-the-connection
model: role follows the resource, no protocol-level direction;
`-D` composes at the assembly layer
- [x] No-forced-binding requirement encoded (OQ-TN-04) — binding is
always assembly-layer and optional; remaining work is the
concrete produce/consume API surface sketch (spec task)
- [x] Access control + discovery resolved (OQ-TN-08) — resource
ownership assumed on the far side; alkcall's existing ACL
applies as-is; ops listing (ADR-047) is tunnel-resource
discovery; `-D` = "tunnel a socks5 connection" (target selection
in the socks5 protocol, not params). Residue: per-resource
metadata in the ops listing (alkcall ADR-047 interaction,
Phase 1)
- [ ] Decision input: backend trait vs no-trait (OQ-TN-05), now
including the hub re-produce composition question
- [ ] Targeted POC(s) run + summary (OQ-TN-10) — UDP first, reverse