--- status: draft last_updated: 2026-10-01 --- # Hashing and keys ## What this is The content-address layer: the canonical hash derivation every entry is keyed under, the tolerated legacy algorithm, the typed `Key`/`Digest` surface the store API speaks, and the physical byte encoding of keys inside backends. This is the crate's one-way door: key byte layouts are persisted in backend rows and filenames, survive digest-layer evolution, and must precede any wire consumer (AGENTS convention 5; phase-0 OQ-BL-03 residual). ## The hash family Three hash-policy classes (ADR-002 §Decision; resolved from OQ-BL-03 after the "multi-hash" premise dissolved — nothing forces BLAKE3 once iroh-blobs' inheritance is rejected): 1. **Canonical — `git-blob-sha-256`:** the git oid derivation `H("blob \0" + content)` with SHA-256, uncompressed content. Chosen because alkgit *forces* git's derivation by protocol definition, and every other consumer (workspaces, appfile) sees addresses, not algorithms — so one algorithm domain makes the pool one address space and cross-consumer dedup free by construction (ADR-005). 2. **Tolerated legacy — `git-blob-sha-1`:** existing git repositories are overwhelmingly SHA-1; the store accepts them under the same preamble discipline. Git's own collision-hardened SHA-1 threat model is inherited verbatim; the store adds nothing and weakens nothing. 3. **Not present — BLAKE3:** demoted out of the crate entirely. If a chunk-tree transfer encoding is ever adopted, it is a new decision at a new layer (ADR-006); its verified whole-contents would register as ordinary `git-blob-sha-256` entries. Security posture: one algorithm across consumers is safe here — SHA-256 has no practical cross-protocol ambiguity at these input shapes, and the preamble domain-separates the derivation (ADR-002 §Consequences). ## Key encoding (the one-way door) Physical key bytes inside backends (POC #1 finding 5, validated in the interop test where an oid produced by *external git* addresses the same pool entry the store puts): - **Algorithm identity is part of the key itself** — a per-store single-algorithm configuration cannot express git-sha-256 and git-sha-1 coexisting in one flat pool, which the external-oid test proves is required. - **Fixed-length, enum-tagged:** `1 algorithm byte + digest bytes` (32 for sha-256, 20 for sha-1). The POC's extra "kind" tag byte is dropped — there is exactly one key kind. Algorithm bytes are assigned from a single registry constant in ADR-002 so external producers can compute them. - **Sort stability:** fixed-length enum-tagged keys sort cleanly in a total order — required for the sweep's live-set diffs (list() walks are plain range scans; ADR-005). - **Opaque to backends:** the `Backend` trait speaks opaque byte keys (ADR-003); only the store core constructs and interprets typed keys. ## The Key/Digest surface (WHAT the API exposes) - `Digest` — an algorithm + digest pair; construction via the canonical derivation from content (known length) or from a pre-computed pair (interop: `from_git_oid_hex` shape validated in POC #1 finding 4). - `Key` — the typed wrapper; `as_bytes()` / `from_bytes()` are the only conversions across the backend boundary. Malformed key bytes (truncated, unknown algorithm) are rejects, never guesses — the POC's length-checking test is the standard. - Verification semantics ride the whole-blob posture (ADR-006): put and get paths hash-check against the canonical derivation; there is no per-range hash relationship under this derivation (preamble includes the length), which is the constraint ADR-006 documents rather than works around. ## Design Decisions | ADR | Decision | Summary | |---|---|---| | [002](decisions/002-canonical-hash-and-key-encoding.md) | Canonical hash + key encoding | three-tier hash policy; algorithm-in-key byte layout; the declared wire-format ADR | ## Open Questions None owned by this document. The interop surface alkgit ultimately needs (oid formats, hex/binary conventions at *its* boundary) is OQ-07 — alkgit's question, not a key-encoding question. ## References - `docs/research/phase-0.md` OQ-BL-03 (resolution + key-encoding mechanics) - `docs/research/poc-trait-dispatch-findings.md` findings 4/5 (byte-exact git CLI validation; tagged-key coexistence) - gix-odb (`/workspace/gitoxide/gix-odb`) — the consumer-side baseline for object reads/writes - ADR-002; ADR-003 (opaque byte keys at the backend boundary); ADR-006 (what verification is possible under this derivation)