# AGENTS.md This file is the README for *coding agents* working on the emem source. Per the [agents.md convention](https://agents.md) (OpenAI Codex, 2025; Linux Foundation AAIF, Dec 2025): build commands, test rules, code style, and what's off-limits during autonomous runs. End users of the protocol should read [docs/agents.md](docs/agents.md) and [skills.md](web/skills.md) instead; those describe how to *use* emem from an agent. ## First 5 minutes (using emem as an agent) If you only want to *call* emem (not edit its source), here is zero to a signed answer in three calls: 1. **Ask.** `POST /v1/ask {"q":"what is the NDVI near Mount Fuji?"}` (MCP tool `emem_ask`, or `emem_intent` / `POST /v1/intent` for a structured single-shot). The classifier routes the question to one of four paths. These are a self-description of emem, a corpus audit, a hunter sweep over a region, or a point answer. A corpus audit redirects to the coverage endpoints and has no receipt. The hunter sweep and the point answer carry a signed receipt. Ask answers a point question with the current value, or with a reading of the date the question names; when it holds no reading of that date it says `cannot_tell` rather than answer from another date. `direct_answer` carries the verdict, the band and the limits, and `context.context_id` continues the thread. Send a change question ("how has X changed") to `emem_intent` with `did_change`, or to `emem_diff`. This is the fastest path. 2. **Or take control.** `POST /v1/locate {"place":"Mount Fuji"}` → a `cell64`, then `POST /v1/recall {"cell":""}` (auto-materialises on a miss). 3. **Cite it.** Verify the receipt offline at `/verify` or through `POST /v1/verify_receipt`; hand other agents an `emem:fact:` token from `emem_memory_token` (or `emem_memory_bundle` for several). Newer "connect & evolve" surfaces (typed temporal edges, the contradiction-fed refinement loop) are walked end-to-end in [examples/connect-and-evolve.md](examples/connect-and-evolve.md). Full usage guide: [docs/agents.md](docs/agents.md). The rest of this file is for agents editing the source. ## Repo shape Rust workspace, 19 crates, version 2.4.5, MSRV 1.91. `emem-guard` is the verdict server for AI inference checkpoints, such as Anthropic Inference hooks and Claude Code hooks. It is a separate binary and shares no code path with the responder. The bulk of the code lives in `crates/emem-api-rest/src/lib.rs` (HTTP/MCP router plus every inline materializer) and `crates/emem-fetch/src/*.rs` (27 data connectors + 8 utility modules). Earlier versions ran Clay, Prithvi, Galileo and JEPA-v2 on a GPU sidecar; facts they signed still verify. Web surface in `web/` is plain HTML, no build step, included with `include_str!`. ## Build ```sh # Full workspace, debug cargo build --workspace # Release binary, for a local or self-hosted node cargo build --release --bin emem-server ``` Production (emem.dev) does not run a binary built on the host. It runs a container under the system unit `/etc/systemd/system/emem-server.service`, which starts the image with `docker run`. To deploy: 1. Push the commit to `main`. 2. Wait for the `publish` workflow (`.github/workflows/publish.yml`) to finish with success. It builds and pushes the image. 3. Run `/home/ubuntu/emem-ops/pending_deploy.sh `. Both arguments are 7-character commit shas: the new one, and the last good one to roll back to. Do not use `scripts/redeploy.sh` on the production host. It builds on the host and restarts a user unit that production no longer uses. It is only for a node that runs the binary directly. ## Test ```sh # Unit + bin + crate-level integration, no network cargo test --workspace --lib --bins --tests # Network-gated tests live in crates/emem-fetch/tests/live_cog_fetch.rs # and skip automatically when offline. There is NO `live` cargo feature. # Don't write `--features live`, that flag doesn't exist. cargo test --workspace --test live_cog_fetch ``` Unit tests live inline in `src/` next to the code they cover (`#[cfg(test)] mod tests`). Crate-level integration tests live under `crates//tests/`. Five crates have those today: `emem-airgap`, `emem-fact` (round-trip), `emem-fetch` (live COG fetch), `emem-primitives` and `emem-trace`. ## Lint + format ```sh cargo fmt --all # local cargo fmt --all --check # CI gate cargo clippy --workspace --all-targets -- -D warnings # CI gate ``` Both gates run in `.github/workflows/ci.yml` on Linux. Only the `test` job runs on Linux and macOS. There is also an MSRV 1.91 build job. Do not ship a commit that fails either. CI rejects it, and the next agent then has to find out why. Every action in `.github/workflows/` is pinned to a full commit SHA with its tag in a trailing comment (`@ # v4.4.0`). A tag can be moved to other code; a SHA cannot. To bump one, resolve the new tag with `git ls-remote --tags https://github.com//` (take the peeled `^{}` line for an annotated tag) and change the SHA and the comment together. Two hard-won specifics: - CI installs Rust from the `stable` branch of `dtolnay/rust-toolchain`. That action is pinned to a commit like every other action, and the commit installs the stable that is current when the job runs. So the clippy gate tracks CURRENT stable, not the MSRV. Run `rustup update stable` first, or lints that are new in stable pass locally and fail in CI one at a time. Never run it while a build runs: it deletes the old toolchain's rlibs under the compile. - Run clippy with `--all-targets`. A plain `--lib` test run never compiles the integration-test and demo-bin targets, and CI finds what you missed there. ## Code style - **No `unsafe`.** Every crate carries `#![forbid(unsafe_code)]` at the top. - **No `unwrap()` on user-facing paths.** Use `?` with structured errors; the `MaterializeMiss` / `CidNotFound` types are designed to surface honest gaps without panicking. `unwrap()` is fine inside tests. - **Don't widen `pub`.** Keep crate boundaries tight. New public API needs a justification in the commit message. - **Comments**: only when the *why* is non-obvious (a hidden constraint, a workaround for a specific bug, a subtle invariant). Don't explain *what* the code does; well-named identifiers do that. Don't reference the current task or PR; those belong in the PR description. - **Receipts and CIDs are load-bearing**. A change to `crates/emem-storage/src/server.rs::sign_receipt` or to the canonical-CBOR layout in `crates/emem-fact/src/` needs two more updates. Update `docs/protocol.md` (the byte-by-byte preimage example). Update the in-browser verifier at `web/humans.html` (the BLAKE3 + Ed25519 path). These three places must always agree. ## Commit + PR conventions Commit messages are sentence-case, ≤72 chars on the subject line. Body explains the *why* and any non-obvious wire/protocol implications. Tag with the version prefix when relevant (`0.0.8: …`). **Never** add a `Co-Authored-By: Claude` trailer or any AI attribution trailer. The user has stated this preference in `/home/ubuntu/.claude/projects/-home-ubuntu-emem/memory/feedback_no_claude_coauthor.md`. Don't commit on the user's behalf without an explicit instruction. Don't force-push to `main`. Don't `--no-verify` past pre-commit hooks; if a hook fails, fix the underlying issue. ## Off-limits during autonomous runs - `var/emem/identity.secret.b32`: the responder's Ed25519 secret. Never read, copy, or commit this file. It is mode `0600` for a reason. - `var/emem/sled/`: the live attestation log. Never delete or rewrite; agent-replayable bugs are debugged from this log. - `crates/emem-codec/src/alphabet.rs`: the cell64 alphabet builder. Changing this rotates every cell64 in the corpus. Don't touch without a registry CID rotation plan. - `web/index.html` GA injection: the consent banner is GDPR-compliant by design; don't simplify it without re-reading `docs/operators/operating.md` § Privacy/GA. ## Where to find things | concern | path | |---|---| | HTTP/MCP router, route registrations | `crates/emem-api-rest/src/lib.rs` | | Inline materializers | `crates/emem-api-rest/src/lib.rs` (search `^async fn materialize_`) | | Open-data connectors | `crates/emem-fetch/src/*.rs` (27 data modules + 8 utility) | | Receipt signing + preimage | `crates/emem-storage/src/server.rs::sign_receipt` | | Canonical CBOR + FactCid | `crates/emem-fact/src/{cbor,cid}.rs` | | Cell64 / tslot / alphabet | `crates/emem-codec/src/` | | Merkle log + per-fact proofs | `crates/emem-storage/src/{merkle_log,server}.rs` | | Registries (10 manifest digests, `GET /v1/manifests`) | `crates/emem-core/data/*.json` + `src/` | | MCP tool registry (116 tools) | `crates/emem-mcp/src/lib.rs` | | Read primitives | `crates/emem-primitives/src/*.rs` | | Reference offline verifiers (kept out of the plugin, which ships no code) | `tools/verifiers/` | | Hunter and corpus-audit classifiers for /v1/ask | `crates/emem-api-rest/src/ask_foundation.rs` | | Physics solvers (heat / wave / NDVI AR(2)) | `crates/emem-api-rest/src/physics.rs` | | `/humans` interactive console | `web/humans.html` | | Static web surface | `web/` (served with `include_str!` from api-rest) | | Demos | `crates/emem-cli/src/bin/emem-{demo,livedemo,realdemo}.rs` | ## Where to read more - [docs/developers/architecture.md](docs/developers/architecture.md): what shape the protocol takes - [docs/protocol.md](docs/protocol.md): wire format, preimages, encodings - [docs/whitepaper-v2.md](docs/whitepaper-v2.md): math + design rationale (v1 archived at docs/whitepaper-v1.md) - [docs/operators/operating.md](docs/operators/operating.md): deployment, env vars, TLS, CSP - [docs/developers/developing.md](docs/developers/developing.md): dev workflow + test invariants - [docs/agents.md](docs/agents.md): *consumer*-agent guide (how to USE emem) - [web/skills.md](web/skills.md): composed recipes for agent integrations - [plugins/emem/](plugins/emem/): the Claude Code plugin, MCP server plus nineteen skills, installable with `/plugin marketplace add Vortx-AI/emem`