Renames the written-usage rule into practice across the contract surface: docs/ (architecture, research, plans, sdd), tasks/ (all 43 task files, taskgraph validate passes), AGENTS.md, README.md, CHANGELOG.md, and the .opencode/agents/ prompts. Every replacement is a sense-preserving rewrite (colons, semicolons, commas, parentheses, sentence splits, varied), never a mechanical swap; no spaced hyphens were substituted. Enum fields, frontmatter, tables, wire data, and cited identifiers survive verbatim; en dashes inside numeric ranges keep their meaning. Verification: taskgraph validate (43 tasks), repo grep clean (single exempt hit: the verification command's own search pattern in AGENTS.md), cargo test, clippy --all-targets -D warnings, fmt --check, doc all green.
5.6 KiB
status, last_updated
| status | last_updated |
|---|---|
| reviewed | 2026-10-28 |
ADR-006: Mapping decisions (route-1 bridge, exec-only git, session dispatch)
Status
Accepted (2026-10-26). All three decisions are
POC-3-validated against published sibling crates; amendments are new
ADRs. Amended same day (review untangle): point 3's SOCKS-detect is
retired: with the dynamic-forward feature removed (ADR-003 §1a),
session dispatch is parse-only and a request-less session channel
simply declines. The parse-vs-anything split was only ever needed if
a session channel could be a SOCKS stream; no consumer is that
client (vanilla -D rides direct-tcpip; the family -D door is
client-local, alksocks composed at the assembly). POC-3 stage B's
evidence survives as: (a) the load-bearing correction that vanilla
-D = client-side SOCKS + plain direct-tcpip, (b) proof that
SOCKS-in-channel is feasible if ever wanted back.
Context
mapping-table.md left three choices explicit for the architecture
pass: which of alktunnels' two routes serves direct-tcpip; whether
git over SSH has a subsystem path; and the session-channel dispatch
shape when one channel type serves both parseable commands and
SOCKS5-in-channel traffic. POC-3 resolved all three by construction
(real git 2.43, real curl 8.5, real OpenSSH through published
alkgit/alksocks/alktunnels/alktty).
Decision
direct-tcpiprides the adapter-side bridge (alktunnels route 1). alkssh holds aChannelClientinto the family fabric and callsTunnelSession::open_direct(client, target, substrate), pumpingtake_halves()against the russh channel (channel_open_direct_tcpip→ accept only after the fabric open succeeds →copy bidirectional). POC-3 stage C proved it end to end (8 MiB in ~333 ms; fabric-open failure maps to an explicit SSHConnectFailedreject; accept happens only post-success, sinceaccept()consumes the handle). Registry-side bridging (route 2: alkssh-shapedChannelOperationsin a serving endpoint's registry) is rejected: it inverts the door posture by putting adapter work upstream of the door. The alktunnels absence note (no serve-over-stream entry) is thereby resolved, as route 1 never needed one.- Git over SSH is exec-only; every subsystem request declines.
The vanilla git connection model is: git spawns its ssh transport,
which opens one session channel and sends
exec_request "git-{upload,receive}-pack '/repo'", so the repo path rides inside the command string, and a subsystem request (name only, no repo id) can never dispatch. POC-3 proved the parse grammar (quoted/unquoted paths, service-only → decline, non-git → parse-then-fail with no resource alloc) and clone/push/second-push through the published seam with zero fixups. Vanilla git behavior loses nothing: vanilla git never speaks subsystem for git; the decline only refuses a manualssh -s-style invocation, with a reason. Session-channel dispatch: request-driven parse wins; detect covers the request-less case(amended: parse-only). The original decision composed the POC-3 modes as: requests take the parse path (git undergit, pipe/shell undersession); request-less session channels ran a SOCKS-detect (dynamic-forward: spawn, first-byte0x05sniff, 500 ms bounded window). Withdynamic-forwardremoved from the feature graph (ADR-003 §1a), the detect has no owner: session dispatch is parse-only: requests parse to git (exec) or pipe/shell, and a request-less session channel declines as unfeatured. This still resolves OQ-02 (the composition was the unknown; the resolution is now the simpler of the two candidates).- The spawn-and-return rule is a structural constraint, not an
implementation detail. russh 0.64.1-era servers run handler
callbacks inline inside the session's packet loop, so a blocking
handler deadlocks against the peer's follow-up bytes (POC-3
proved by construction: receive-pack pushes bytes immediately
after the exec request). Every serving path is
tokio::spawn+ handler-returns-fast; exit reporting from the spawned task rides the clonedSession::handle():exit-status(thenclose) before channel close,exit-signalfor signal termination (signal-name fidelity: the derivation contract onmapping.md's exit rows; OQ-10 resolved).
Consequences
- Positive: every one-seam-per-mapping row now has its route recorded; the OQ list loses its highest-priority pending item; the alkforge assembly gets an exact wiring recipe (POC-3 §C.4's in-process fabric leg is the template, verbatim).
- Negative: the SOCKS-detect retirement removes a tunable the POC proved workable; if a family client ever wants a remote SOCKS door, the shape is re-addable via ADR (500 ms bounded window preserved in the reference here).
- Neutral: route 2 remains documented in
mapping-table.mdas the rejected alternative, with its rationale, useful if the posture is ever revisited (that revisit is an ADR, not a code flip).
References
docs/research/poc-3-mapping-bakeoff.md(stages A–C: all three decisions' evidence; §C.4 the fabric wiring recipe)mapping-table.md(the rows + the absence note this ADR resolves)- ADR-003 (the feature gates these dispatch decisions sit behind)
docs/research/reverse-runner.md(the client-direction mirror of leg 1, the-L/-Rlegs the same route-1 bridge serves)- OQ-02 (resolved by this ADR), OQ-10 (resolved: the derivation
contract lives on
mapping.md's exit rows, and the PTY-path signal-identity limitation is recorded upstream on the alktty/portable-pty side)