Files
alkblobs/AGENTS.md
T
glm-5.3-flash 7f7f70b220 feat: initial repo setup (Phase 0 scaffolding)
- AGENTS.md: repo conventions adapted from alkcall/alksocks (store
  posture, multi-hash requirement, no-iroh-wire rule; no fuzz gate yet)
- Cargo.toml + src/lib.rs: bare lean lib skeleton (tokio async, thiserror)
- docs/research/phase-0.md: Phase 0 draft — vision, prior art (iroh-blobs
  store, gix-odb, alknet appfile probe, alkcall), OQ register, POC plan
- .gitignore, LICENSE-APACHE/MIT
- Re-pointed stale alknet/alkcall references in .opencode/agents/ and
  docs/sdd_process.md

Verification: cargo build/test, cargo clippy --all-targets -- -D
warnings, cargo fmt --check, cargo doc --no-deps — all pass
2026-09-30 07:45:40 +00:00

8.6 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:

  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 <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 0 (Exploration) — docs/research/ is the working state of the repo; docs/architecture/ does not exist yet and no wire format, API shape, or backend trait is decided. 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. Hashes are data, not identity of transport — the crate must tolerate multiple hash algorithms (the alkgit conflict: git's SHA-1/ SHA-256 object hashes vs iroh-blobs' BLAKE3). How the hash algorithm is abstracted (trait, enum, per-backend configuration) is a Phase 0/ 1 decision, not yet pinned. Do not hardcode a single algorithm.

  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.

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/ — does not exist yet (Phase 1 output). When it lands, 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/git-oxide/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.