Greenfield architecture spec set for the alknet-docker crate — a thin,
single-host bollard wrapper exposing docker container/image operations
as call-protocol ops on the shared alknet/call ALPN, plus a
DockerTtyBackend (impl TtyBackend) behind a tty feature for interactive
terminal sessions into containers over alknet/tty.
Six ADRs:
- 058: docker ops on alknet/call (no separate ALPN; raw-carriage handoff
dissolved by alknet-tty extraction — interactive attach moved to
alknet/tty via DockerTtyBackend, no carriage field on call.requested)
- 059: bollard 0.21 (verified current on crates.io) + feature selection
(http+pipe+time; no ssl/ssh/websocket/buildkit)
- 060: container resource model (ADR-050 application) — alknet.managed/
alknet.owner labels, list owned_only flag, hosted-services operator
role via static-resource fallback, handler-driven revoke with
autonomous-death tolerance, resource-action vocabulary
- 061: DockerTtyBackend in alknet-docker behind tty feature (attach vs
exec mode; POC drive_attach_raw as reference)
- 062: Docker client + OwnershipStore injection via closure capture
(not Capabilities, not OperationContext — matches from_openapi pattern)
- 063: exit code on terminal call.responded for non-interactive exec
(call.completed stays empty, ADR-012 unchanged)
Four spec docs (crates/docker/): README, overview, docker-operations,
docker-tty-backend. Four deferred-scope OQs (048-051): network/volume
ops, buildkit, system events subscription, create options surface.
Updates the tty-backend.md Backend implementations table (DockerTtyBackend
row now specced) and the architecture README (doc table, ADR table,
current-state paragraph, OQ count).
Grounded in the alknet-docker POC (docs/research/alknet-docker/poc-summary.md)
which validated the hard parts; the remaining lifecycle ops are mechanical
bollard wrapping. Reviewed by architecture-reviewer subagent; criticals
(the docker_client injection model conflicting with the Capabilities
contract) resolved via ADR-062/063 before commit.
Each open question lives in its own file under questions/,
named NNN-slug.md (mirroring the ADR convention). This file is the index:
theme-grouped tables for scannability, plus a cross-theme
Deferred / Blocked section that surfaces the
safe-exit deferrals with their blocking conditions inline — so "what's
currently parked and why" is answerable at a glance.
Status values:
open — Needs to be resolved now. Has a clear path to resolution.
resolved — Decided. The resolution is stated cleanly, without caveats about how it could be changed later.
deferred(scope) — Cannot be resolved yet. The information doesn't exist. Has a concrete blocking condition (e.g., "blocked on: alknet-agent crate spec"). Not a failure — scope management.
partially resolved — Some aspects decided, others deferred or open.
dissolved — The question was reframed out of existence (e.g., superseded by an ADR that retires the premise). Kept for reference.
Door type classifications follow ADR-009 — they describe reversal cost (how expensive it is to undo), not urgency:
One-way door: Reversal requires rewriting significant code or permanently closes a capability. Getting it wrong is expensive — requires ADR before implementation.
Two-way door: Reversal is cheap or additive. Getting it wrong is recoverable — decide, implement, revert if needed.
Door type is separate from whether a decision is made. A two-way door is a decision you make now and can revert later, not a decision to defer. See ADR-009 §"What this framework is NOT."
The safe-exit visibility surface. These questions are parked because the
information needed to resolve them does not exist yet — each has a concrete
blocking condition. They are not failures; they are scope management. See
ADR-009 §"Safe Exit: Deferred Decisions." This section exists so "what's
currently blocking the architect" is answerable at a glance, not by
filtering the tables above.
OQ-09: WASM Target Boundaries
Blocked on: A concrete server-side WASM use case, or a deliberate confirmation that WASM stays a client-side design constraint. Tracked as architecture/oq-09-wasm-server-use-case in tasks/architecture/.
OQ-10: Git Adapter Scope — Smart Protocol Only or Full Server?
Blocked on: Speccing the alknet-git crate — resolve this when that crate is specified, not deferred past it. Tracked as architecture/oq-10-git-adapter-spec in tasks/architecture/.
Blocked on: A handler that needs stream operators and finds the existing combinators (Box::pin(stream::iter(...)), async_stream::stream!, futures::stream) insufficient. The operators library is a convenience, not a prerequisite for any handler.
Blocked on: a concrete use case for network or volume management over the call protocol. Dev containers use the default bridge network; hosted services declare networks/volumes in docker compose.
Blocked on: a concrete use case for prompt stale-ownership cleanup. The base model (ADR-060 §4) tolerates inert stale entries; the events subscription is a refinement.
Blocked on: v1 implementation — the create input JSON Schema is finalized when register_docker_ops is written and tested against bollard's Config struct. An architectural decision (ADR-060 §5), not a deferral past implementation.