alkgit 0.1.0

Git smart protocol for the alk family: pkt-line substrates, protocol V2 serving (upload-pack/receive-pack), producer/consumer halves on alkcall channels, and the backend seam traits — the shipped alkstore+alkblobs composition is the alkgit-substrate crate (ADR-010/025)
Documentation
//! alkgit: git smart protocol for the alk family.
//!
//! A pure protocol crate (ADR-010, the alktty/alktunnels template) on
//! alkcall channels — the `alk/git` ALPN: the git smart protocol as
//! producer/consumer halves over the alk-family call fabric. The crate
//! carries no binary and no front doors — the alkhttp `git`/`lfs`
//! features and alkssh are family infrastructure (docs/architecture/
//! doors.md); a downstream app embeds this crate, brings its own door,
//! and supplies the backends. The shipped substrate composition is the
//! separate `alkgit-substrate` crate; this crate is substrate-free by
//! construction. The architecture specs are `docs/architecture/`
//! (transport.md, backend.md, doors.md + the ADRs); each API's contract
//! stamps are on the items themselves.
//!
//! # The backend seam (ADR-018)
//!
//! Everything the wire layer runs *through*: the `#[async_trait]` +
//! `Send + Sync` trait family every backend implements (the shipped
//! impls are the substrate crate's) — [`GitRegistry`] /
//! [`GitRegistryStore`] (the registry family) and [`GitRefs`] /
//! [`GitPackGen`] / [`GitPackIngest`] (the object-storage family, the
//! prepare/apply split with the [`PreparedPush`] seam); the repo
//! record family ([`RepoRecord`], the repo-id grammar
//! [`validate_repo_id`]); the error model ([`RegistryError`] +
//! [`StorageError`]); the budget model ([`Limits`], ADR-009 — wall
//! clock, request bodies, advertisement refs, negotiation rounds,
//! haves per round, the pack size, the packless peek window, the
//! blocking-pool concurrency); and the wire shapes both transport
//! directions speak ([`RefLine`], [`RefUpdate`], [`RefOutcome`],
//! [`PushOptions`]).
//!
//! # The session substrates and serving entries (ADR-005)
//!
//! Two substrate mechanisms, both taking the ADR-007
//! [`AuthorizedRepo`] marker by type so a session cannot reach the
//! wire unchecked:
//!
//! - **duplex** (§1, the pkt-line framing layer the native transport
//!   drives): [`Session`] (the request reader with the stop-delimiter
//!   discipline, the writer machinery, the [`RawTail`] raw-tail
//!   escape), the [`Sideband`] blocking-side sink, and the serving
//!   entries — [`serve_duplex`] (advertisement-once + command loop /
//!   one-request push, under the wall clock) with the resolve→authorize
//!   front [`serve_duplex_resolved`].
//! - **stateless** (§2, the smart-http framing facts the http door
//!   mounts): [`StatelessRequest`] (the capability-dump skip, the
//!   delim-aware split, the flush-only probe, the raw-tail escape),
//!   [`StatelessResponse`] (one-shot flush, never `0002`), the
//!   [`BodyReader`] door-body adapter, and the entries —
//!   [`serve_stateless_post`] (one POST = one command invocation) and
//!   [`serve_stateless_advertisement`] (the `info/refs` GET emission).
//!
//! # The protocol machines
//!
//! V2 fetch ([`advertise_v2`] — the honest capability list;
//! [`serve_ls_refs`] — the ls-refs grammar;
//! [`serve_fetch_round`] + [`parse_fetch_args`] — ADR-014's ack loop
//! and argument grammar with the rounds/haves/pack budgets) and
//! receive-pack ([`advertise_v0`] — the V0 push advertisement;
//! [`parse_push_request`] + [`serve_receive_pack`] — ADR-013 §3–11 as
//! amended by ADR-020 §1: command grammar, the bounded packless peek
//! with the duplex/stateless tail disciplines, prepare-under-permit
//! ingestion with the single CAS home, and the substrate-owned status
//! report framing via [`bridge_pack_source`], the pack stream the raw
//! tail hands through — [`PackSourceFault`] is its typed budget class).
//! The transport-side ACL completes the layer: [`authorize`] (the
//! ADR-011/015 policy), [`validate_ref_name`] (ADR-013 §9's deny-list).
//!
//! # The transport (producer half)
//!
//! The direct-ALPN [`GitAdapter`] — the `alk/git` `ProtocolHandler`
//! whose session boundary is the ADR-016 preamble: the request-line
//! grammar ([`RequestLine`], [`parse_request_line`],
//! [`read_request_line`]) and the channels open op
//! ([`register_openable`] — the `channels/git/sub` establisher gate,
//! ADR-016 §1). The `git/repo/*` op family ([`register_repo_ops`],
//! ADR-012 §3/§5 with the ADR-015 two-tier gate) rides the same
//! registry.
//!
//! # The consumer half
//!
//! [`GitSession`] (ADR-017, in the POC-X-validated shape of ADR-023):
//! a typed git client over gix-transport's git-daemon `Connection` on
//! the alkcall `BiStream` compat halves, split into flat sibling
//! modules (one workstream one file): `session` carries the
//! construction + handshake workstream and the shared drain helpers
//! both clients build on; `session_fetch` the fetch workstream —
//! [`GitSession::ls_refs`] / [`GitSession::fetch`], the client side of
//! the V2 grammar above; `session_push` the hand-rolled push
//! workstream ([`GitSession::push_advertisement`],
//! [`GitSession::push`]) — all bounded by the client-direction budget
//! kinds, no credentials on the session surface (their types re-export
//! through `session`, so the crate's public paths are unchanged).

