feat: workspace skeleton + phase 0 research docs

- Cargo workspace with 5 sub-crates: alkgit-core (storage),
  alkgit-transport (smart protocol), alkgit-http, alkgit-ssh, alkgitd
  (binary); sha1 pinned through the gix stack, sha256 passthrough feature
- docs/research/: vision, gitoxide alignment, alk stack fit, server-side
  protocol inventory, license/reference policy, POC plan
- AGENTS.md: conventions mirroring alkcall (no comments, thiserror, tokio,
  no secrets on wire/at rest, visible-surface=authorized-surface,
  gitoxide-only serving path, bounded resources, registry-resolved repos)

Verified: cargo build, clippy -D warnings, fmt, test, check --all-features
This commit is contained in:
glm-5.3-flash committed 2026-09-19 15:36:21 +00:00
1 parent a633dddd6b
commit a3cdef909b
20 files changed
+965

No files matched your search

+101
View File
@@ -0,0 +1,101 @@
# alkgit Phase 0: Vision and Guiding Principles
**Status**: draft v1 — 2026-09-19
**Phase**: 0 (exploration) — this document captures WHAT we are building and
WHY before architecture (phase 1) commits to HOW.
## Vision
A self-hosted, single-binary git server in Rust: `alkgitd` serves repositories
over **http** and **ssh** interfaces with an authenticated-by-default surface,
built on the alk stack (alkcall, alkhttp, alktls, alkvault) and gitoxide.
It exists because self-hosted git platforms (gitea/gitlab) are large
multi-component applications with a long-tail of exposed APIs, plaintext
secret storage, and web-UI attack surface — and because CVE-2026-59774
(gitea) demonstrated that a single logic bug in an internally-exposed API is
enough for full compromise of the host. Our blast-radius and exposure model
is designed from day one, not retrofitted.
## The problem, precisely
1. **Exposure model**: mainstream self-hosted git servers expose a large
HTTP API surface regardless of auth (openapi describes everything;
enforcement is somewhere else). alkcall inverts this: only operations the
caller has privileges for are visible on the wire, and `Visibility::Internal`
ops are structurally unreachable. alkgit inherits that property by using
alkcall as the transport/protocol substrate.
2. **Secret hygiene**: gitea stores secrets plaintext in its DB. alkgit uses
alkvault for anything credential-shaped; the metadata store holds vault
references, never plaintext secrets.
3. **Footprint**: a git server is a small program (storage + smart protocol +
two front doors). The platform features (issues, PRs, wikis, CI) are where
the CVEs live. alkgit v1 is deliberately just the git server; everything
else stays out.
4. **Language**: the whole serving path is Rust (memory-safe, no C deps in
the packet path).
## Guiding principles (architecture must honor)
1. **Authenticated by default** — no unauthenticated endpoint exists unless a
repo is explicitly marked public; even then, advertisement is the only
anonymous surface, and push is always authenticated.
2. **Visible-surface = authorized-surface** — the alkcall model end to end;
no endpoint exists on the wire that a caller cannot see themselves
authorized for; internal/admin ops are never wire-reachable.
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.
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).
6. **gitoxide for storage/wire primitives** — never shell out to the `git`
binary (no GPL dependency, no process injection surface); own the smart
protocol server layer ourselves on gitoxide primitives.
7. **Bounded resources** — every protocol session carries wall-clock, size,
and round limits; git servers are internet-facing by definition.
## Non-goals for v1
- Web UI of any kind.
- Issues/PR/review features.
- Git LFS (later phase, separate decision).
- federation/replication between alkgit instances (later phase).
- Serving as a general sshd (only the git command surface).
- Windows as a serving platform (linux first; keep code portable-ish but
don't test it).
## Sub-crate shape (provisional, matches workspace skeleton)
| crate | role |
|---|---|
| `alkgit-core` | storage: repos, refs, odb, pack read/write, access-rule types |
| `alkgit-transport` | smart protocol: pkt-line sessions, advertise, ls-refs, fetch, receive-pack |
| `alkgit-http` | http front door (smart-http endpoints + admin API via alkhttp) |
| `alkgit-ssh` | ssh front door (git commands over alkcall channels) |
| `alkgitd` | binary: config, assembly, TLS/ACME, serving loops |
## What phase 0 must still produce before phase 1
- [x] gitoxide capability + version research (`gitoxide.md`)
- [x] alk stack fit + integration surface (`alk-stack.md`)
- [x] server-side protocol inventory (`git-protocol.md`)
- [x] license/reference policy (`reference-policy.md`)
- [ ] POC-1: real `git clone` over alkcall BiStream using gix-packetline
(validates BiStream fit + packetline async codec end-to-end)
- [ ] POC-2: server-side pack generation composition (bundle-write vs
entries-to-bytes) for a small want/have set
- [ ] POC-3: http smart-endpoint streaming shape through alkhttp
(chunked pack response, unbuffered receive-pack POST ingestion)
- [ ] Convergence: recommended approach summary feeding phase 1 architecture
## Immediate threat-model notes carried into architecture
- The admin API (repo/user/permission management) is alkcall
`Visibility::Internal` ops over an admin-only listener; it is never part
of the git traffic surface.
- Repo names arriving on the wire are registry IDs, never paths; storage
roots are configured server-side only.
- The advertisement phase runs ACL before the first ref line is emitted.
- receive-pack applies ref updates via CAS transactions; hooks/plugins do
not exist in v1 (no arbitrary code execution surface at all).