cli.sgit.ai / Research / Pack mode — feature reference for 0.24.0

Pack mode — feature reference for 0.24.0

Date2026-10-22 · 01:24 UTCKindreferenceResearch topicswrite-path scaleWritten bythe sgit-ai CLI team (Claude Code sessions), for Dinis CruzSourceteam/humans/dinis_cruz/claude-code-web/10/22/feature-reference__pack-mode.md in SGit-AI__CLI at 182cfc1. Published here as written; the CLI repository is where the work happened.

For: the sgit.ai team writing the release notes and the feature documentation. Status: released in sgit-ai 0.24.0 (branch merged to dev on 22 Oct 2026). Sources: the spec (../10/21/spec__pack-mode.md), the measurements (../10/21/note__pack-mode-round-trip.md), the tester's page (../10/21/howto__test-pack-mode.md), the four verification rounds (../10/21/response__pack-mode-verification*.md), the CHANGELOG entry under 0.24.0. This page is the one-stop summary; everything in it is tested or measured.

1. What it is, in one paragraph

A pack vault is a vault whose objects travel and are stored on the host as zips instead of one file per object. Every sgit push uploads one zip of the commit's new objects; the first push and sgit pack compact upload one snapshot of the whole history; a clone takes the newest snapshot plus the commit packs it lacks, in a handful of requests whatever the history's size. Files are compressed before they are encrypted, so the host holds about half the bytes for text-heavy vaults. Nothing changes on the server: the same batch, presigned, list and delete routes. Pack vaults are opt-in, created with sgit init --packs, and are a separate vault from any existing one.

2. Why

On the comms vault (1,229 commits, 33k objects, 527 MB loose) a full clone over the API took 3½ minutes because it is 700 batch reads; agents' command timeouts are shorter than that. The same history as a pack vault clones in 25 s, of which 18 s is one 251 MB download in four requests. A pull that is N pushes behind is two listings and one batch of N zips.

3. Commands

CommandWhat it does
sgit init --packs [dir], sgit create --packs <name>A new pack vault: branch-index features packs and blob-deflate, min_client 0.24.0.
sgit push / sgit pull / sgit clone / sgit statusUnchanged for the user; on a pack vault they move packs. Clone takes the snapshot for the branch head (then older ones until the history is complete) and every commit pack; pull takes the commit packs it has not absorbed; push uploads one commit pack per new commit, oldest first, then the ref under compare-and-swap exactly as before.
sgit pack import <normal clone> <new dir>Rewrites the clone's HEAD history into a NEW pack vault with its own key (blobs re-encrypted and deflated, trees deterministic, commits re-signed by the new clone's key with messages and timestamps kept). The source is untouched. The new vault's first sgit push uploads one snapshot. --no-deflate keeps blobs uncompressed; --json prints the stats.
sgit pack export <pack clone> <new dir>The reverse: a NEW normal vault, nothing deflated, nothing packed. Round trip tested end to end.
sgit pack compact [dir] [--dry-run]One snapshot of the current head; the commit packs it absorbs, the snapshots it supersedes and orphan commit packs older than a day move to bare/packs/archive/ (copy, verify by listing, then delete the original; nothing is ever deleted without its copy; archive/ is never deleted by the client). Refuses a clone that has not pulled, a dirty working tree, a read-only clone.
sgit pack ls, sgit pack stats, sgit pack verifyThe three folders as the host lists them (packs this clone absorbed marked *); packs and bytes on the host plus the local compression ratio; every member of every pack checked against its content address.

Flags on pack take the usual network options (--base-url, --token, --remote, --transport).

4. Host layout

bare/packs/commits/   <epoch>__<commit id>__<bytes>.zip   one per push
bare/packs/snapshots/ <epoch>__<commit id>__<bytes>.zip   first push and each compaction
bare/packs/archive/   the same names, moved by compaction; never deleted by the client
bare/refs/, bare/indexes/, bare/keys/                      exactly as on a normal vault
bare/data/                                                 empty, except tag objects (tiny, read by id)

A pack is a deterministic zip (ZIP_STORED, members sorted, fixed timestamps) of members named bare/data/<object id>: the same commit always gives the same bytes, so a pack can be rebuilt from any clone that holds the objects. The local store stays loose: packs are extracted on arrival, so every local command (history log, cat, diff, branch, stash, tag) is unchanged.

5. Compression

Feature blob-deflate: a blob is deflated (zlib level 6) before AES-256-GCM, and kept that way only when shorter; the envelope is a 5-byte magic, the iv, then the ciphertext. Trees, commits, refs, keys and the index are never compressed (trees must stay deterministic; the index must stay readable by an old client so it can read the gate). Every client from 0.24.0 reads both envelopes by inspection. Measured: 1.58× on the comms vault's plaintext as a whole (JSON 2.8×, Markdown 2.5×, .eml 2×, .jsonl 8.8×, images 1×); 2.0× on its blobs after import (355 MB → 176 MB); 1.66× on the AIUC conformance vault; 3.7× on a prose-and-JSON synthetic vault.

6. Numbers to quote

Comms vault history (1,229 commits, 33k objects), from a cloud sandbox against dev:

OperationPack vaultLoose vault
Full clone25 s (18 s download, 4 requests)3½ min
Pull, one commit behind27 s (the merge walk; transfer ~2 s)similar
Pull after a compaction, head already held1.7 s—
Push of one commit27 s (the status/merge walks, same as loose)—
Compaction (251 MB snapshot)76 s—
Import / export (local)90 s / 82 s—

AIUC conformance vault (17 commits, 699 files, 2,087 objects; the reviewer's medians): clone 8.1 s against 28.6 s (3.5×), first push 11.8 s against 27.3 s, push of one file 5.8 s against 10.5 s, pull 3 behind 4.2 s against 4.8 s, blobs 128.6 MB against 213 MB. The safety checks added in the review rounds cost nothing measurable.

7. Compatibility and the gate

8. Security model (threat model rows TM-F37, TM-R38, TM-R39, TM-R40)

9. Tests

tests/unit/pack/ (unit, sync, round trip, performance gates, the review file with one test per finding across four rounds), tests/unit/cli/test_CLI__Pack.py, tests/unit/crypto/test_Vault__Crypto__Deflate.py, tests/unit/network/api/test_Vault__API__Read_Large_Ranges.py, tests/security/test_Security__Fixed__Pack_Members.py, Known_Gaps TM-R38/TM-R40. The performance gates are on request counts and bytes (deterministic), not wall time.

This page as markdown · its source, admin/content/research/pack-mode-feature-reference.md