Skip to content

Diagnostics reference

When a spec violates a rule, the engine raises a coded diagnostic with a message, a citation, and a precise span. An error blocks codegen, so no contract is emitted (exit 1). A warning is advisory and does not block. Citations are flagged for scholarly verification ([scholar-verify] for fiqh, [verify] for common law), never asserted as fatwa.

Every diagnostic is the same structure, emitted as JSON under --json or pretty-printed otherwise:

{
"severity": "error",
"code": "RIBA-1",
"message": "capital is guaranteed; a guaranteed return of capital turns a partnership into an interest-bearing loan (riba).",
"citation": "al-Baqarah 2:275; AAOIFI Shari'ah Standard No. 12 [scholar-verify]",
"span": { "line": 38, "col": 5 }
}

span points at the offending token, so the LSP underlines exactly that, the capital_guarantee line and not the whole block. Codes are stable identifiers; the prose message may evolve.

example: a disguised loan, refused
$ deduce check specs/riba_disguised.fiqh
✗ RIBA-1 38:5 capital is guaranteed to 'bank' (riba). al-Baqarah 2:275 · AAOIFI SS No. 12
✗ RISK-1 37:5 loss must follow ownership. al-ghunm bi-l-ghurm
✗ GHARAR-1 31:7 buyout price is not oracle-derived (majhūl).
3 errors · no contract emitted
$ echo $?
1

There are roughly 109 codes. The tables below group them by the part of the law they enforce.

Code Principle
RIBA-1 capital is guaranteed; a guaranteed return of capital turns a partnership into a loan.
RIBA-2 a return is charged on principal/capital rather than a living share or usufruct.
RIBA-3 a late-payment penalty accrues to the seller/lessor (interest on a debt).
RISK-1 loss is not shared proportional to ownership/capital.
RISK-2 in mudarabah, financial loss is not borne by the rabb al-māl alone.
RISK-3 in ijarah, the lessor (owner) does not bear the asset’s risk.
GHARAR-1 a buyout/sale price is not independently oracle-derived (majhūl).
GHARAR-2 realized profit is self-reported, not oracle-attested.

Structure: parties, capital, roles, invariants

Section titled “Structure: parties, capital, roles, invariants”
Code Principle
INV-1 a required invariant for this instrument class is not declared.
CAP-1 / CAP-2 capital does not sum to 10000 bps / fewer than two contributors.
ROLE-1 / ROLE-2 no independent valuation oracle / the oracle party is not marked independent.
PARTY-1 a required commercial role is missing.
RENT-1 / RENT-2 a rent block lacks a basis / a required rent mechanism is missing.
BUYOUT-1 / BUYOUT-2 a buyout lacks a price / the diminishing-buyout mechanism is missing.
Code Principle
MUR-1 / MUR-2 murabaha needs the disclosed-cost sale block / an acquireAsset (qabḍ) step before selling.
SALAM-1 / SALAM-2 / SALAM-3 salam needs the full salam block / a known quantity (maʿlūm) / a known delivery date (ajal maʿlūm).
ISTISNA-1 / ISTISNA-2 / ISTISNA-3 / ISTISNA-4 istisnaʿ needs the istisna block / the maker supplies materials / a known price / (warning) a known delivery date.
SARF-1 / SARF-2 / SARF-3 ṣarf needs the exchange block settled spot / same-genus must be equal (ribā al-faḍl) / positive amounts.
TAWARRUQ-1 / TAWARRUQ-2 / TAWARRUQ-3 the onward buyer is not the seller (ʿīnah) / a takePossession step / not financier-arranged (munaẓẓam).
Code Principle
MUD-1 / MUD-2 / MUD-3 / MUD-4 the muḍārib contributes no capital / a rabb_al_mal role / a mudarib role / the rabb funds 100%.
PROFIT-1 / PROFIT-2 profit split by a pre-agreed ratio / a profit mechanism is present.
Code Principle
IJARAH-1 (warning) the rent basis is not usufruct.
IJARAH-2 lease-to-own needs a distinct transferOwnership step (no two contracts in one).
JUALA-1 / JUALA-2 juʿāla needs a reward block / the reward is due on completion.
ARIYAH-1 / ARIYAH-2 ʿāriyya needs a loan_use block / the same asset is returned.
WAKALA-1 / WAKALA-2 wakala needs the agency block (with no agent guarantee) / a definite fee (ujra).
MUZARA-1 / MUZARA-2 muzāraʿa needs a harvest_share block / no fixed rent on the land (the owner shares the crop’s fate).
Code Principle
QARD-1 / QARD-2 qarḍ ḥasan needs the loan block / no fee tied to the loan.
RAHN-1 / RAHN-2 / RAHN-3 rahn needs the pledge block with no creditor benefit / surplus returns to the pledgor / positive debt and value.
KAFALA-1 / KAFALA-2 kafala needs the guarantee block with no fee / recourse is exactly what was paid.
HAWALA-1 / HAWALA-2 hawala needs the transfer block / it discharges the original debtor.
WADIA-1 / WADIA-2 wadiʿa needs the deposit block / the custodian must not use the deposit.
Code Principle
SUKUK-1 / SUKUK-2 ṣukūk needs an income block / income distributed pro-rata to holders.
TAKAFUL-1 / TAKAFUL-2 takaful needs a contribution block / surplus belongs to participants, not the operator.
POOL-1 / POOL-2 pool shares total exactly 10000 bps / at least two participants.
Code Principle
WAQF-1 / WAQF-2 waqf needs the endowment block / only the income is distributed (corpus preserved).
HIBAH-1 / HIBAH-2 hibah needs the gift block / no consideration (else it is a sale).
WASIYYA-1 / WASIYYA-2 wasiyya needs the bequest block (≤ ⅓) / the beneficiary is a non-heir.
Code Principle
ZAKAT-1 the rate must match the genus (e.g. 250 bps for trade goods, 1000 for rain-fed crops).
ZAKAT-2 produce zakat is due at harvest; wealth zakat at a lunar ḥawl.
ZAKAT-3 a positive niṣāb must be declared.
ZAKAT-4 the beneficiary must resolve to a declared party or role.
ZAKAT-5 the zakat genus is unknown to the engine.
ZAKAT-6 the eight-aṣnāf policy is missing a category of al-Tawba 9:60.

