Integration & APIs
The same invariant engine is reachable from four surfaces beyond the CLI, so it can sit inside a core-banking stack, a browser, an editor, or a SupTech service.
C-ABI FFI (fiqhc-ffi)
Section titled “C-ABI FFI (fiqhc-ffi)”crates/fiqhc-ffi builds a cdylib exposing a minimal, stable C ABI. UTF-8 .fiqh in,
NUL-terminated JSON diagnostics out.
/* allocate a buffer the caller fills with UTF-8 .fiqh source */char* fiqh_alloc(size_t len);void fiqh_free(char* ptr, size_t len);
/* check source; returns a malloc'd C string of JSON diagnostics (caller frees) */char* fiqh_check_json(const char* src, size_t len);void fiqh_free_cstr(char* ptr);Returned JSON is an array of { code, severity, message, citation, line, col }. Build target
libfiqhc_ffi.so (~620 KB) links from Java (JNI/JNA), .NET (P/Invoke), Python (ctypes/cffi), Go
(cgo), or C. Memory rule: every pointer the library returns is freed with the matching
fiqh_free* — never free() directly.
WebAssembly
Section titled “WebAssembly”The same crate compiles to wasm32-unknown-unknown → deducible.wasm (~180 KB) for in-browser
validation with no server round-trip. The native-only paths (nl.rs’s Command, lsp.rs’s stdin)
are std stubs on wasm and unused there. Marshalling mirrors the C ABI: call fiqh_alloc, write the
source into linear memory, call fiqh_check_json, read the NUL-terminated result, fiqh_free_cstr.
const { instance } = await WebAssembly.instantiate(bytes, imports);const { memory, fiqh_alloc, fiqh_check_json, fiqh_free_cstr } = instance.exports;// write src bytes at fiqh_alloc(len), then:const out = fiqh_check_json(ptr, len); // → ptr to JSON; read until NUL; then fiqh_free_cstr(out)Language Server (deducible lsp)
Section titled “Language Server (deducible lsp)”A stdio JSON-RPC server (std + serde_json only — no async runtime, no tower-lsp). Lifecycle and
document methods:
| Method | Behaviour |
|---|---|
initialize / initialized |
capability handshake |
textDocument/didOpen · didChange · didSave |
re-check, then push diagnostics |
textDocument/publishDiagnostics |
server→client; precise ranges, code set, daleel in message |
shutdown / exit |
teardown |
Severity maps error → 1, warning → 2; ranges are LSP 0-based line/col with end at end-of-line
where a token span isn’t available. A VS Code extension (editors/vscode) spawns deducible lsp via
vscode-languageclient and ships a TextMate grammar for .fiqh.
Invariant gateway
Section titled “Invariant gateway”A small Node http service (binds 127.0.0.1:8799) that serves the
manifests and answers enforcement queries — useful as
SupTech: it checks consistency and issues no fatwa.
| Route | Purpose |
|---|---|
GET / |
dashboard |
GET /manifests |
list loaded manifests |
GET /dids |
sample DID registry (capacity middleware) |
POST /enforce |
{ target, terms } → allow/deny + cited violations (ops eq/ne/gt) |
POST /authorize |
{ target, terms, parties } → checks terms and every party’s ahliyyah |
POST /compile |
{ spec } → shells deducible check, returns { consistent, diagnostics } |
curl -s localhost:8799/enforce -H 'content-type: application/json' \ -d '{"target":"musharakah_mutanaqisah","terms":{"loss_share":"by_ownership","capital_guarantee":false}}'# → { "allow": true }# a disguised loan → { "allow": false, "violations": [ { "code":"RIBA-1", "citation":"al-Baqarah 2:275" }, ... ] }terms are flat dotted keys (e.g. zakat.rate_bps). The gateway never mutates state; it is a pure
decision endpoint over the manifest + the DID/ahliyyah resolver
(see Capacity).
Exit codes (CLI)
Section titled “Exit codes (CLI)”deducible check/build exit non-zero when a spec is inconsistent, so they drop into CI gates directly:
| Code | Meaning |
|---|---|
0 |
consistent (and, for build, artifacts emitted) |
1 |
inconsistent — one or more error diagnostics (printed to stderr as JSON or pretty) |
2 |
usage / I/O error (bad path, unreadable rule module) |