Files
alkgit/docs/architecture/decisions/006-http-adapter-composition.md
T
glm-5.3-flash 74029207e6 docs(architecture): record OQ-09 — slim-crate model under discussion
New open question capturing the doors-as-family-infrastructure
direction: alkssh (planned) becomes the ssh door for git, git is a
payload service exposed by downstream doors (alkhttp, alkssh, alknet),
and the crate set may slim to protocol crates + http adapter (kept in
alkgit, Slim-A, or promoted to an alkhttp git feature, Slim-B).

OQ-09 carries the three sub-decisions (alkgit-ssh deletion vs
temporary russh scaffolding; http adapter home; alkgitd consumption
path) and cross-references ADR-006 (now flagged as possibly superseded
before finalization) and OQ-01. Deferred summary table updated.
2026-09-21 04:31:11 +00:00

4.4 KiB

ADR-006: HTTP adapter composition — router factory in alkgit-http

Status

Proposed (recommendation recorded; final call pending user review — OQ-01, and now also OQ-09, whose slim-crate model may supersede this ADR's shape entirely)

Context

POC-3 proved that git smart-http runs through alkhttp's HttpAdapter::with_extra_routes surface with zero alkhttp changes: an axum Router with internal state merges under the gateway's auth layer, request bodies stream, responses stream under back pressure. The question is where that router lives so downstream users can stack git onto their own alkhttp deployment.

Two candidate shapes:

Option A — router factory in alkgit-http (this crate). alkgit-http exports a builder that takes (registry, transport hooks, identity-extractor callback, limits) and returns an axum Router ready to merge via with_extra_routes. Downstream: depend on alkhttp + alkgit-http, merge one router, wire their own auth into the extractor.

Option B — git feature on alkhttp with alkgit as an optional dependency. Downstream enables alkhttp = { features = ["git"] } and gets git routes directly.

Evaluation of Option B:

  • Dependency direction: alkhttp is a published generic sibling (0.5); the git adapter is alkgit's domain. Making alkhttp depend on alkgit inverts the layering — the generic layer would know about the git member of the family, and every alkgit adapter change would require an alkhttp release.
  • The alkcall ADR-027 precedent (from-jsonschema-as-http-adapter) puts call-protocol adapters inside alkhttp, but those are alkcall-op adapters — shared machinery for the protocol alkhttp exists to serve. Git smart-http is a foreign wire protocol (its own content types, framing, streaming shape), not a call adapter.
  • Composability rule (vision): front doors are replaceable adapters; "ALPN as a service" implies the service family member owns its adapter.
  • One-dep ergonomics is real but buyable later: alkhttp could gain a convenience feature re-exporting or wiring alkgit-http once alkgit is published — that is an alkhttp-side decision that does not constrain alkgit's shape now.

Decision (proposed)

Option A. alkgit-http owns the smart-http adapter and exposes it as an axum router factory; alkhttp stays git-agnostic and unchanged.

The factory's seam is the composability surface:

  • Input: the adapter's dependencies as traits/callbacks — peer-identity extraction (the downstream app decides how http requests authenticate, OQ-08), the core registry (repo resolution + ACL inputs, ADR-007/008), transport hooks (upload-pack/receive-pack entry points, ADR-002), and Limits (ADR-009).
  • Output: an axum Router (state finalized internally) serving exactly GET /{repo}/info/refs, POST /{repo}/git-upload-pack, POST /{repo}/git-receive-pack with the POC-3-validated framing, which the downstream merges via HttpAdapter::with_extra_routes.
  • The route set is small and stable; reserved-path collision checking (POC-3 confirmed it passes for these shapes) stays with alkhttp.
  • alkgitd is the first consumer of the factory (no special privileges); downstream apps are second users of the same seam — this is what makes the adapter genuinely composable rather than binary-only.

If a concrete downstream later demonstrates that the two-dep + merge ergonomics is a real friction point, the Option-B-style sugar can be added in alkhttp without any change here (alkhttp would gain an optional alkgit-http feature re-exporting the factory). Deciding that now is not necessary and would couple the release cadences; recording the escape hatch here is enough.

Consequences

  • alkgit controls its http adapter's cadence; alkhttp is untouched.
  • Downstream embedding is: two deps + one merge + one auth callback.
  • The identity-extractor callback is the one place downstream auth semantics enter; ACL itself stays in core (ADR-007) — adapters never hand-roll authorization.
  • This ADR stays Proposed until OQ-01 is discussed (user flagged the alkhttp-feature alternative; the escape hatch above is the recorded reconciliation path).

References

  • poc3-findings.md §"alkhttp fit" (with_extra_routes surface), follow-up 1
  • docs/research/vision.md §"ALPN as a service", §"Sub-crate shape"
  • alkcall ADR-027 (precedent and its limits)
  • ADR-001 (crate decomposition), ADR-002 (session boundary), ADR-007/008/009
  • http.md, OQ-01, OQ-08, OQ-09 (may supersede this ADR)