The core release gate verdict (core/review-wave-5): all six wave-5 tasks read clean; all three OQ-19 riders served/dispositioned (rider 1 executed inline in the gate session after the operator confirmed the decomposition report omitted it; rider 2 validated machinery-side with the wave-7 substrate facet booked; rider 3's include-tag / session-id dispositions confirmed); R-2's size-bomb cap confirmed as landed and waved-8-inherited; the fuzz corpus gate green with clean reported campaigns; the counting-reader residual accepted (wall-clock-only); N-1's permit posture accepted; review 005's no-split verdict stands; the feature matrix + dry-run + coverage (94.22% lines) re-verified at the gate's tree; the doc-hidden disposition and the crate-qualified tag convention recorded; the OQ-03 core-side freeze inventory enumerated and settled (11 surfaces, from the crate-root re-export list). On green: transport/overview/backend flip to `stable`; OQ-19 closed (resolved); the w5-publish task unblocks.
11 KiB
status, last_updated
| status | last_updated |
|---|---|
| stable | 2026-10-23 (the wave-5 release gate — the core froze OQ-03-side; track B decomposes against the published core) |
Overview: alkgit
Purpose
alkgit is the git payload service of the alk family (per ADR-010's
pure-protocol framing, corrected for the crate shape by ADR-025):
one repo, a two-crate workspace implementing the git smart protocol
over alkcall channels — the alk/git ALPN — with repository storage
behind backend traits. The protocol core provides the smart protocol
as producer/consumer halves and the backend trait seam; the shipped
storage composition lives in the sibling alkgit-substrate crate; and
nothing else: no binary, no front doors. The original
framing of this repo (a monorepo with an alkgitd binary and its own
http/ssh crates) was an init-agent artifact corrected by OQ-09/ADR-010;
docs/research/vision.md is amended accordingly.
Re-baselined 2026-10-19 (ADR-019..023, after the substrate
recomposition round — all four POCs complete; the evidence ledger is
docs/research/substrate-recomposition.md): storage is
substrate-first, registry-file and the on-disk odb engine are gone,
RepoRecord carries no path, LFS is v1 scope, reactivity is wired by
default.
Re-split 2026-10-20 (ADR-025, relitigating ADR-010's granularity
sub-decision): one repo, a two-crate workspace — the protocol core
alkgit and the shipped backend composition alkgit-substrate. The
boundary encodes the real consumption split: door crates and wire-only
embedders consume the protocol core and cannot drag the substrate;
full embedders take both.
The one-line architecture
Two crates (one workspace): alkgit — producer + consumer + backend
traits, the protocol; alkgit-substrate — the shipped alkstore +
alkblobs composition implementing the traits. Doors (alkhttp,
alkssh, alknet) expose the protocol; assembly belongs to downstream
consumers.
Crate map
Workspace of two published crates (ADR-025):
| Crate | Contents | POC evidence |
|---|---|---|
alkgit — protocol core |
Producer: GitAdapter (alk/git ALPN via alkcall ProtocolHandler; parses the ADR-016 request-line preamble), channels register_openable (channels/git/sub — open-op params {repo, service}, the negotiation + service selector + ACL point; ADR-016). Consumer: GitSession typed client (connect_direct, open_via_channels) — ADR-017: ls_refs/fetch/push; construction simplified per ADR-023 §2 (validated end-to-end by POC-X). Wire: duplex session + stateless request/response layer (ADR-005), V2 state machines (ADR-003), receive-pack machine (ADR-013) — POC-1/2/3. Seam: the five ADR-018-pinned traits + seam types + error model; RepoRecord/op schemas + authorize (ADR-011/015); the git/repo/* call ops (ADR-012 §3). No substrate dependency at any feature level (ADR-025) |
POC-1, POC-2, POC-3, POC-X |
alkgit-substrate — the composition |
the ADR-019 composition implementing the seam over alkstore + alkblobs: the reactive halves (publish/notify/enqueue + reconcile + watermark leg), the coherence-contract cached read provider, the family adapter pattern (trait pair + in-memory default adapter), the sqlite/postgres engine twins, the substrate Find/odb front + pack pipelines, GC liveness sourcing + maintenance wiring, migrations (ADR-024), the LFS surface (see lfs.md) |
POC-O, POC-R, POC-L, POC-X |
Feature model (ADR-025's placement table): alkgit carries only the
sha256 passthrough and defaults to no features — the protocol core
is substrate-free by construction, not by remembered flag.
alkgit-substrate carries sqlite (default-on), postgres
(optional), lfs (default-on, fail-safe); reactivity and the
engine-generic composition are the crate's unconditional base (there
is no "reactivity" feature — it rides the crate). Engines are
constructor statements at assembly time (alkstore ADR-016), never
alkgit features. Doors
live in the door crates — see doors.md.
Security invariants (spec-level, carried from vision/principles)
- Authenticated by default — anonymous fetch only on explicitly- public repos; push always authenticated (the LFS batch composes the same posture onto the door surface — lfs.md).
- Visible-surface = authorized-surface — alkcall ACL end-to-end; internal ops never wire-callable; the ownership provider is wired on every ops-serving surface (alkcall ADR-048's loud default; the LFS batch binds through the door's own context — lfs.md).
- ACL before advertisement — nothing is emitted before the check (ADR-007); the channels open-op carrying the repo id is the natural enforcement point on the native path.
- Registry-resolved repo identity — wire names are ids, never paths (ADR-008); the record carries no path at all (ADR-019 §8), so the never-a-path rule holds a fortiori.
- No secret material on the wire or at rest outside alkvault — metadata holds vault references; no env-var credential reads. (In v1 alkgit's metadata holds no credential-shaped material at all, so nothing is vault-placed — ADR-011 §5.)
- No shelling out to
git— pure Rust on gix primitives. - Bounded resources — every session carries
Limits(ADR-009); the receive machine's pack-header peek is bounded (ADR-020 §1). - Honest capability advertisement — advertise exactly what we serve (ADR-003).
What is already validated (POC-backed)
- pkt-line over alkcall
BiStreamend-to-end (POC-1 → producer half). - Pack generation pipeline streaming with O(counts) memory (POC-2 →
the pipeline shape) — now over the substrate
Find(POC-O). - Smart-http streaming both ways (POC-3 → the stateless substrate that
alkhttp's future
gitfeature maps onto;docs/research/poc3-findings.md§alkhttp fit is the mounting reference). - The substrate re-baseline's four gates (POC-L/O/R/X, complete):
- POC-O — real
git clone/git pushagainst substrate-only storage; through-store ranged pack serving; row-CAS refs (stale/ atomic/delete/force); GC interop; sqlite co-tenancy clean. - POC-R — the reactive registry composition cross-process; the coherence contract + reconcile recipe; the maintenance chain (scheduler → queue → TTL lock → sweep).
- POC-L — LFS end-to-end with real
git-lfs3.7.0 (both bindings, three engines). - POC-X — two-node replication converging on real pushes;
GitSession's first working validation; the packless-push and RST-discipline wire facts.
- POC-O — real
Design Decisions
| ADR | Decision | Summary |
|---|---|---|
| 001 | Crate decomposition | superseded by ADR-010 |
| 002 | Session boundary | (identity, repo, service, stream, limits) — unchanged, load-bearing; service per ADR-016 |
| 003 | V2-first protocol | V2-only fetch both doors; push is V0-framed by upstream design (ADR-013); honest advertisement |
| 004 | Pack pipeline | data::output gen / data::input ingestion |
| 005 | Substrate types | duplex + stateless APIs over one state machine |
| 006 | HTTP adapter composition | superseded by ADR-010 (mounting → alkhttp feature) |
| 007 | ACL first | no ref/capability line before ACL passes |
| 008 | Repo identity | wire names are registry IDs (record carries no path — ADR-019 §8) |
| 009 | Budgets | every session carries limits |
| 010 | Pure protocol crate | producer/consumer halves, no doors/binary (granularity + posture superseded: ADR-025) |
| 011 | Per-repo authorization | grants in repo records, policy in core, vault-nil (amended: ADR-015) |
| 012 | Registry + ops | read/write split, CRUD ops, feature split (file default superseded by ADR-019) |
| 013 | receive-pack | V0-framed push machine, thin-pack acceptance, unpack-first CAS (§3/§6 amended: ADR-020) |
| 014 | Negotiation | ack loop, common_haves seam, no ready |
| 015 | Manage grant + op gate | manage tier, admin-OR-manage gate, create seeds manage |
| 016 | Native session preamble | {repo, service} open-op params, request-line preamble, service in the tuple |
| 017 | Consumer half | GitSession typed client; construction simplified (ADR-023 §2) |
| 018 | Trait signatures + storage errors | signatures held with zero drift through the re-baseline POCs |
| 019 | Substrate re-baseline | storage on alkstore + alkblobs; registry-file scrapped; reactive-by-default |
| 020 | receive-pack duplex | packless delete pushes; unpack-to-loose + pin bridge |
| 021 | Feature graph | superseded by ADR-025 (graph re-partitioned across the two-crate workspace) |
| 022 | LFS | media under GitObjectSha256; alkhttp lfs door; wired liveness |
| 023 | Replication v1 | protocol-native via GitSession; mirror plane = optimization bucket |
| 024 | Schema migrations | construction-run, version-stamped, additive-first |
| 025 | Two-crate workspace | protocol core alkgit + composition alkgit-substrate; the placement rule for every feature |
Open Questions
Key questions tracked in open-questions.md:
- OQ-03: publish-time API freeze inventory (the trait family, op
set, and the revised
RepoRecordschema + substrate composition types enter it). - OQ-05: sha256 policy (deferred(scope), low).
- OQ-16: grant-key identity namespace (deferred(scope); blocks nothing in v1 — ADR-015 §7).
- OQ-17: relational registry schema migrations — resolved as ADR-024 (construction-run, version-stamped, additive-first).
- OQ-19: implementation-phase wire validations (unborn-HEAD
rider;
common_havesover the substrate odb).
The re-baseline round resolved the recomposition's DQ ledger (substrate-recomposition.md DQ-1..8 → ADR-019..023); the registry backing question (OQ-06, resolved by ADR-012) is superseded by ADR-019. The crate-shape round (2026-10-20, ADR-025) superseded ADR-010's granularity sub-decision and ADR-021's feature graph — OQ-03's freeze inventory re-partitions per crate.