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).
4.5 KiB
ADR-006: HTTP adapter composition — router factory in alkgit-http
Status
Superseded by ADR-010 (pure protocol crate — the http mounting moves to an
alkhttp git feature; the stateless substrate stays in alkgit)
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
(Historical: this ADR was written as a proposal with the router factory recommended; OQ-09/OQ-01 later resolved in favor of the alkhttp feature instead, and ADR-010 superseded this ADR. Text below preserved as written.)
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 exactlyGET /{repo}/info/refs,POST /{repo}/git-upload-pack,POST /{repo}/git-receive-packwith the POC-3-validated framing, which the downstream merges viaHttpAdapter::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.
alkgitdis 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.
(Historical) A concrete downstream later confirmed the ergonomics
friction; the Option-B sugar — an alkhttp git feature — was chosen as
the outcome (OQ-01/OQ-09), and ADR-010 adopted it as the structural
decision, superseding this ADR.
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.
- (Historical) This ADR was Proposed pending OQ-01; OQ-01/OQ-09 resolved in favor of the alkhttp-feature alternative recorded below the escape-hatch note, and ADR-010 superseded this ADR outright.
References
poc3-findings.md§"alkhttp fit" (with_extra_routes surface), follow-up 1docs/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
- OQ-01 (resolved), OQ-08, OQ-09; superseded by ADR-010