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.
This commit is contained in:
glm-5.3-flash committed 2026-09-21 03:55:33 +00:00
1 parent 70815e22a0
commit 8f73da5d12
21 files changed
+1669

No files matched your search

@@ -0,0 +1,91 @@
# ADR-006: HTTP adapter composition — router factory in alkgit-http
## Status
Proposed (recommendation recorded; final call pending user review — OQ-01)
## 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
- `docs/research/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