Contributing to emem
August 24, 2026 · View on GitHub
emem is a Cargo workspace. Rust 1.91, edition 2021, 19 crates, one binary
(emem-server) at the centre. The agent-facing surface is a single axum
router in crates/emem-api-rest/src/lib.rs; everything else feeds into it.
Where to start
git clone https://github.com/Vortx-AI/emem && cd emem
cargo build --workspace
cargo run --release --bin emem-server # 0.0.0.0:5051
Hit http://127.0.0.1:5051/v1/discover to see the full bootstrap; that's
the same JSON an agent gets. crates/emem-cli/src/bin/emem-livedemo.rs
exercises every primitive end-to-end and dumps signed receipts under
var/demos/<UTC>/.
Ground rules
No stubs, no silent fallbacks. Don't commit todo!(), unimplemented!(),
"lands in vX" comments, hardcoded fake values, or empty handlers wired into
the router. If a code path needs an upstream that isn't reachable, return a
typed ErrorCode (SourceFetchFailed, Unauthorized, BandNotMaterialised)
with a clear message. That's real semantics. If a feature is out of scope,
delete it rather than leaving a placeholder. Empty results must distinguish
"wrong query" from "place is empty": recall returns bands_available so
the caller can tell.
Receipts must round-trip. Any change to a primitive's response, signing
preimage, or fact-CBOR layout has to keep verify_receipt green against
old receipts. Run cargo test -p emem-fact and replay a receipt from
var/demos/ before opening the PR.
Open licences, open data. Every dep stays MIT / Apache-2.0 / BSD / ISC
(cargo deny check licenses). New default-build connectors must use
no-auth open data (Copernicus, JRC, Hansen, ESA, OSM, met.no, Open-Meteo,
Tessera, …). Keyed providers go behind an operator-registered connector,
opt-in.
Docs follow the house prose convention. Short sentences, plain words,
no em or en dashes (use a comma, a colon, or a full stop). State what
ships and what is open in the same paragraph; never present roadmap as
capability. Every number in prose must trace to a registry or a
measurement (python3 scripts/sync_counts.py checks the known ones), and
every claim must be verifiable against the code as written. A withdrawn
claim is recorded, not silently deleted; the whitepaper's section 18 is
the pattern. A CI doc-lint for the mechanical parts is roadmap work; until
it lands, review enforces this by hand.
Adding a band
- Add the entry to
crates/emem-core/data/bands-v0.json. Each band hasdim_offset,dim_count,tempo,privacy_class,materializer. - Wire the materialiser. Add a connector module under
crates/emem-fetch/src/<your_source>.rsand register it incrates/emem-fetch/src/connectors.rs. - Map band → connector in the dispatch table in
crates/emem-api-rest/src/lib.rs(search for the existing band you're modelling on, e.g.weather.temperature_2m). - The new band auto-discovers via
/v1/bandsonce the manifest CID rolls forward. No router change needed.
Adding an algorithm
- Append to
crates/emem-core/data/algorithms-v0.jsonwith a unique versioned key (my_score@1),inputs(band names),formula(string, evaluable),output_unit,references. - The algorithm is now visible at
GET /v1/algorithmsand routable from/v1/locate'salgorithms_for_topic. - If the formula needs evaluation logic the existing engine doesn't
handle, extend
crates/emem-primitives/src/<…>rather than inlining it in the router.
Adding a connector
- Create
crates/emem-fetch/src/<source>.rs. ImplementSourceConnectorwithkind,fetch, andrange_readfor COG sources. - Register the source in
crates/emem-core/data/sources-v0.json(scheme,endpoint,licence,attribution). - Add an integration test under
crates/emem-fetch/tests/patterned onlive_cog_fetch.rs. Live tests skip whenEMEM_NO_NETWORK=1is set.
Tests
cargo fmt --all
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
EMEM_NO_NETWORK=1 cargo test --workspace # CI default: skips network
Live network tests run when EMEM_NO_NETWORK is unset; they hit real
public COGs and STAC endpoints (Cop-DEM, Hansen, JRC GSW, Sentinel-2
L2A) and tolerate upstream flakiness so they don't break CI.
Commits and PRs
- One logical change per PR.
- Branch from
main. Descriptive name:feat/diff-derivative,fix/sled-prefix-scan,docs/agent-card-examples. - Conventional prefixes welcome (
feat:,fix:,docs:,refactor:,test:,chore:) but not enforced. - Never use
--no-verify. If a hook fails, fix the underlying issue and push a new commit; don't bypass. - Never add
Co-Authored-By: Claude(or any AI co-author trailer) to commit messages. - If the change touches a primitive, attach a fresh
var/demos/<UTC>/trace.jsonfromemem-livedemoshowing it green.
Reporting bugs
GitHub issues. Include:
- Server version (
/healthJSON:version,responder_pubkey_b32). - Minimal reproduction (curl command + body, or MCP
tools/callpayload). - Expected vs actual (paste the receipt or error envelope verbatim).
- For receipt issues: include the full receipt JSON. We replay the preimage and verify offline; short receipts speed this up.
Security
Vulnerability disclosure: see SECURITY.md. Email
avijeet@vortx.ai directly for sensitive issues rather than opening a
public issue.
Code of conduct
By participating you agree to abide by CODE_OF_CONDUCT.md.
License
Apache-2.0 (see LICENSE). No CLA. By contributing you agree your contributions are licensed under the same terms as the rest of the repo.