#![forbid(unsafe_code)]

mod adapter;
mod authorize;
mod backend;
mod channels;
mod duplex;
mod error;
mod fetch;
mod limits;
mod ops;
mod pack_source;
mod preamble;
mod push;
mod refname;
mod registry;
mod seam;
mod session;
mod session_fetch;
mod session_push;
mod stateless;
mod substrate;
mod v0;
mod v2;

pub use adapter::GitAdapter;
pub use authorize::{authorize, authorize_repo_op, AuthorizedRepo, GIT_ADMIN_SCOPE};
pub use backend::{GitPackGen, GitPackIngest, GitRefs, GitRegistry, GitRegistryStore};
pub use channels::{git_open_spec, register_openable, GIT_ALPN, OP_GIT_OPEN};
#[doc(hidden)]
pub use channels::{make_git_establisher, OpenParams};
pub use duplex::{
    serve_duplex, serve_duplex_resolved, RawTail, Request, Session, Sideband,
    SIDEBAND_CHANNEL_CAPACITY,
};
pub use error::{RegistryError, StorageError};
pub use fetch::{parse_fetch_args, serve_fetch_round, FetchArgs, FetchRounds};
pub use limits::{
    Limits, MAX_ADVERTISEMENT_REFS, MAX_CONCURRENT_BLOCKING_TASKS, MAX_HAVES_PER_ROUND,
    MAX_NEGOTIATION_ROUNDS, MAX_PACK_SIZE_BYTES, MAX_REQUEST_BODY_BYTES, PACKLESS_PEEK,
    SESSION_WALL_CLOCK, SIDEBAND_CHUNK_SIZE,
};
pub use ops::{
    git_repo_create_spec, git_repo_delete_spec, git_repo_get_spec, git_repo_update_spec,
    register_repo_ops, OP_GIT_REPO_CREATE, OP_GIT_REPO_DELETE, OP_GIT_REPO_GET, OP_GIT_REPO_UPDATE,
    REPO_RESOURCE_TYPE,
};
pub use pack_source::{
    bridge_pack_source, PackSource, PackSourceBridge, PackSourceFault,
    PACK_SOURCE_CHANNEL_CAPACITY, PACK_SOURCE_CHUNK_SIZE,
};
pub use preamble::{
    parse_request_line, read_request_line, RequestLine, RequestLineError, MAX_REQUEST_LINE_BYTES,
};
pub use push::{
    parse_push_request, serve_receive_pack, PackTailDiscipline, PushCapabilities, PushRequest,
    ATOMIC_PUSH_FAILURE_REASON, UNPACKER_ERROR_REASON,
};
pub use refname::{
    validate_ref_name, FUNNY_REFNAME_REASON, LOCK_REFNAME_SUFFIX, RESERVED_REF_NAMESPACES,
};
pub use registry::{
    validate_repo_id, AccessAction, RepoIdError, RepoRecord, Visibility, REPO_ID_MAX_BYTES,
};
pub use seam::{PreparedPush, PushOptions, RefLine, RefOutcome, RefUpdate};
pub use session::{
    FetchRound, FetchRoundReport, GitSession, GitTransport, HandshakeResponse, PushAdvertisedRef,
    PushReport, PushSendOptions, SessionError,
};
pub use stateless::{
    serve_stateless_advertisement, serve_stateless_post, BodyReader, StatelessPost,
    StatelessRequest, StatelessResponse,
};
pub use substrate::{Service, ServiceParseError, SubstrateError};
pub use v0::{advertise_v0, PUSH_SERVED_CAPABILITIES};
pub use v2::{advertise_v2, parse_ls_refs_args, serve_ls_refs, LsRefsArgs, PktLineWriter};