refactor(architecture): ADR-010 — pure protocol crate (alktty template)

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).
This commit is contained in:
glm-5.3-flash committed 2026-09-21 10:54:03 +00:00
1 parent de922253a4
commit 86bf5a0cf0
37 files changed
+730 -947

No files matched your search

+115
View File
@@ -0,0 +1,115 @@
---
status: draft
last_updated: 2026-09-21
---
# Doors: how alkgit is exposed
## What this is
alkgit (per ADR-010) owns no front doors. This document records the two
door mappings that exist or are planned in the family, and the requirements
alkgit places on each. The protocol crate itself is door-blind (ADR-002):
every door converges on the same two substrates.
## The door pattern
Doors are family infrastructure: alkhttp (exists), alkssh (planned, after
alksocks), the alknet rewrite (coming). A door wraps alkcall's
producer/consumer in its wire protocol; services like git, tty, tunnels,
and socks5 are payloads doors optionally expose. Downstream consumers
(our platform deployment, a future gitea-like app) assemble the doors they
want with the payloads they want.
Auth semantics are the door's auth (http: the door's token mechanism; ssh:
the door's key-based identity). alkgit consumes the resulting alkcall
identity — the identity-extractor seam that ADR-006 needed exists only in
the door, where it belongs.
## alkhttp `git` feature (http mounting)
**Scope**: an alkhttp feature that maps two route shapes onto alkgit's
stateless substrate (ADR-005):
| Route | Service |
|---|---|
| `GET /{repo}/info/refs?service=git-{upload,receive}-pack` | advertisement (smart prefix + capability dump + flush) |
| `POST /{repo}/git-upload-pack` | V2 fetch commands (one command per POST) |
| `POST /{repo}/git-receive-pack` | push (streaming ingestion, budgeted body) |
| `GET /{repo}/info/refs?service=git-upload-archive` | honest refusal (not served) |
`{repo}` is the registry id (ADR-008); resolution + ACL run before any
response byte (ADR-007).
**Sequencing**: the feature requires `alkgit` on crates.io (optional
dependencies must resolve), so it lands in alkhttp 0.6 after alkgit's
first publish. Until then, git-over-http is served by any downstream that
mounts the stateless substrate directly — POC-3's `httpservice.rs` is the
reference implementation of exactly that mapping.
**Framing facts the feature must honor** (all POC-3-validated, encoded in
the substrate, not re-decided): responses end at flush (never `0002`);
flush is one-shot per response; flush-only POSTs are probes answered
200-empty; request bodies stream (no accumulation); response bodies
stream under back pressure (bounded mpsc → `Body::from_stream`); request
bodies carry a budget (ADR-009 — alkhttp custom routes are unbounded by
default).
## alkssh (git-over-ssh, future)
**alkgit's requirement on alkssh** (to record in alkssh's spec when it
exists): parse the exec-request string with a fixed grammar —
`git-upload-pack '<repo>'` / `git-receive-pack '<repo>'` — never shell-
interpret it (ADR-008's never-execute rule), map the door's key-based
identity to the alkcall identity space, resolve the repo id against the
registry, run ACL, and hand (identity, repo, post-auth stream, limits)
to alkgit's duplex session. `git-upload-archive` gets a fixed refusal.
V2 is expected (ADR-003); `GIT_PROTOCOL=version=2` rides the ssh env
mechanism.
**Interim**: no git-over-ssh path ships with alkgit. A downstream that
needs it before alkssh lands can terminate wire-ssh itself (russh or
otherwise) and consume the duplex session — that is exactly the embedder
path ADR-002 defines, and it works today against the POC-1 shape. It is
an embedder assembly concern, not alkgit scope.
## The alkcall-native path (no adapter at all)
The `alk/git` ALPN producer and the channels open-op (repo id in the
open-op params) need zero door code — POC-1 is that shape verbatim. Any
alkcall-speaking client (including alkgit's own consumer half,
`GitSession`) can use it. This is the baseline path; the http/ssh doors
are conveniences layered on top for stock git clients.
## Assembly (downstream responsibility)
There is no alkgit binary (ADR-010). A deployment assembles: alkcall
connection sources (alkhttp/alktls for http, alkssh later, raw ALPN for
the native path) + `GitAdapter` + a backend implementation (the `gix`
feature's, or its own) + `Limits` from config + vault for any credential
material. Reference sequence for our platform deployment lives in that
deployment's docs, not here.
## Design Decisions
| ADR | Decision | Summary |
|---|---|---|
| [002](decisions/002-front-door-blind-core.md) | Session boundary | every door consumes the same tuple |
| [003](decisions/003-protocol-v2-first.md) | V2-first | honest advertisement per door |
| [007](decisions/007-acl-before-advertisement.md) | ACL first | before any protocol byte |
| [008](decisions/008-registry-resolved-repo-identity.md) | Repo identity | wire names are registry ids |
| [009](decisions/009-bounded-resources-budget.md) | Budgets | limits on every session |
| [010](decisions/010-pure-protocol-crate.md) | Pure protocol crate | doors are family infrastructure |
## Open Questions
- **OQ-08**: registry identity space + vault placement (narrowed by
ADR-010; door auth mechanics belong to the door crates).
## References
- `docs/research/poc-1-findings.md` (duplex shape), `docs/research/poc3-findings.md`
(http mounting evidence, framing facts)
- alktty/alktunnels architecture docs (the template this follows)
- ADR-010 (supersedes ADR-001/006; this file replaces http.md, ssh.md,
alkgitd.md)