Architecture
Package structure
Section titled “Package structure”packages/├── core/ @faraid/core — pure math engine├── domain/ @faraid/domain — types, schemas, presets├── extensions/ @faraid/extensions — 12 extension instances├── api/ @faraid/api — user wrappers + BaseSolver├── server/ @faraid/server — Hono HTTP server├── client/ @faraid/client — generated RPC client├── web/ @faraid/web — web application (Astro + Svelte 5)├── design/ @faraid/design — shared CSS tokens└── docs/ @faraid/docs — this documentation site (Astro Starlight)Dependency boundaries
Section titled “Dependency boundaries”Enforced by eslint-plugin-boundaries (.eslintrc.json):
core ← domain ← extensions ← api ← server web (imports domain only)No package may import from a package to its right. This keeps the math engine completely decoupled from HTTP, UI, and schema layers.
@faraid/core — pure engine
Section titled “@faraid/core — pure engine”The math engine. Implements the 4-axiom system from findings/02:
- Phase 0 — attribute exclusion (non-Muslim, slave, killer)
- Phase 1 — ghost-pressure flags (hasDescendant, hasFather, etc.)
- Phase 2 — person exclusion (α₁ intermediary + α₂ quwwa tiebreak)
- Phase 3 — share assignment (β — farḍ and ʿaṣaba)
- Phase 4 — normalization (γ — ʿAwl / Radd / ʿAṣaba absorption)
- Phase 5 — taṣḥīḥ (integer conversion)
Key invariant: no strings, no HTTP, no UI. Pure TypeScript math with exact BigInt arithmetic.
The alpha2.ts helper provides the shared minQ computation used by both Phase 2 and Phase 4.
@faraid/domain — single source of truth
Section titled “@faraid/domain — single source of truth”All types, Zod schemas, and madhhab presets live here. No other package defines HeirType or validates request bodies — they import from domain.
Key exports:
HeirTypeSchema— 27 heir types as a Zod enumMadhhabConfigSchema— 9 fields including D16/D17/D18 togglesSHAFII,HANAFI,HANBALI,MALIKI— preset configsScenarioFlagSchema,PHENOMENA— scenario generation types- All input and output Zod schemas (request validation + response docs)
@faraid/extensions — unified extension primitive
Section titled “@faraid/extensions — unified extension primitive”All six extension families reduce to one primitive: scenarioExtension(F, S, w, A) where:
- F — the core
computeSharesfunction - S — scenario set (e.g. 2ⁿ alive/dead masks for Mafqūd, 6 gender×count for Ḥaml)
- w — weight function (uniform, estate-ratio, etc.)
- A — aggregation rule (componentMin, componentMean, singlePick, asymmetricMinMax, weightedSum, caseSplit)
The 12 instances correspond exactly to findings/16 §4:
| Instance | Method | Aggregation |
|---|---|---|
| Munāsakhat | Chain of deaths | weightedSum (path products) |
| Gharqā Jumhūr | Independent estates | No merge |
| Gharqā Ḥanbalī | Chain Forest (TILD/ṬARIF) | weightedSum |
| Mafqūd | 2ⁿ alive/dead | componentMin |
| Ḥaml Jumhūr | 6 scenarios | asymmetricMinMax |
| Ḥaml Ḥanafī | 2 scenarios | asymmetricMinMax |
| Khunthā Shāfiʿī | {m, f} | componentMin |
| Khunthā Mālikī | {m, f} | componentMean |
| Khunthā Ḥanafī | {m, f} | singlePick(argmin) |
| Khunthā Ḥanbalī | {m, f} | caseSplit |
| DhA Tanzīl | Projection tree | sub-distribution products |
| DhA Qarāba | Priority cascade | priority-weighted split |
@faraid/api — user layer + BaseSolver
Section titled “@faraid/api — user layer + BaseSolver”The API layer translates between string HeirType values and the engine’s 5-tuple vectors.
BaseSolver class hierarchy:
abstract class BaseSolver<TInput, TOutput> { abstract preProcess(input: TInput): PreparedInput; abstract runCore(prep: PreparedInput): PipelineResult; protected postProcess(result, warnings): TOutput; // = _annotatePipelineResult solve(input: TInput): TOutput;}
class FlatSolver extends BaseSolver<HeirInput[], SolverResult>class ChainSolver extends BaseSolver<ChainSolverInput, ChainSolverResult>class MafqudSolver extends BaseSolver<MafqudSolverInput, MafqudSolverResult>class DhaSolver extends BaseSolver<DhaSolverInput, SolverResult>The public functions (solve, solveChain, solveMafqud, solveDha) are thin wrappers: new FlatSolver(config).solve(input).
@faraid/server — HTTP layer
Section titled “@faraid/server — HTTP layer”Hono server targeting Cloudflare Workers. All request validation uses Zod schemas from @faraid/domain. No schema is defined in the server itself.
Build system
Section titled “Build system”- Turborepo — task orchestration, dependency-aware builds
- tsc -b — composite TypeScript builds with project references
- pnpm workspaces — package management
- Vitest — testing (809 total tests across all packages)