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:
1 parent
70815e22a0
commit
8f73da5d12
21 files changed
+1669
No files matched your search
@@ -0,0 +1,119 @@
|
||||
---
|
||||
status: draft
|
||||
last_updated: 2026-09-21
|
||||
---
|
||||
|
||||
# Overview: alkgit
|
||||
|
||||
## Purpose
|
||||
|
||||
alkgit is a self-hosted git server: repository storage, the git smart
|
||||
protocol served over http and ssh interfaces, and the `alkgitd` binary that
|
||||
assembles it all. It exists to provide a small, security-first git platform
|
||||
whose exposure model inverts the mainstream pattern (visible-surface =
|
||||
authorized-surface, authenticated-by-default, no plaintext secrets, no
|
||||
plugin execution). See `docs/research/vision.md` for the full WHY.
|
||||
|
||||
## The one-line architecture
|
||||
|
||||
**Storage + ACL + protocol adapters.** `alkgit-core` owns repository storage
|
||||
and access-rule types; `alkgit-transport` owns the git protocol state
|
||||
machines; `alkgit-http` and `alkgit-ssh` are thin front doors that
|
||||
authenticate, resolve the repo, and hand a session to the transport;
|
||||
`alkgitd` assembles everything with config, TLS/ACME, and the vault.
|
||||
|
||||
## Crate map
|
||||
|
||||
| Crate | Owns | Depends on | Never depends on |
|
||||
|---|---|---|---|
|
||||
| `alkgit-core` | repo registry/storage roots, odb wrappers, ref store, pack generate/ingest, fsck, ACL input types | gix crates, alkcall (ACL types only) | any front-door crate |
|
||||
| `alkgit-transport` | pkt-line sessions, V2 advertisement/state machine, ls-refs, fetch, receive-pack | `alkgit-core`, alkcall, gix-packetline | alkhttp, alkgit-ssh |
|
||||
| `alkgit-http` | smart-http endpoints over alkhttp | transport, core, alkhttp | alkgit-ssh, alkgitd |
|
||||
| `alkgit-ssh` | git-command dispatch for exec requests over alkcall channels | transport, core, alkcall | alkhttp, alkgitd |
|
||||
| `alkgitd` | binary: config, assembly, TLS/ACME, listeners, vault wiring | everything | — |
|
||||
|
||||
Dependency rules (ADR-001, ADR-002):
|
||||
|
||||
1. `alkgit-core` + `alkgit-transport` are **front-door-blind**: they consume
|
||||
(identity, repo id, duplex stream, limits) and depend on alkcall types
|
||||
only. No http types, no ssh channel types below the stream.
|
||||
2. `alkgit-http` and `alkgit-ssh` never depend on each other.
|
||||
3. `alkgitd` is the only crate allowed to know the whole graph.
|
||||
4. A downstream application (gitea-like) embeds core + transport and brings
|
||||
its own front doors; the admin API is a set of alkcall ops it may use or
|
||||
replace.
|
||||
|
||||
## Security invariants (spec-level, all components honor)
|
||||
|
||||
These are the load-bearing rules from `docs/research/vision.md` and
|
||||
`docs/research/alk-stack.md`; each component doc references them where
|
||||
concrete:
|
||||
|
||||
1. **Authenticated by default** — anonymous fetch exists only on
|
||||
explicitly-public repos; push is always authenticated.
|
||||
2. **Visible-surface = authorized-surface** — via alkcall ACL; ops with
|
||||
`Visibility::Internal` are never wire-callable; admin ops ride an admin
|
||||
surface, never the git traffic surface.
|
||||
3. **ACL before advertisement** — access is checked before any ref line or
|
||||
capability line is emitted (ref names leak repo existence) (ADR-007).
|
||||
4. **Registry-resolved repo identity** — wire-supplied repo names are IDs
|
||||
resolved to server-configured storage roots; never used as paths (ADR-008).
|
||||
5. **No secret material on the wire or at rest outside alkvault** — metadata
|
||||
holds vault references only; outbound credentials flow through alkcall
|
||||
`Capabilities` (alkcall ADR-010), and no handler reads credentials from
|
||||
env or files (the no-env-vars invariant).
|
||||
6. **No shelling out to `git`** — serving path is pure Rust on gix
|
||||
primitives (GPL hygiene + no process-injection surface).
|
||||
7. **Bounded resources** — every session carries wall-clock, size, and round
|
||||
limits (ADR-009); unbounded loops/buffers are bugs.
|
||||
8. **Honest capability advertisement** — the protocol advertises exactly
|
||||
what we serve (ADR-003).
|
||||
|
||||
## Interfaces (the boundary shape)
|
||||
|
||||
The core boundary, from POC-1 (`docs/research/poc-1-findings.md`, follow-up 4) and the
|
||||
"ALPN as a service" rule in `docs/research/vision.md`:
|
||||
|
||||
- **Transport input**: one session = (peer identity from alkcall
|
||||
`AuthContext`, repo id resolved against the registry, a duplex byte
|
||||
stream, session limits). For the stateless http door this becomes
|
||||
(identity, repo, request-reader, response-writer, limits) — the same state
|
||||
machines, a different substrate (ADR-005).
|
||||
- **Storage input**: the transport asks core for (a) ref advertisement data,
|
||||
(b) pack generation for a want/have set, (c) pack ingestion + ref
|
||||
transactions for receive-pack. Storage never sees pkt-lines.
|
||||
|
||||
## What is already validated (POC-backed)
|
||||
|
||||
- pkt-line over alkcall `BiStream` end-to-end (POC-1).
|
||||
- Pack generation pipeline streaming with O(counts) memory (POC-2).
|
||||
- Smart-http streaming both ways through alkhttp custom routes (POC-3).
|
||||
The full V2 fetch path against real git 2.43 is proven; receive-pack is
|
||||
designed but not yet exercised (OQ-04 tracks the POC/validation gap).
|
||||
|
||||
## Design Decisions
|
||||
|
||||
| ADR | Decision | Summary |
|
||||
|---|---|---|
|
||||
| [001](decisions/001-crate-decomposition.md) | Crate decomposition | 5 crates: core, transport, http, ssh, alkgitd |
|
||||
| [002](decisions/002-front-door-blind-core.md) | Front-door-blind core | Session boundary = (identity, repo, stream, limits) |
|
||||
| [003](decisions/003-protocol-v2-first.md) | V2-first protocol | V2-only fetch on both doors; honest advertisement; multi-round negotiation sequenced (OQ-02); push surface OQ-04 |
|
||||
| [004](decisions/004-pack-pipeline.md) | Pack pipeline | gitoxide `data::output` generation, streaming-input ingestion |
|
||||
| [005](decisions/005-session-substrate-types.md) | Substrate types | Duplex + stateless session APIs over one state machine |
|
||||
| [006](decisions/006-http-adapter-composition.md) | HTTP adapter composition | Router factory in alkgit-http (**proposed**, OQ-01) |
|
||||
| [007](decisions/007-acl-before-advertisement.md) | ACL first | No ref/capability line before ACL passes |
|
||||
| [008](decisions/008-registry-resolved-repo-identity.md) | Repo identity | Wire names are registry IDs |
|
||||
| [009](decisions/009-bounded-resources-budget.md) | Budgets | Every session carries limits |
|
||||
|
||||
## Open Questions
|
||||
|
||||
Key cross-cutting questions tracked in [open-questions.md](open-questions.md):
|
||||
|
||||
- **OQ-01**: http adapter composability (where the smart-http routes live
|
||||
for downstream embedding) — affects http.md and ADR-006.
|
||||
- **OQ-04**: receive-pack (push) validation gap (high — the
|
||||
always-authenticated half of the wire surface).
|
||||
- **OQ-08**: identity sources per front door (how http and ssh authenticate
|
||||
peers in v1).
|
||||
- **OQ-06**: metadata store backing for the registry (config-file vs
|
||||
embedded store vs alkcall-hosted).
|
||||
Reference in new issue
Block a user