Contributing
The toolchain, the just recipes, the code and commit conventions, the repository skills and what CI runs.
Set up the toolchain, keep to the conventions, and pass the checks below before every commit. Porting a model and testing have the two longer workflows.
Toolchain
| Tool | Used for |
|---|---|
| Rust 1.94 or newer, and a C compiler | building; the C compiler builds aws-lc-sys for the default download feature |
| a nightly toolchain | cargo +nightly fmt only, since rustfmt.toml uses unstable options |
just | every workflow, as a recipe |
uv | the Python reference scripts, through uv run --project scripts |
| Bun | this site |
Before every commit
- Run
just fmt, thenjust ci: the format check, clippy with warnings denied,just line-lengthsand the workspace unit suite. - For a model change, run the golden suite of every model it touches; when the registry changes, run
just docs-modelsand commit the regeneratedwebsite/public/models.jsonwith it. - For a change under
website/, runjust docs-check. - Write the subject as
<type>: <imperative subject>, under 60 characters, with no scope, no trailing period and no trailer. One logical change per commit, and a fixture travels with the code that needs it.
Conventions
- Rust files stay under the limit
just line-lengthsenforces, andmain.rsholds onlymain; a file that outgrows it becomes submodules. - A comment is one or two lines and says what the code cannot: a constraint or a why; no banners, no restated code, no commented-out code.
- The library never prints: diagnostics go through
tracing, andprintln!belongs to the CLI. - Model code has no
#[cfg]and no device checks; the one backend branch is in the shared attention function. - A field added to a descriptor,
BackendSupportorDtypeBackendSupportcarries#[serde(default)], or#[serde(default = "...")]when the type's default is not the old behaviour, and the constructor sets the same value, so stored descriptor JSON still parses and keeps its meaning. - Everything is in English, and Markdown is not hard-wrapped: one paragraph is one line.
Recipes
just --list prints every recipe; these are the ones the workflows above use.
| Recipe | What it does |
|---|---|
just clippy | clippy over all targets with model-tests, warnings denied |
just test | the workspace unit suite, offline and without weights |
just test-models, just test-metal | the golden suites on the CPU, and on the compiled accelerator |
just test-qwen3-large, just test-rerank-large | the large Qwen3 loads the other recipes leave out for memory, one per process; the 4B embedding's CPU F32 suite takes about two hours |
just parity | the CPU against the accelerator, model by model |
just line-lengths | fails on any Rust file of 300 lines or more |
just fetch <id>, just fetch-phase <n> | downloads one model, or every model of a phase, through the CLI |
just golden <id> [dtype] [device] | regenerates a model's reference from sentence-transformers, in F32 on the CPU by default |
just golden-remote <id> <architecture> <code_revision> | the same for a repository whose architecture is remote code |
just golden-rerank <id>, just golden-rerank-route-check <id> | regenerates a reranker's fixture from its descriptor in scripts/rerank/; checks an offloaded reference route bitwise against a plain load |
just inputs and the *-fixture recipes | rewrite the shared inputs and the STS-B, RoPE, pair, pickle, prompt and window fixtures |
just hub-patterns-fixture | records every catalog repository's file list for the include-pattern test; rerun it when a model is added |
just docs-dev, just docs-build | the site, locally or as a production build |
just docs-models, just docs-demo | regenerate the catalog data from the registry, and the home page demo's scores with the CLI |
just docs-check | every check the site must pass, the link check included |
Repository skills
The skills under .claude/skills/ hold each workflow in full.
| Skill | When to read it |
|---|---|
porting-embedding-model | before adding a model or a family; porting a model is its public form |
golden-vector-testing | when generating or debugging references |
hf-model-download | for downloads, revisions, the cache and gated repositories |
device-compat | for anything Metal, CUDA or dtype related |
commit-workflow | before every commit |
docs-writing | for anything under website/ |
CI
| Workflow | When | What it runs |
|---|---|---|
ci | every push to main and every pull request | a lint job: the format check, clippy with model-tests, the no-default-features build and tests, the publish dry run and the line check; a test job: the unit suite and the golden modules testing lists |
metal | manually, or on a v* tag | the bge and MiniLM golden modules on an Apple runner |
cuda | manually, or on a v* tag | the test job's golden modules, built in NVIDIA's CUDA container and run on a T4, with BF16 skipped below sm_80; a manual run with sweep: full runs every entry's but the non-commercial ones', fetching the gated EmbeddingGemma with the HF_TOKEN secret |
metal-dtype-smoke | every push to main | MiniCOIL's F16 and BF16 golden modules on Metal, which compute only there |
docs | a push to main or a pull request that touches the site, the README, the examples, or the library or CLI source | the examples build, the audit, typecheck, site build and link check |
Only workflow_dispatch and v* tags may target the gpu-t4 runner: workflow_gpu_runner.rs fails the default test run if another workflow names it, or if cuda's on: holds anything else. CI checks a small part of the catalog; the rest is verified locally before a model commit lands.