Files
alkblobs/AGENTS.md
T
glm-5.3-flash 4b5009d85a docs(architecture): Phase 1 spec tree — 7 specs, ADRs 001-006, OQ tracker
- 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
2026-10-01 14:45:32 +00:00

180 lines
8.9 KiB
Markdown

# 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 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 <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.
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.