docs(fiqh): the fiqh basis document — every encoded ruling, sourced (#288) - #317
Merged
Conversation
… doc counts them, so the README cannot contradict it
…n, the §71.1 non-ruling named, plus minor precision
This was referenced Aug 17, 2026
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #288.
What & why
A Muslim developer deciding whether to trust keel with money asks a question the code cannot
answer by being read: WHAT fiqh does this machine enforce, and where did each ruling come
from? The answers exist — scattered across guard comments, a KB the size of a bookshelf, and
a handful of experiment records — auditable in principle, auditable by nobody who does not
already know where to look.
This PR adds
docs/fiqh-basis.md: the Shariah reasoning encoded in keel, stated ruling byruling, each with its in-repo source — the curation screen (sector §28.4, backing
§65.5/§67.2,
pays_yieldbare-holder semantics, wrapper §71.4a), rail 1 allowlistenforcement, rail 17
qabd§65.4 (Ayub quoted verbatim, tri-sourced §65.4 · §67.1 OIC53/4-6 · §71.5 AAOIFI SS 18 3/5, 7-day TTL, entries-only, fails closed), rails 18/19 as
charter, purification §65.9 and USDC-rewards §56.3 — plus what is attested versus computed,
what keel deliberately does not decide, the known open questions (ATOM dilution, staking
§65.14 contested, DOGE §86.4), and how to disagree. The remaining rails are marked
PRUDENTIAL-not-fiqh with §65.6's anti-scalping correction stated in the KB's own words.
The document claims no scholarly review; that is deliberately #289's still-open question.
README's documentation map and CONTRIBUTING's governance section each gain one link line.
Tests-first evidence
tests/test_fiqh_basis.pywritten first; the document did not exist.Red run (
uv run pytest tests/test_fiqh_basis.py -q):Every failure is the assertion it was written to be (the
_doc()helper returns empty for amissing file, so red is failures, not errors). After writing the document and the two link
lines:
13 passed.Pins are TWO-SIDED per the house pattern (
test_contributing.py): every verbatim quote isasserted in the document AND in the file it quotes (
guards.py,screen.py, KB sources,experiment records) — the §65.4
qabdcondition is pinned THREE-sided (doc + rail 17 + §65.4)— so the document cannot drift from the code it explains. One extra source-normalisation was
needed: the riba failure message is two adjacent Python string literals, so the helper joins
implicit string concatenation before matching.
Gates (all must pass)
uv run ruff checkclean — All checks passed!uv run mypyclean — Success: no issues found in 233 source filesuv run pytest -qgreen — 2820 passed, 1 skipped in 34.75sScope check
tests only: no classification, no mechanism, no rail semantics change. One pre-existing
inconsistency noticed and deliberately NOT fixed here (separate concern): README says
"nineteen deterministic checks" / "the 19 rails" while
guards.py's docstring and thisdocument say eighteen (there is no rail 15).