Skip to content

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.

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.

The same crate compiles to wasm32-unknown-unknowndeducible.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)

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.

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 }
Terminal window
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).

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)