Files
alkgit/docs/architecture/transport.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

5.5 KiB

status, last_updated
status last_updated
draft 2026-09-21

alkgit: Git Smart Protocol (wire layer)

What it is

The wire half of the alkgit protocol crate: pkt-line session substrates, protocol V2 state machines (advertisement, ls-refs, fetch, receive-pack), and the substrate types that keep doors and handlers from touching futures_io or raw packetline APIs. Depends on alkcall and — only under the gix feature — the backend implementations (ADR-010). The wire layer itself is backend-trait-only, which is what makes default-features = false compile without gix.

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 (the alk/git ALPN producer, channels-opened git sessions, embedder 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 doors, e.g. alkhttp's future git feature) — 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). IO-abstract: the door supplies reader/writer; see doors.md for the mounting.

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). git-upload-archive is not served (fixed refusal — ADR-008's never-execute rule, ssh analog in doors.md).

ls-refs

  • Parse command=ls-refs (peel, symrefs, ref-prefix), stream ref lines from the backend'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 GitPackGen (ADR-004), streamed over sideband on duplex / sideband-in-response on http; generation runs on spawn_blocking with the owned 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).
  • Ingestion via GitPackIngest (ADR-004); 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)

Crate-root re-exports (alktty pattern; the full list in backend.md §public API): GitAdapter + register_openable, GitSession, substrate types, Limits, the backend traits (ADR-010's seam), protocol error enums; gix-feature types under the feature. Publish-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
010 Pure protocol crate wire layer is backend-trait-only

Open Questions

  • OQ-02: V2 multi-round negotiation (open — efficiency, not correctness).
  • OQ-04: receive-pack state machine + validation (deferred(unclear)).
  • OQ-03: publish/API freeze (partially resolved — single-crate shape settled by ADR-010).
  • 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)
  • alktty wire.rs/session.rs/adapter.rs (the template's half shapes)