# 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: 1. Make the change 2. Verify: `cargo test`, `cargo clippy --all-targets -- -D warnings`, `cargo fmt --check`, `cargo doc --no-deps` if docs changed 3. Inspect `git status` and `git diff` before staging — stage only the intended files, never secrets 4. 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. 5. `git push origin main` 6. 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 `). 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. 1. **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. 2. **Error handling** — `thiserror` for library error types. No panics in library code. No `unwrap()` or `expect()` outside tests. If you reach for `unwrap`, the error path wasn't specified — stop and decide what should actually happen. For poisoned `RwLock`/`Mutex`, use `unwrap_or_else(|e| e.into_inner())` so a panic in one operation does not cascade to other operations. 3. **`tokio` is the async runtime** — all I/O is async. Use `tokio::sync` primitives (`oneshot`, `mpsc`) for lifecycle correlation; `parking_lot` for short-held internal locks. Do not introduce blocking I/O on the async path. 4. **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). 5. **Canonical hash is the git-family derivation** — the store keys entries under git's oid derivation (`"blob \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. 6. **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. 7. **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). 8. **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) and `cargo test --all-features` pass if features are added. 9. **Naming** — Rust standard: `snake_case` for functions/variables/ modules, `PascalCase` for types/traits, `SCREAMING_SNAKE_CASE` for constants. 10. **Module structure** — one module per file under `src/`, re-exported from `src/lib.rs`. Public API surface is `lib.rs` re-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. ```bash 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, and `phase-0.md` (vision, prior art, open questions, converged recommendation). Read it before non-trivial work. The SDD process lives in `docs/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.md` tracks 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; its `AccessControl`/identity seam is the authorization story for network-facing blob ops. - 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.