# alkgit POC Plan ## POC modes POCs are not production code — fewer constraints (comments, unwrap, error taxonomy are all relaxed), and their code never merges to main. Two modes, chosen by whether the POC touches code in this repo: - **Branch mode** (POC depends on alkgit code in the repo): create a git branch off main, do the work there, then **merge the findings into the research docs** on main and drop the branch — the POC code itself does not merge. - **Standalone mode** (POC is independent of alkgit code): a scratch crate or project at `/workspace/` (e.g. `/workspace/alkgit-poc1`), outside the repo entirely. Findings are written directly into `docs/research/` on main. In both modes the deliverable on main is the findings write-up, not the POC source. POC source is disposable once findings are recorded. Each POC records: hypothesis, method, result (proceed/pivot/block), and what it changes in the research docs. ## POC-1: pkt-line over alkcall BiStream **Status**: complete (2026-09-20) — **proceed**. See `poc-1-findings.md`. Real git 2.43 clones/fetches/fsck-clean over the alkcall `Connection → BiStream → tokio-util compat → gix-packetline` path; the flagged futures-io risk resolved with a two-line compat adapter. **Hypothesis**: a full V2 fetch handshake (`ls-refs` + one `fetch` round) between real `git` CLI (as client, `git clone`/`git fetch`) and a Rust listener that bridges alkcall `BiStream` to `gix-packetline`'s async codec can be completed. **Method sketch**: alkcall `Connection` accepted over a local stream; spawn a handler that receives a `BiStream`; wrap `read_half`/`write_half` in the pkt-line async reader/writer; advertise V2 capabilities with honest feature list; parse `command=ls-refs`, emit refs from a fixture repo (created with `gix`), flush. Client side: `git -c protocol.version=2 clone` against a local bridge (POC can start with plain tcp and only simulate the alkcall side if alkcall dialing adds friction — the alkcall-fit part can be tested with `Connection::from_stream`). **Success**: git prints its ref advertisement fetch result without error; all framing validated against real git's parser (the strictest pkt-line validator available). **Risks**: gix-packetline `async-io` feature uses `futures-io` traits — confirm alkcall stream halves implement `AsyncRead`/`AsyncWrite` compatibility (they should, being tokio io objects; may need a thin adapter). ## POC-2: server-side pack generation **Status**: complete (2026-09-20) — **proceed**. See `poc2-findings.md`. Real git 2.43 clones/fetches (fsck-strict clean) packs generated by gitoxide's own pipeline (`count::objects` + `iter_from_counts` + `FromEntriesIter`) streamed over sideband; memory is O(counts), not O(pack) — 60k-object pack written through a 64 KB sink at ~11 MB extra RSS. Course correction recorded: `TreeContents` does not follow commit parents — the closure needs a commit-ancestry walk feeding the count stage. **Hypothesis**: given a fixture repo and a want/have set, we can produce a valid pack stream in memory that `git verify-pack`/`git unpack-objects` accepts, using one of: a. `gix-pack::bundle::write` into a temp dir then read the file back (correctness baseline), or b. `gix-pack::data::output::bytes` fed by an odb object walk (streaming). **Method**: build fixture repo via `gix` API or a scripted `git` (fixture creation may shell out to `git` — only serving-path must be git-binary-free). Try (b) first; fall back to (a) to establish the correctness baseline. **Success**: `git clone` from a bridge that serves the generated pack completes and `git fsck` passes in the clone. **Decision to make**: streaming composition that doesn't materialize the whole pack in memory for large repos — record memory behavior for a 10k-object repo at minimum. ## POC-3: smart-http shape through alkhttp **Status**: complete (2026-09-21) — **proceed**. See `poc3-findings.md`. Real git 2.43 clones/fetches/tag-checkouts over `http://` through the full alkcall → alkhttp path (`Connection::from_bidi(http/1.1)` → `HttpAdapter` → axum custom routes); request bodies stream (measured via dribble probe + git's forced-chunked path), pack responses stream under back pressure with O(counts) memory on a 60k-object clone. Key protocol correction: http V2 responses end at the flush — the `0002` response-end pkt is synthesized by the client's transport helper, never sent on the wire. **Hypothesis**: alkhttp can serve `GET /info/refs` and stream a POST body (ingest without full buffering) for `git-receive-pack`. **Method**: minimal alkhttp service exposing a fake `/repo.git/info/refs?service=git-upload-pack` and `/repo.git/git-upload-pack` wired to the POC-1 bridge; run real `git clone http://...` against it; measure whether alkhttp's request-body API streams or buffers (inspect/measure, not guess). **Success**: real git clones over http; documented answer on body streaming for receive-pack sizing. ## Sequencing POC-1 first (the BiStream/packetline fit is the load-bearing assumption). POC-2 next (the crux of fetch). POC-3 last (http shape). Each POC updates the corresponding research doc with results and a proceed/pivot/block note. **Status**: POC-1, POC-2, and POC-3 complete and proceed — phase 0 gates all pass. ## Modes applied to these POCs - POC-1, POC-2: **standalone mode** — nothing in the alkgit repo exists to build on yet; run as `/workspace/alkgit-poc1` and `/workspace/alkgit-poc2`. (If POC-1's bridge turns out to want the workspace deps, it can flip to branch mode on the repo instead — decide before writing, not after.) - POC-3: **branch mode** — it exercises alkhttp wiring against this repo's skeleton; findings merge into `alk-stack.md`, branch is dropped after.