- CHANGELOG.md founded — the 0.1.0 entry: the ADR-010 posture, the honest-advertisement statement, the ADR-009 budget inventory, and the wave-by-wave landed surface (waves 1–5); only served surface listed - README.md created — the posture, the five-trait seam table, the serving + consumer sketches, the sibling-crate pointer (alkgit-substrate), the license (MIT OR Apache-2.0) - Crate docs current against the post-wave-5 surface: the session split's modules entered the D-2 crate map; GIT_ALPN + the four OP_GIT_REPO_* constants gained their pinning ADR tokens; cargo doc warning-free on both feature sets - Package policy landed in the root manifest (the sibling crates' convention): the process surface (tasks/, docs/reviews|research| plans/, .opencode/, AGENTS.md) excluded — the package ships 75 files (src, tests, docs/architecture, README, CHANGELOG) Verified: cargo test / -p alkgit / --all-features (13 binaries each), both clippies (-D warnings), fmt, doc, the fuzz corpus gate, publish dry-run, taskgraph validate
4.4 KiB
alkgit
Git smart protocol for the alk family: the producer and consumer halves
of the git smart protocol as a pure protocol crate, riding alkcall
channels on the alk/git ALPN.
The crate serves the wire — V2 upload-pack (advertisement, ls-refs,
the negotiation ack loop, the done round's streamed pack) and V0
receive-pack (push advertisement, the bounded packless peek, ingestion
through the seam, status reports) — and consumes it (GitSession, the
typed fetch/push client). It is a pure protocol crate (ADR-010, the
alktty/alktunnels template): no binary, no front doors — the alkhttp
git/lfs features and alkssh are family infrastructure
(doors.md); a downstream app embeds this crate, brings its own door
(alkcall duplex or the smart-http shapes), and supplies the backends.
The shipped alkstore + alkblobs composition is the separate
alkgit-substrate crate (ADR-025).
The backend seam
Everything the wire layer runs through — five #[async_trait],
dyn-compatible traits (ADR-018) every backend implements:
| Trait | Contract |
|---|---|
GitRegistry |
repo id → RepoRecord (ADR-012 §1) |
GitRegistryStore |
registry writes (put/update/remove; grants ride RepoRecord) |
GitRefs |
ref listings + apply_updates — the single CAS home (ADR-013 §7) |
GitPackGen |
pack generation (wants/haves closure) + common_haves (the ack-loop recognition seam, ADR-014 §5) |
GitPackIngest |
push ingestion, the prepare/apply split (PreparedPush) (ADR-020 §2) |
Supporting surface: RepoRecord / Visibility / AccessAction +
the repo-id grammar, the error model (RegistryError, StorageError),
the budget model (Limits — wall clock, request bodies, refs,
negotiation rounds, haves, pack and object sizes, the packless peek
window, blocking-pool concurrency — ADR-009), and the wire shapes
(RefLine, RefUpdate, RefOutcome, PushOptions).
Serving — the producer half
Sessions take the AuthorizedRepo marker by type (ADR-007 — the
resolve→authorize check is unskippable; ACL runs before any protocol
byte) and are bounded by Limits throughout:
use std::sync::Arc;
use tokio::sync::Semaphore;
use alkgit::{AuthorizedRepo, AccessAction, Limits, Service, serve_duplex};
// the door resolves + authorizes, then hands the marker on:
let marker = AuthorizedRepo::authorize(record, identity, AccessAction::Read)
.expect("the check passed");
let pipeline = Arc::new(Semaphore::new(limits.max_concurrent_blocking_tasks));
serve_duplex(
&marker, stream, Limits::default(), Service::UploadPack,
refs, packgen, ingest, /* push_options_negotiated */ false, pipeline,
).await?;
On the native transport, GitAdapter fronts the alk/git ALPN
directly (it holds the same handles and emits the ADR-016 request-line
preamble discipline), and register_openable mounts the
channels/git/sub open op for channel-mediated sessions. On the
smart-http shapes, serve_stateless_post / serve_stateless_advertisement
mount the per-POST entry (one POST = one command invocation) the http
door composes — see tests/duplex_serving.rs and
tests/stateless_serving.rs for full, working assemblies.
Consuming — the consumer half
GitSession is a typed git client over gix-transport's git-daemon
Connection on the alkcall BiStream compat halves (ADR-017):
let mut session = GitSession::connect_direct(
bistream, "owner/repo", Service::UploadPack, Some("peer.alk.dev"), limits,
)?;
let refs = session.ls_refs(&LsRefsArgs::default()).await?;
let reports = session.fetch(
vec![FetchRound { wants, haves, done: true }],
&mut pack_sink,
).await?;
Push rides its own session (Service::ReceivePack, the hand-rolled
send-pack — commands, the caller's pack streamed raw, the typed
PushReport parsed in both framings).
Status
The protocol core is at its first release; the architecture specs
(docs/architecture/) are the authoritative contract — the ADRs and
transport.md / backend.md pin every wire shape and trait
signature the publish froze. The substrate track (waves 6–10) lands
the shipped backend composition in alkgit-substrate.
Documentation
- Architecture docs — the authoritative spec: ADRs, wire formats, and the backend contracts.
- API docs — full crate documentation.
- Changelog
License
MIT OR Apache-2.0