Files
alkgit/docs/architecture/decisions/002-front-door-blind-core.md
T
glm-5.3-flash 86bf5a0cf0 refactor(architecture): ADR-010 — pure protocol crate (alktty template)
Structural decision (OQ-09 resolved): alkgit follows the alktty/
alktunnels template — a single published protocol crate on alkcall
channels, no binary, no front doors.

- ADR-010 supersedes ADR-001 (crate decomposition) and ADR-006
  (http router factory); both marked Superseded
- Single crate at repo root: Cargo.toml with gix feature (default-on
  backend implementations; wire layer compiles without it —
  gix-hash always-on with sha1 per the compile-time-rejected
  invariant), crates/ workspace deleted, src/lib.rs stub in place
- doors.md replaces http.md/ssh.md/alkgitd.md: alkhttp git-feature
  sequencing (after first publish), alkssh requirement (fixed-grammar
  exec dispatch), native alk/git path, downstream assembly
- backend.md replaces storage.md: GitRegistry/GitRefs/GitPackGen/
  GitPackIngest traits (ingest validates, refs commits — single CAS
  home), gix feature encodes POC-2 prerequisites
- transport.md reframed for the single crate; backend traits replace
  hook traits in the public API
- OQ-09 resolved (all five sub-decisions in ADR-010), OQ-01 resolved
  (subsumed), OQ-03 narrowed to publish-freeze, OQ-08 narrowed to
  registry identity + vault placement, OQ-07 rescoped to the gix
  feature's registry impl
- vision.md v2: single-binary/monorepo framing corrected as
  init-agent artifact; POC checklist marked complete
- AGENTS.md + .opencode agent specs updated to the new shape

Verification: cargo build (default + no-default-features), cargo test
--all-features, clippy --all-features -D warnings, fmt --check all
pass. Third review round: zero critical, all warnings/suggestions
addressed (GitPackGen signature amended in ADR-004, stale anchors
fixed, ADR-006 body tense normalized, CAS split stated, vision
residuals cleaned).
2026-09-21 10:54:03 +00:00

3.2 KiB
Raw Blame History

ADR-002: Front-door-blind core — the session boundary

Status

Accepted

Context

The load-bearing composability rule ("ALPN as a service", docs/research/vision.md): alkgit (the single crate) must never know which front door is talking. POC-1 proved the exact shape survives the wire: Connection::accept_bi() → BiStream → tokio::io::split → tokio-util compat → gix-packetline ran a full V2 fetch against real git. POC-3 proved the stateless-http variant: the same protocol state machines ran per-POST over (request-reader, response-writer) instead of a duplex stream.

The question this ADR settles: what is the interface the core/transport exposes to adapters?

Alternatives considered:

  • Adapters implement an alkcall-style ProtocolHandler themselves and call into transport with raw BiStream — pushes too much protocol responsibility (advertisement timing, framing errors) into every adapter.
  • Transport speaks alkcall Connection directly — forces stateless http (one request per connection) through a session-shaped API; wrong shape for http, and couples transport to alkcall connection lifecycle.
  • HTTP-specific abstractions in transport — violates the blind-core rule.

Decision

The transport exposes two session entry points, both consuming the same tuple (peer identity, resolved repo, limits):

  1. Duplex session (ssh, git://, any stream door): transport consumes a BiStream-shaped duplex byte stream (AsyncRead + AsyncWrite + Unpin, the alkcall BiStream contract, alkcall ADR-005/009) and runs the advertise-once → command-loop state machine. Adapters hand it over after ACL and repo resolution (ADR-007, ADR-008).
  2. Stateless session (smart-http): transport consumes a (request-reader, response-writer) pair per http request and runs one command per invocation, matching smart-http's stateless framing. The same core state machines run under both entry points.

Storage-facing side: the wire layer calls the backend traits for advertisement data, pack generation (want/have set in → streaming pack out), and pack ingestion + ref CAS (receive-pack). Storage never sees pkt-lines.

The futures-io bridging detail (tokio_util::compat), the split/compat glue, and the packetline stop-delimiter handling live inside transport — adapters never see futures_io types (POC-1 follow-ups 1–2, POC-3 follow-up 2).

Consequences

  • The core+transport pair is embeddable with any front door; POC-1/3 are existence proofs of both shapes.
  • State machines are written once; http statelessness is a substrate property, not a protocol fork.
  • Transport depends on alkcall types only (BiStream shape, identity, limits) — no alkhttp, no channel types below the stream.
  • One cost: the stateless entry point needs explicit per-request limits (body budget, wall clock) since there is no session to amortize them (ADR-009).

References

  • docs/research/vision.md §"ALPN as a service"
  • docs/research/poc-1-findings.md (duplex shape validated), docs/research/poc3-findings.md (stateless shape validated)
  • alkcall ADR-005 (BiStream type), ADR-009 (BiStream as handler leaf)
  • ADR-005 (substrate types detail), ADR-007/008 (what adapters do before calling transport)
  • overview.md §"Crate map"