- overview/hashing/store-api/backends/gc/ops specs + README index, all draft status with YAML frontmatter and cross-referenced ADR/OQ - ADR-001: substrate posture (store layer alkcall-free = family conformance, not deviation) + ops placement decided (feature-gated module, no consumer-waited deferral) - ADR-002: canonical git-blob-sha-256 + key encoding — the declared wire-format ADR (one-way door) - ADR-003: backend contract, sqlite/fs/mem tiers, pure-function dispatch, no migration, unknown-length buffering semantics pinned - ADR-004: exactly two production backends; manifest/path-tree layers are consumer-side (the corrected two-vs-three-backends framing) - ADR-005: pooled CAS, three liveness sources, delete windows with pin-before-publish + delete-time arbitration (race closed), no ambient scheduling - ADR-006: whole-blob verification; chunk-tree encodings excluded by scoping, not deferred on a paused consumer - open-questions.md: OQ-BL-01..06 resolved with ADR cross-refs; OQ-07 /08 externally-owned, OQ-09 deferred(scope) with SDD tracker task - AGENTS.md: status updated to Phase 1, gix-odb path corrected Verification: cargo test / clippy -D warnings / fmt --check clean
8.9 KiB
AGENTS.md
Operating instructions for opencode agents working in this repo. opencode
auto-loads this file as instructions, overriding the built-in defaults for
this project. Custom agents in .opencode/agents/ inherit these rules
unless their own prompts say otherwise.
Git Workflow
Commit and push when reasonable. When a change is complete and
verified (build + lint + tests pass), commit and push to origin/main
without asking. This overrides the built-in default of "only commit when
explicitly asked."
The workflow:
- Make the change
- Verify:
cargo test,cargo clippy --all-targets -- -D warnings,cargo fmt --check,cargo doc --no-depsif docs changed - Inspect
git statusandgit diffbefore staging — stage only the intended files, never secrets - Write a concise commit message matching the repo style (see
git log --oneline -10). For multi-point changes, use a summary line plus a body with bullet points and a verification block. git push origin main- Report the commit hash and the verification summary
Exceptions — do not commit or push without asking:
- The change is exploratory / speculative (you're not sure the user wants it kept)
- The user is actively reviewing the diff and may ask for changes
- The change touches the wire format, a trait shape backends implement, or the hashing/verification story (one-way doors once consumers exist — see convention 7; nothing is wire-stable yet, but the first wire-format ADR must be written before the first consumer)
- You'd be force-pushing, amending a published commit, creating an empty commit, or skipping hooks
Never commit secrets, keys, or credentials. If a commit fails or hooks reject it, fix the issue and create a new commit — do not amend the failed one.
Git identity is preconfigured (glm-5.3-flash <glm-5.3-flash@alk.dev>). Do
not change git config, skip hooks, or use git commit -i.
Project Conventions (Rust / blob storage crate)
This is the blob storage crate — content-addressed blob storage in the
alk* family, inspired by iroh-blobs' store work but deliberately not a
fork of it. It sits downstream of alkcall (the call + channels substrate
its network operations ride, when they exist) and its first planned
consumer is alkgit (git object storage, where the iroh-blobs hashing
story collides with git's own object hashes). Status: Phase 1
(Architecture) — Phase 0 converged (see docs/research/phase-0.md);
docs/architecture/ is the working state of the repo (specs, ADRs
001-006, open-questions tracker). The conventions below apply to all work in
src/ and tests/. They mirror
.opencode/agents/implementation-specialist.md §Project Conventions and
are repeated here so they apply to every session.
-
No comments in code unless the user explicitly asks. This is a project-wide convention. Doc comments (
///,//!) are fine and expected on public API. Inline//comments only when the user asks or when a non-obvious safety/correctness constraint would otherwise be missed. -
Error handling —
thiserrorfor library error types. No panics in library code. Nounwrap()orexpect()outside tests. If you reach forunwrap, the error path wasn't specified — stop and decide what should actually happen. For poisonedRwLock/Mutex, useunwrap_or_else(|e| e.into_inner())so a panic in one operation does not cascade to other operations. -
tokiois the async runtime — all I/O is async. Usetokio::syncprimitives (oneshot,mpsc) for lifecycle correlation;parking_lotfor short-held internal locks. Do not introduce blocking I/O on the async path. -
Substrate-agnostic by construction — the store layer must not know whether bytes arrive over the network, from a local writer, or get reassembled anywhere particular. iroh-blobs welds its store to its provider/ticket/postcard stack; this crate's defining posture is the opposite split: the store (put/get/verify against a hash) is its own layer, and transport/protocol concerns live above it or in feature-gated modules. This is the same inversion-point pattern as the alk* family (alktty
TtyBackend, alktunnels pump halves). -
Canonical hash is the git-family derivation — the store keys entries under git's oid derivation (
"blob <len>\0" + content), SHA-256 canonically, SHA-1 tolerated (existing repos; git's own hardened-SHA-1 threat model inherited). The hash-conflict framing dissolved 2026-10-01: BLAKE3's presence was an iroh-blobs inheritance, not a requirement — it is demoted to a conditional large-blob encoding consideration (docs/research/phase-0.md OQ-BL-03). Do not hardcode beyond the small enum abstraction: the key encoding is a one-way door. -
Auth-gated operations ride the alkcall authorization seam — when network-facing operations exist, authorization happens via alkcall's
AccessControl/identity mechanisms (the producer/consumer model), not via an in-band invented auth scheme. Producer/consumer vocabulary, not "server"/"client" (alkcall ADR-022/037). Not yet pinned in detail — the ops surface is a Phase 0 question. -
Do not adopt iroh-blobs' wire surface — tickets, the postcard serialization, and the provider protocol are iroh-blobs' design-welded choices we have decided not to inherit. Reading
/workspace/iroh-blobs(a fresh upstream checkout) is encouraged for store-shape lessons (src/store, the kv + flat file backends); borrowing its conclusions is fine, wiring in its types, framing, or serialization as load-bearing dependencies is not (yet — the dependency posture is a Phase 0 question if a small pure piece, like bao outboard encoding, earns its place). -
Feature flags — substrate backends (kv, sqlite, flat fs) may be feature-gated if the need arises. The base crate should compile lean. Verify both
cargo test(default) andcargo test --all-featurespass if features are added. -
Naming — Rust standard:
snake_casefor functions/variables/ modules,PascalCasefor types/traits,SCREAMING_SNAKE_CASEfor constants. -
Module structure — one module per file under
src/, re-exported fromsrc/lib.rs. Public API surface islib.rsre-exports. The expected shape (pending Phase 0 convergence) separates the backend/store layer from any protocol/ops layer.
Verification Commands
Run these before committing. All must pass.
cargo test # full suite
cargo clippy --all-targets -- -D warnings
cargo fmt --check
cargo doc --no-deps # if docs changed
cargo publish --dry-run --allow-dirty # before a release
If feature flags are added, also run cargo test --all-features and
cargo clippy --all-features --all-targets -- -D warnings.
No fuzz targets exist yet for this crate. If/when a wire format is
pinned (Phase 1), a fuzz gate on the model of alkcall/alksocks (fuzz/
corpus replay on stable) is expected — until then ignore fuzzing.
Architecture Context
docs/research/— the Phase 0 (Exploration) state of this repo: research findings, POC records, andphase-0.md(vision, prior art, open questions, converged recommendation). Read it before non-trivial work. The SDD process lives indocs/sdd_process.md.docs/architecture/— exists (Phase 1 in progress: specs draft, ADRs 001-006 accepted, open-questions tracker active). The SDD process applies: specs describe WHAT,decisions/ADRs explain WHY,open-questions.mdtracks what's unresolved.- Key prior art (read-only, in the global workspace):
- iroh-blobs —
/workspace/iroh-blobs(fresh upstream checkout): the shape inspiration, specifically its store work (kv + flat file backends, bao verification, chunking). Its wire-surface choices (tickets, postcard, BLAKE3-only) are the ones we are deliberately diverging from. - gix-odb —
/workspace/gitoxide/gix-odb: git's own object database; the backend alkgit currently plans against and the hashing-algorithm baseline git actually uses. - alknet's blobs research —
/workspace/@alkdev/alknet/docs/research/alknet-filesystem/(alknet-blobs-external-store-probe.md,poc-summary.md): the appfile external-store probe — small blobs in a kv/sqlite-ish store, large blobs on the filesystem fallback, filename↔hash mapping. Written against an older iroh-blobs than the current checkout; re-verify conclusions before relying on them. - alkcall —
/workspace/@alkdev/alkcall(the substrate): call + channels; itsAccessControl/identity seam is the authorization story for network-facing blob ops.
- iroh-blobs —
- If a TODO references a design direction that a later ADR has decided against, the TODO is stale — remove it and align with the ADR. Do not implement the rejected design.