Repository navigation
Architecture
A Rust workspace (edition 2024, MSRV 1.90) of eleven crates under crates/, organized in planes where dependency arrows only ever point toward core.
Related pages: Engine (the core crate's behavior) · Decisions (the IR) · Interfaces (the five interface crates) · Contributing (the gates below as a workflow).
- Crate table
- Dependency direction (binding)
- Sync core, async edges
- Wire formats live in schema only
- Feature matrix (D11)
- Floating-point policy
- Failure posture
- Workspace lints
- Quality gates (the CI contract)
- CI platform
| Crate | Plane | Owns |
|---|---|---|
opencodifier-core |
decision core | canonical IR: validating constructors, Distribution, ConfidenceReport + outcome routing, stable ir.* error codes, trace_version, #[non_exhaustive] enums. Pure — no local deps
|
opencodifier-schema |
adapters | the only place wire formats are named: native (identity) / OpenAI structured outputs / Anthropic tool schemas / Jev/System One, plus the DecisionDefinition registry. Byte-locked fixtures under fixtures/
|
opencodifier-engine |
deterministic engine | DAG executor, rule engine, metadata + hand-written BM25 narrowing, exact-decision cache (CacheKeyBuilder, D6), relational solver, Calibration + LadderPolicy seams, cross-rung escalation, focused extraction, optimizer, EngineHandle facade, the transport-neutral wire module |
opencodifier-runtime |
inference runtime |
InferenceBackend / EmbeddingBackend traits (sync, object-safe, logits-only), validating DenseTensor, mock backends; ort only behind the onnx feature (Kai + Julia ONNX transports live here) |
opencodifier-model |
decision model | candidate-conditioned serving contract, EmbeddingClassifier, SHA-256 ModelManifest (D14), the Kai (D33) and Julia (D34) contracts with committed parity fixtures, the NLI verbalization verifier contract, the llama.cpp decision rung (D26, llamacpp feature), shared answer-key rendering |
opencodifier-itemgen |
corpus tooling | D37 relational/contrastive item generator: sample → render through the engine's extraction grammar → solver-verify. Corpus emission only — never a serving dependency |
opencodifier-http |
interface | axum 0.8 /v1 API (D12 amended), loopback-default bind, error envelope, x-opencodifier-format selection (D30) |
opencodifier-cli |
interface | clap v4 binary opencodifier: decide / graph / serve / mcp / models / ladder / recipe, D13 exit codes |
opencodifier-mcp |
interface | rmcp 2.2 stdio server, six codify_* tools (D17). Stdio only — local by construction |
opencodifier-wasm |
interface |
WasmEngine over the zero-ML stack for wasm32-unknown-unknown (D23); dual glue (web + nodejs) in releases |
opencodifier-ffi |
interface | C-ABI staticlib over the same wire module (D24); hand-written include/ocffi.h that integration tests re-declare so header and implementation cannot drift |
cli ──► http ──┐
├──► engine ──► core ◄── schema
model ──► runtime ──► core
└────────► engine
itemgen ──► engine ──► core (itemgen also declares the direct core edge)
mcp / wasm / ffi take the same engine-facade edge as cli/http
Binding rules (PLANNING.md §39):
-
opencodifier-coremust never depend on HTTP, MCP, CLI, Tokio, or any ML runtime. - Each heavyweight dependency is confined to exactly one crate (matrix below); no crate may enable another crate's heavyweight feature transitively.
- The default build of the whole workspace is ML-free and runtime-free.
The core and engine are synchronous — deterministic, testable, trivially embeddable. I/O shapes are traits (Clock, Deadline, CancellationToken, InferenceBackend); async wrappers (Tokio, wasm-bindgen) live in the interface crates. The HTTP/MCP servers own any threading; the engine stays single-threaded per request. Deliberate asymmetry, not inconsistency: a concurrent HTTP server must protect unrelated connections (spawn_blocking off the async workers), while a stdio MCP session is strictly sequential and calls the engine inline.
Native IR is the truth; adapters are total functions in both directions with fixture-locked round-trips: native ⇄ OpenAI structured outputs, native ⇄ Anthropic tool schemas, native ⇄ Jev/System One (state/model/questions; score answer = probability-weighted mean index; noul = probability of yes). Where a format cannot express an IR feature, the adapter refuses or discloses (e.g. unsupported_generation_field) — it never pretends.
| Feature | Crate | Pulls in |
|---|---|---|
| (default) | core, engine, schema | serde, thiserror, sha2 — nothing heavy |
onnx |
opencodifier-runtime |
ort =2.0.0-rc.13 (D2 pin; reinstated for the Kai/Julia rungs under D33/D34) |
runtime-onnx-dynamic |
opencodifier-runtime | ort load-dynamic (system dylib via ORT_DYLIB_PATH) |
llamacpp |
opencodifier-model | ureq (sync HTTP client only, D26) |
tokenizers |
opencodifier-model |
tokenizers 0.22 + fancy-regex (Kai reference encoder, D33) |
http |
opencodifier-http | axum 0.8, tokio |
mcp |
opencodifier-mcp | rmcp 2.2 (D1) |
cli |
opencodifier-cli | clap v4 |
wasm |
opencodifier-wasm | wasm-bindgen, getrandom js |
- All decision math (softmax, calibration, margins, entropy, weighted score means) is Rust f64 — never inside an ONNX graph — so CPU/GPU/quantization cannot change a decision (D7).
- ONNX returns logits; Rust converts.
- Comparisons use
total_cmpor explicit tolerances; thefloat_cmplint is allowed only in test modules. - Cross-implementation float equality is never assumed (measured: ORT vs Rust softmax agree to ~5 ULP, never bit-identical — D2).
- Malformed or hostile input → typed error with a stable code, never a panic.
- Unknown wire fields are ignored forward-compatibly — except the native IR, which denies unknown fields.
- Model artifacts are SHA-256-verified against a manifest before load;
models/is never committed. - Default posture is local: bind
127.0.0.1, no outbound calls. See Security.
unsafe_code forbidden workspace-wide (one documented exception in the FFI crate, where pointer handling is the boundary, pinned by a drift-guard test); missing_docs warned and CI-enforced via -D warnings; clippy all + pedantic with unwrap_used, expect_used, panic, todo!, unimplemented!, dbg_macro, print_stdout denied. Test modules may re-allow unwrap_used, expect_used, panic, float_cmp at module level only. No placeholders anywhere: no TODO/FIXME/stub lands on main. Every public item is rustdoc-documented; anyhow is banned from public APIs; one thiserror error enum per crate with a stable code().
just ci runs exactly this, and .gitforge.yml mirrors it line-for-line:
cargo fmt --all -- --check
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace
cargo test -p opencodifier-model --features llamacpp,tokenizers # feature lane
cargo test --doc
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps
cargo deny check # licenses / advisories / bans / sources
cargo audit # known-vulnerability audit
aegis --format json scan --file . --baseline .aegis/baseline.json # 0 new findingsPlus the coverage lane: cargo llvm-cov --workspace --lcov with a floor assertion at 97.5 % (lcov DA basis, measured inside the pinned CI image — the number of record; only an in-image measurement may move the floor, D36). The 298-line residual above the floor is proven class-infeasible and recorded line-by-line in docs/COVERAGE.md.
Not part of just ci (run when the relevant boundary changes): just check-wasm (the wasm32 compile + Node smoke over the real artifact) and just check-macjev (renderer/prep byte parity).
GitForge is the CI platform of record (.gitforge.yml); the GitHub Actions config is a mirror, and a red GitHub run is not a code-failure signal. All jobs run on the runner-local opencodifier-ci-rust:2 image (toolchain, clippy/rustfmt, cargo-deny, cargo-audit, aegis at a pinned rev, llvm-cov, warm registry — zero runtime tool installs). The job graph fans out (lint → {test, doc, supply-chain} → e2e) and is safe only because the runner serializes a run's jobs; the file documents the collapse condition. The e2e lane builds the release binary and drives serve + MCP over the real wire.
OpenCodifier · local-first, deterministic-first decision runtime · Apache-2.0
Releases (current: v0.6.1) · Weights on HuggingFace (aliasfox org) · Live site + playground · Measured benchmark board · Benchmarks
OpenCodifier
Learn
Build
Participate
External