See Charge for the multi-genus rate table and the aṣnāf split.

Code Principle
ORACLE-1..5 the consensus-oracle config is malformed (unknown mode, quorum/committee bounds, or gharar_bound_bps out of range).
CONT-1 a calamity (jāʾiḥah) may only reschedule or abate, never add a penalty or interest.
CONT-2 / CONT-3 death is distributed by farāʾiḍ, not discretion / a farāʾiḍ dissolution needs an arbiter.
CONT-4 (warning) a contingency block declares no recognized off-ramp.
INAH-1 / INAH-2 / INAH-3 bayʿ al-ʿīnah (a 2-cycle back to origin) / organised tawarruq (a ≥3-cycle ring, or a deferred-in + spot-out monetization flip) / (warning) a zero-net round-trip.
BUNDLE-1, LEG-1..4 a bundle declares no legs / a leg is missing fields, has a bad payment, references an undeclared party, or transfers an asset to itself.
BUNDLE-2 a bundle has no (or a blank) completeness_attestation — the graph search cannot prove a ring absent from legs it was never shown, so a cycle-free verdict requires an attributed claim that the legs are complete.
Code Doctrine
CONSID-1 consideration must move between distinct parties (Currie v Misa, 1875).
CERTAINTY-1 / CERTAINTY-2 the amount / the condition must be definite (Scammell v Ouston, 1941).
PENALTY-1 damages must be liquidated, not a penalty in terrorem (Cavendish v Makdessi, 2015).
TERMS-1 a commercial escrow needs a release block.
DISPUTE-1 a dispute-resolution remedy (arbiter_ruling) is required.
Code Meaning
MAQASID-1 / MAQASID-2 (warning, never blocking) a form-compliant contract whose maqṣad a scholar should examine. See Maqāṣid & the ḥiyal ceiling.
MAQASID-3 (warning, never blocking) a bundle leg takes on a deferred debt for an asset with no disposal of it declared anywhere in the bundle — the signature a hidden ring’s remainder would leave, and equally an ordinary end-consumer keeping what they bought.
META-1 (warning) no fiqh basis is cited in meta.
CLASS-1 the instrument class is unknown to the engine.
REGIME-1 the declared regime contradicts the class.
RULES-1 the active pluggable module has no entry for this class.
RULES-2 a rule module claims ratification.status: "ratified" but its content hash is missing or no longer matches — it was edited after sign-off, or never had anything to pin against.
RULES-3 (warning) a rule module has no ratification block, or isn’t yet "ratified" — treat its verdicts as draft. See Rule modules.
PARSE a lexical or syntactic error (surfaced through the LSP and FFI).