diff --git a/AGENTS.md b/AGENTS.md index f305e7f..61a1214 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -149,6 +149,14 @@ implementation agents. `alkgit-transport` (smart protocol), `alkgit-http` (http front door), `alkgit-ssh` (ssh front door), `alkgitd` (binary). +15. **Composability boundary ("ALPN as a service")** — `alkgit-core` + + `alkgit-transport` are front-door-blind: they consume (identity, repo + id, duplex stream, limits) and depend on alkcall types only, never on + alkhttp/alkgit-ssh, and carry no http/channel-specific types below the + stream. The http and ssh crates are replaceable adapters; a downstream + app embeds core + transport and brings its own front doors. v1 is the + reduction to storage + ACL + protocol adapters. + ## Verification Commands Run these before committing. All must pass. diff --git a/docs/research/alk-stack.md b/docs/research/alk-stack.md index ca515a7..04845bf 100644 --- a/docs/research/alk-stack.md +++ b/docs/research/alk-stack.md @@ -72,7 +72,10 @@ Both interfaces converge on the same core: **a `BiStream`-like duplex session + repo identity + caller identity** → `alkgit-transport` runs the smart protocol and produces/consumes packs via `alkgit-core`. The interfaces are thin adapters; all policy (auth, ACL, limits) lives before the transport -layer gets the stream. +layer gets the stream. This is the same "ALPN as a service" shape as +alktty/alktunnels/alksocks: the git member of the family, one core, many +front doors, and nothing below the transport boundary knows or cares which +door produced the stream. ## What to verify before architecture commits (POC candidates) @@ -87,6 +90,19 @@ layer gets the stream. as raw duplex streams rather than chunk-framed channels if needed. 4. **alktls ACME**: config shape for the http endpoint; likely trivial. +## Composability boundary (what "ALPN as a service" implies here) + +Same family pattern as alktty/alktunnels/alksocks (alknet decomposition): +one core that is front-door-blind, adapters that each speak one door. For +alkgit the boundary is concrete: + +- `alkgit-core` + `alkgit-transport` depend on alkcall types only + (`BiStream`, identity/ACL types); they never depend on alkhttp or + alkgit-ssh, and carry no http/channel-specific types below the stream. +- The http and ssh crates are replaceable: a downstream app (gitea-like) + embeds the core + transport and brings its own front doors. +- Admin API = alkcall ops, usable as-is or replaced by a downstream app. + ## Version pins in workspace manifests - `alkcall 0.8` (published), `alkhttp 0.5` (published), `alktls 0.1` diff --git a/docs/research/vision.md b/docs/research/vision.md index 5d66554..07d3777 100644 --- a/docs/research/vision.md +++ b/docs/research/vision.md @@ -45,7 +45,8 @@ is designed from day one, not retrofitted. 3. **No plaintext secrets at rest** — alkvault or nothing. 4. **Thin interfaces, one core** — http and ssh are adapters that authenticate, resolve a repo, and hand a duplex stream to the transport layer. Policy - lives in exactly one place. + lives in exactly one place. The core never knows which front door is + talking (see "ALPN as a service" below). 5. **Honest capability advertisement** — the git protocol advertises only what we actually serve (this is both protocol correctness and the security pattern: promise/enforce in the same place). @@ -75,6 +76,41 @@ is designed from day one, not retrofitted. | `alkgit-ssh` | ssh front door (git commands over alkcall channels) | | `alkgitd` | binary: config, assembly, TLS/ACME, serving loops | +## Composability: "ALPN as a service" + +alkgit is the git member of the alk "ALPN as a service" family — alktty, +alktunnels, and alksocks (socks5) follow the same pattern, and the alknet +mono-repo is being decomposed into exactly these pieces for rewrite. The +pattern's load-bearing rule: **`alkgit-core` + `alkgit-transport` never know +which front door is talking.** The transport layer consumes (identity, repo +id, duplex stream, limits) and speaks git; everything above the stream is +the adapter's problem. That is what keeps alkgit composable for downstream +use: + +- A future gitea/gitlab-like application should be able to embed + `alkgit-core` + `alkgit-transport` (or talk to `alkgitd`) and add its own + UI/issues/PR layer without forking anything here. +- The admin API is a set of alkcall ops, not an embedded web framework — + a downstream app can either use it or replace it. +- Nothing in the core may reach upward into alkhttp/alkssh concerns + (no http types, no channel types below the transport boundary). + +The v1 reduction follows from this: **storage + ACL + protocol adapters**. +A simple static/template web UI for the public repo listing is explicitly +out of scope here (would be a separate downstream thing on top). + +## Primary deployment target + +Our own use case is the design anchor: **public self-hosted repos with +anonymous clone over http, authenticated push, no gitea-style app features +in use**. So: + +- Anonymous *fetch* (clone/fetch advertisement + pack) on explicitly-public + repos is a first-class path, not an afterthought. +- Push is always authenticated, on every repo, no exceptions. +- ACL must be simple enough to reason about completely: repo visibility + (public/private) + identity-based read/write, nothing richer in v1. + ## What phase 0 must still produce before phase 1 - [x] gitoxide capability + version research (`gitoxide.md`)