Files
alkgit/docs/architecture/transport.md
T
glm-5.3-flash 8f73da5d12 docs(architecture): phase 1 bootstrap — specs, 9 ADRs, OQ tracker
Architecture documentation structure per sdd_process phase 1:

- README index (doc table, ADR table, lifecycle), overview with crate
  map, dependency rules, and security invariants
- Component specs: storage, transport, http, ssh, alkgitd (all draft)
- ADRs 001-009: crate decomposition, front-door-blind core, V2-first
  protocol, pack pipeline (data::output generation / data::input
  ingestion), session substrate types, http adapter composition
  (proposed, OQ-01), ACL-before-advertisement, registry-resolved repo
  identity, bounded-resources budgets
- open-questions.md: OQ-01..08 with two deferred(scope), one
  deferred(unclear), door-type definitions, blocker tracker tasks in
  tasks/architecture/
- v1 ssh-door decision recorded: russh terminates wire SSH in alkgitd;
  alkcall channels stay the internal substrate (OQ-03 partially
  resolved)

Two review rounds (fresh-context subagent): 4 critical + 17 warnings
fixed in round one; zero critical + 4 warnings + 5 suggestions fixed in
round two. All ADR/OQ cross-references verified resolving.
2026-09-21 03:55:33 +00:00

4.7 KiB

status, last_updated
status last_updated
draft 2026-09-21

alkgit-transport: Git Smart Protocol

What it is

The git protocol layer: pkt-line session substrates, protocol V2 state machines (advertisement, ls-refs, fetch, receive-pack), and the glue that keeps adapters from touching futures_io or raw packetline APIs. Depends on alkgit-core and alkcall types only (ADR-001/002).

Substrate layer (ADR-005)

Two session entry points over one state-machine core. ADR-005 owns the full decision (what each substrate owns and why); the surface is:

  • Duplex session (ssh, git://, embedded stream doors) — input: (peer identity, resolved repo id, duplex stream, Limits). Encapsulates the split/compat/packetline bridge, the request reader (delim-aware parsing, reset() discipline, break-on-error), and the sideband writer.
  • Stateless session (smart-http) — input: (peer identity, resolved repo id, request-reader, response-writer, Limits) per http POST; adds the http-framing rules (capability-dump skip, flush-only responses, probe handling).

Both substrates feed the same V2 state machines; statelessness is a substrate property (per-request state), not a protocol fork.

Protocol core (ADR-003: V2-first)

Advertisement

  • Emitted once per duplex session (never between commands — real git hangs on re-advertisement); per-request-set on http (stateless: the client re-sends the dump).
  • Honest capability list: exactly what we serve (ls-refs=unborn, fetch=wait-for-done for the v1 done-path policy — ADR-003 pins the values; OQ-02 may extend them when multi-round lands, object-format=sha1). Unimplemented features are declined by omission (validated against real git, POC-1).

ls-refs

  • Parse command=ls-refs (peel, symrefs, ref-prefix), stream ref lines from core's listing, flush. ref-prefix filtering is client-driven.

fetch

  • Parse wants/haves/done/args; object-format check (reject mismatches — POC-1 to-do).
  • Negotiation policy (v1 initial): full-closure pack on done (POC-validated). Multi-round ack/NAK negotiation: OQ-02.
  • Pack generation via core (ADR-004), streamed over sideband on duplex / sideband-in-response on http; generation runs on spawn_blocking with the owned odb handle moved in (POC-2's shape: store shared, handle per session, generation on blocking threads).
  • Round/haves budgets enforced here (ADR-009).

receive-pack (push)

  • Parse update requests (<old> <new> <ref> + shallow lines), ingest the pack stream (POC-3-verified: request bodies stream), apply CAS transactions, emit status report. The capability set, shallow policy, CAS timing, and exact status-report shape are OQ-04's investigation target (design intent: shape per OQ-04's resolution).
  • Validation pending — OQ-04 (includes the receive-pack version surface, which ADR-003's fetch-V2 decision does not cover).

Error taxonomy

  • io errors are terminal (session ends); protocol errors map to pkt-line error bands (duplex) or http status + body (stateless). Substrate-level thiserror enum; no panics in library code (convention 2).

Limits

Every session carries Limits (ADR-009): negotiation rounds, haves per round, receive-pack max size, wall clock, sideband chunk size (fixed 65000), advertisement ref cap. Missing Limits is a type-level error.

Public API surface (v1)

lib.rs re-exports: Session (duplex) + StatelessRequest (http) entry points, Limits, hook trait(s) connecting to core (advertisement data, pack generation, ingestion), protocol error enums. The exact embedder-facing freeze point: OQ-03.

Design Decisions

ADR Decision Summary
002 Session boundary duplex + stateless entry points
003 V2-first honest advertisement, V0/V1 declined
004 Pack pipeline generation on blocking threads, O(counts)
005 Substrate types request reader, sideband sink, http framing rules
009 Budgets Limits in every session tuple

Open Questions

  • OQ-02: V2 multi-round negotiation (open — efficiency, not correctness).
  • OQ-04: receive-pack state machine + validation (deferred(unclear)).
  • OQ-03: embedder API freeze (deferred(scope)).
  • OQ-05: sha256 policy (deferred(scope)).

References

  • docs/research/poc-1-findings.md, docs/research/poc2-findings.md, docs/research/poc3-findings.md (the normative wire behavior — observed against real git, not docs' grammar)
  • docs/research/git-protocol.md (inventory + observed corrections)
  • docs/research/gitoxide.md §"Wire format" (packetline contracts)