# Nisaba — Systems Deep Dive

> The `libs/nisaba/` area: ~23 Nx libraries implementing a full
> digital-philology platform — ancient-script processing, canonical reference
> systems, textual criticism, paleography, translation comparison, and the
> scholar-facing workspace/client/mobile surfaces — for the Nisaba scholarly
> research domain.

## What this area is

Nisaba (named for the Sumerian goddess of writing) is the monorepo's
**ancient-text scholarship** domain, and `libs/nisaba/` is where almost all of
its real work lives. It is not one package but ~23 separate Nx libraries that
together cover the full lifecycle of computational philology: ingesting ancient
corpora, normalising and analysing dozens of historical scripts, resolving
canonical references across religious and classical traditions, collating
manuscript witnesses and reconstructing archetypes, dating and attributing
hands, comparing translations, and presenting all of it to scholars through a
reading workspace, a typed API client, and a mobile surface. The code is
substantial and genuinely domain-specific — on the order of half a million lines
across the area, dominated by `@nisaba/languages` (~258K lines across 29 script
families) and `@nisaba/criticism` (~51K lines of stemmatic algorithms).

The libraries form a clear dependency layering, visible in each `project.json`'s
`tags` and `implicitDependencies`. At the bottom sits `@nisaba/core`
(`layer:contracts`/`layer:domain`, zero dependencies) with shared types,
constants, and utilities; `@nisaba/schemas` (`layer:contracts`) adds Zod runtime
validation over those types; and `@nisaba/database` (`layer:data`) provides the
Prisma persistence layer. Above that sit the **analysis engines** —
`@nisaba/languages`, `@nisaba/canon`, `@nisaba/corpora`, `@nisaba/criticism`,
`@nisaba/paleography`, `@nisaba/philology`, `@nisaba/translations`,
`@nisaba/comparative`, `@nisaba/annotations`, `@nisaba/editions`,
`@nisaba/geotemporal`, and `@nisaba/standards` — each depending on the
foundation and on one another in domain-meaningful ways (e.g. `corpora` depends
on `languages` + `canon`; `editions` depends on `criticism` + `annotations` +
`standards`). The engines are almost entirely **pure TypeScript with zero
external dependencies** (the module headers say so explicitly), which keeps the
scholarly algorithms portable and deterministic.

At the top are the **experience and integration** libraries: `@nisaba/assistant`
(AI-assisted translation/commentary over an injected completion provider),
`@nisaba/study-plans`, `@nisaba/workspace` (which composes most of the engines
into a research environment), `@nisaba/mobile`, `@nisaba/client` and
`nisaba-api-client` (typed HTTP clients), and `@nisaba/cross-domain` (bridges
Nisaba into sibling Oshun domains such as Tara, Arete, Veritas, and Nyx).
`@nisaba/languages-wasm` is a Rust/WASM sibling crate providing
performance-sensitive Unicode/offset primitives. No library in the area is an
empty scaffold — every one read here carries real, implemented domain logic.

## How it fits the wider system

The persistence and contract layers (`@nisaba/database`, `@nisaba/schemas`,
`@nisaba/core`) define what a manuscript, variant unit, critical edition,
canonical reference, or annotation _is_ — the Prisma schema has 16 domain models
and `@nisaba/schemas` mirrors them as Zod schemas (including a W3C Web
Annotation Data Model surface). The analysis engines are consumed by the
scholar-facing `@nisaba/workspace` and surfaced over HTTP: `nisaba-api-client`
is a **generated** typed client built from the domain's OpenAPI spec (so the BFF
and web shells call Nisaba endpoints type-safely), while `@nisaba/client` is a
hand-written zero-dependency fetch client with React hooks. `@nisaba/mobile`
shapes the same content for a compact reading flow. `@nisaba/cross-domain` is
the outward edge: it turns Nisaba passages, study plans, and concept-graph
signals into recommendation links pointing at other Oshun domains. Walk the
"used by" edges on any node below to see exactly who depends on it.

## Entity reference

### @nisaba/core

The foundation layer (`libs/nisaba/core/src`), tagged both `layer:contracts` and
`layer:domain` with **zero dependencies**. It exports the shared domain types
(`types/manuscript.ts`, `apparatus.ts`, `morphology.ts`, `lexicon.ts`,
`writing-systems.ts`, `traditions.ts`, `transliteration.ts`, `annotations.ts`,
`comparative.ts`, `reference.ts`), the constant tables (`unicode-ranges.ts`,
`script-metadata.ts`, `tradition-metadata.ts`), typed `errors.ts`, and utilities
for citations, character/byte offsets, references, dates, Unicode, and
confidence scoring. Every other Nisaba library builds on these primitives.

### @nisaba/schemas

The runtime-validation layer (`libs/nisaba/schemas/src`, `layer:contracts`,
depends on `@nisaba/core`). It defines Zod schemas — not just TypeScript types —
for manuscripts, variants/collation, critical apparatus, canonical references,
cross-tradition comparison, corpus/paleography, and geotemporal data, plus an
annotation module the barrel describes as "W3C WADM compatible". These schemas
let payloads crossing Nisaba's boundaries be validated at run time, and the
inferred types are re-used across the engines.

### @nisaba/database

The persistence layer (`libs/nisaba/database`, `layer:data`, depends on
`@nisaba/core` + `@nisaba/schemas`). It wraps a Prisma schema
(`prisma/schema.prisma`) with **16 domain models** — `Manuscript`,
`CollationProject`, `VariantUnit`, `CriticalEdition`, `Annotation`,
`AnnotationLayer`, `ConceptMapping`, `MotifAttestation`, `InfluenceEdge`,
`CanonicalReference`, `Passage`, `PaleographicAnalysis`, `ScribalHand`,
`ResearchProject`, `PersonalLibraryItem`, and `Bookmark` — an initial migration
(`prisma/migrations/20260528000000_nisaba_initial`), and a seed script.
`src/index.ts` exposes
`getNisabaClient`/`createNisabaClient`/`disconnectNisabaClient` plus type
aliases (e.g. `ManuscriptMaterial`, `VariantClassification`) that are usable
before `prisma generate` runs. Nx targets exist for `prisma:generate`,
`migrate`, `studio`, and `db:seed`.

### @nisaba/languages

By far the largest library in the area (`libs/nisaba/languages/src`, ~258K lines
across 624 files, depends on `@nisaba/core` + `@nisaba/schemas`). It implements
**29 historical script/language modules** — ancient Greek (polytonic accents,
Beta Code, Ionic/Attic numerals, full morphological parsers and a conjugator),
Hebrew, Aramaic, Syriac, Arabic, Ethiopic, Phoenician/Paleo-Hebrew/Moabite,
Samaritan, Ugaritic, Sumerian cuneiform, Egyptian hieroglyphic/hieratic/demotic,
Coptic, Devanagari/Sanskrit, Pali (multi-script), Prakrit, Tibetan, Tamil
Brahmi, Grantha, Kharoshthi, Classical Chinese, Latin, Avestan, Old Persian, Old
Church Slavonic, Runic, and Linear B. Each exposes a `ScriptHandler`, character
classification, and transliteration; the library also includes a shared
transliteration engine and a unified `LexiconService` for multi-lexicon lookup.

### @nisaba/languages-wasm

The Rust/WASM sibling crate (`libs/nisaba/languages/rust`, `type:wasm`).
`lib.rs` exposes `wasm-bindgen` functions for performance-sensitive primitives:
`normalize_nfc`/`normalize_nfd` (Unicode normalization), `detect_script`
(returning ISO 15924 codes via `detection.rs`), and `byte_to_char_offset` /
`char_to_byte_offset` (UTF-8 offset conversion in `offsets.rs`, used for
standoff annotations). It builds via `cargo build` + `wasm-pack` and tests via
`cargo test` — this is real Rust, the chosen language for the hot Unicode/offset
path that backs the TypeScript `@nisaba/languages` engine.

### @nisaba/canon

Canonical reference management (`libs/nisaba/canon/src`, ~43K lines across 17
modules, depends on `@nisaba/core` + `@nisaba/schemas`). It encodes the
structure of major textual canons — Protestant, Catholic, Orthodox
(Greek/Ethiopian), Hebrew Tanakh, Septuagint, Quran (with `qiraat` variants and
Juz/Hizb divisions), the Pali Tipitaka, the Chinese Buddhist Taishō, the Tibetan
Kangyur/Tengyur, Hindu scriptures, Jewish texts
(Talmud/Mishnah/Tosefta/Midrash/Zohar), and Greek and Latin classical works
(Stephanus/Bekker/Diels-Kranz references). On top it provides a
`VersificationMapping` engine (LXX↔MT psalm offsets, divergent-book detection),
a canonical-URI scheme, CTS/CITE URN parsing, and a cross-tradition
reference-mapping service. Each canon ships parsing, formatting, validation,
navigation, and stats helpers.

### @nisaba/corpora

Corpus ingestion and parsing (`libs/nisaba/corpora/src`, ~20K lines, depends on
`@nisaba/core` + `@nisaba/schemas` + `@nisaba/database` + `@nisaba/languages` +
`@nisaba/canon`). The barrel namespaces an `atf-parser` (ASCII Transliteration
Format used by CDLI/ORACC/ETCSL for cuneiform, with sign names, determinatives,
damage notation, and dollar lines), a `tei-xml-parser`, scripture-format parsers
(OSIS/USFM/USX), and classical/religious/specialized corpus connectors, plus an
`ingestion-pipeline`. It is the on-ramp that turns external scholarly source
formats into Nisaba's internal model.

### @nisaba/criticism

The textual-criticism engine (`libs/nisaba/criticism/src`, ~51K lines across 25
modules, depends on `@nisaba/core` + `@nisaba/schemas` + `@nisaba/languages` +
`@nisaba/canon`) — the analytical heart of the area. It implements a witness
registry/classification/hierarchy, a collation engine (tokenization, alignment,
variant graphs, apparatus generation), fuzzy orthographic matching with
language-specific rules (Greek itacism, Hebrew matres lectionis, Akkadian
gemination), transposition and block alignment, scribal-error taxonomy
(haplography, dittography, homoioteleuton, metathesis), and full phylogenetic
stemmatics: Fitch parsimony, neighbor-joining, UPGMA, bootstrap support,
NeighborNet split networks, contamination detection, CBGM (Coherence-Based
Genealogical Method), and Lachmannian archetype reconstruction. It also covers
Leiden epigraphic conventions, lacuna registries, reconstruction proposals, IIIF
manifest linking, and apparatus typography with LaTeX/TEI/SVG export.

### @nisaba/paleography

Paleographic analysis (`libs/nisaba/paleography/src`, ~30K lines across 11
modules, depends on `@nisaba/core` + `@nisaba/schemas` + `@nisaba/languages`).
It runs script/period/regional classification over manuscript images using real
image-processing primitives — Otsu thresholding, histogram/contrast
normalization, stroke/layout/texture/direction feature extraction, PCA/ICA for
multispectral palimpsest separation — plus letterform analysis, writer
identification, hand-change detection, scribal-habit profiling,
damaged-character reading, and **multi-factor Bayesian dating** that combines
paleographic, orthographic, material, codicological, historical, and radiocarbon
evidence (including IntCal20 calibration) into a posterior date distribution.

### @nisaba/philology

Computational philology (`libs/nisaba/philology/src`, ~31K lines across 12
modules, depends on `@nisaba/core` + `@nisaba/languages` + `@nisaba/corpora`).
It provides cognate-chain tracing with phonological rules, semantic-drift
analysis, loanword detection, semantic-domain mapping (Louw-Nida framework),
collocational/metaphor analysis, hapax-legomena detection, word-frequency
analysis (Zipf deviation, log-likelihood and chi-squared keyness, dispersion),
stylometric authorship attribution (Burrows's Delta, function-word feature
vectors, cross-validation), register analysis, chiastic/ring-composition and
inclusio detection, and intertextuality (quotation/allusion/echo) detection with
influence scoring.

### @nisaba/translations

The translation-comparison engine (`libs/nisaba/translations/src`, ~12K lines
across 23 files, depends on `@nisaba/core` + `@nisaba/schemas` +
`@nisaba/languages` + `@nisaba/canon`). It implements alignment algorithms —
Gale-Church length-based sentence alignment, IBM Model 1 word alignment (with
language-pair concordance seeds), embedding/neural alignment with cosine
similarity, and manual alignment sessions — and divergence detection (semantic,
theological-rendering, omission/addition, equivalence scoring, translation
history). On top, it builds anchor-indexed display view models: side-by-side,
synoptic, interlinear, reverse-interlinear, and synchronized scroll state.

### @nisaba/comparative

Cross-tradition comparison (`libs/nisaba/comparative/src`, ~12K lines, depends
on `@nisaba/core` + `@nisaba/schemas` + `@nisaba/canon` + `@nisaba/philology`).
It namespaces four modules: `concept-equivalence`, `parallel-passage-detection`
(semantic, Thompson Motif-Index-compatible, and structural matching with
cultural context weighting and quality classification — VERBATIM/CLOSE/THEMATIC/
STRUCTURAL/TYPOLOGICAL), `motif-theme-tracking`, and `influence-network`. It is
how Nisaba relates passages and motifs across religious and literary traditions.

### @nisaba/annotations

Standoff annotation infrastructure (`libs/nisaba/annotations/src`, ~7.7K lines,
depends on `@nisaba/core` + `@nisaba/schemas` + `@nisaba/database`).
`standoff-annotations.ts` implements the **W3C Web Annotation Data Model**
(TextPositionSelector, TextQuoteSelector, FragmentSelector) with an immutable
multi-indexed store and overlapping layers, a seven-type scholarly annotation
type system (textual, linguistic, translation, critical, comparative,
structural, pedagogical), and a Talmudic-style layered-commentary model spanning
Jewish, Christian, Islamic, Buddhist, and Hindu traditions. It also covers
collaborative annotations and annotation exports.

### @nisaba/editions

Critical-edition management (`libs/nisaba/editions/src`, ~5.8K lines, depends on
`@nisaba/core` + `@nisaba/schemas` + `@nisaba/criticism` + `@nisaba/annotations`

- `@nisaba/standards`). `edition-management.ts` covers the edition-project
  lifecycle (base-text config, witnesses, milestones, tasks, semantic
  versioning), apparatus composition (variant readings, source references,
  Quellenapparat), and collaborative editing with role-based access control,
  version history/diffing, and review gates. `edition-exports.ts` renders
  editions to TEI-XML, LaTeX, and HTML.

### @nisaba/geotemporal

Geographic and temporal modelling (`libs/nisaba/geotemporal/src`, ~7.6K lines,
depends on `@nisaba/core` + `@nisaba/schemas` + `@nisaba/database` +
`@nisaba/canon`). `provenance-diffusion.ts` tracks manuscript provenance chains
(ownership/custodial history with gap detection), a registry of scriptoria
(WGS-84 coordinates, active periods, writing traditions), historical
transmission routes, and tradition-diffusion maps with contact-zone detection
and diffusion-speed calculation. `geographic-timeline.ts` adds the timeline view
over that data.

### @nisaba/standards

Text-encoding standards (`libs/nisaba/standards/src`, ~8.4K lines, depends on
`@nisaba/core` + `@nisaba/schemas` + `@nisaba/canon` + `@nisaba/corpora`).
`text-encoding-standards.ts` implements TEI-XML (P5) import/export, the EpiDoc
TEI variant for epigraphy, and the Bible-text formats OSIS, USFM, USX, and
SWORD; `reference-linked-data.ts` covers linked-data reference encoding. It is
the interchange layer that lets Nisaba round-trip with the broader
digital-humanities ecosystem.

### @nisaba/assistant

AI-assisted scholarship (`libs/nisaba/assistant/src`, ~8.1K lines, depends on
core/schemas plus the analysis engines: languages, translations, criticism,
corpora, philology, comparative). `translation-commentary.ts` builds rigorous
prompts for morphological parsing, translation drafting, disambiguation, and
grounded commentary across many ancient languages, then calls an **injected
completion provider** (a fail-loud seam, not a hardcoded model), validates the
structured response, integrates Sophia-style grounding sources, and flags
AI-generated output for scholarly review. `variant-evaluation-research.ts`
applies the same pattern to textual-variant evaluation.

### @nisaba/study-plans

Study-plan modelling (`libs/nisaba/study-plans/src`, ~1.1K lines, no implicit
Nisaba dependencies). Beyond a rich type vocabulary (objectives, resources,
cadences, difficulty, forecast states) it exports four real functions:
`createNisabaStudyPlan`, `sequenceNisabaStudyResources` (orders resources by
prerequisite/sequence hints), `initializeNisabaLearnerTracking`, and
`recordNisabaLearnerProgress`. It is intentionally dependency-light so that
`@nisaba/cross-domain` and the experience layers can consume study plans without
pulling in the engines.

### @nisaba/workspace

The scholar research environment (`libs/nisaba/workspace/src`, ~12K lines,
`layer:domain`, depends on core/schemas plus corpora, annotations, editions,
geotemporal, and assistant — the broadest engine fan-in in the area).
`research-environment.ts` provides research-project management (shared
resources, team roles, milestones, task dependencies, templates), a configurable
split-pane reading environment (text/translation/apparatus/commentary/lexicon/
image panes with morphological popups, synced scrolling, vim keybindings), and
unified cross-corpora search (lemma/morphology/semantic-aware, Boolean +
proximity + script-aware regex, ranking and pagination). It also includes
personal-library export and a scholar-mode profile.

### @nisaba/mobile

The mobile reading surface (`libs/nisaba/mobile/src`, ~590 lines, no implicit
Nisaba dependencies). `mobile-study.ts` declares twelve required mobile features
and their routes and builds the mobile study state: a sorted reading queue, a
deterministic daily passage, compact highlight/annotation drafts, quick-compare
cards, glossary/morphology lookup (NFKD-normalised), scheduled study reminders,
and assistant explanations that track inspectable citations, unsupported claims,
and a `requiresReview` flag. It is a self-contained presentation/state library
rather than an engine.

### @nisaba/client

The hand-written API client (`libs/nisaba/client/src`, ~7.5K lines,
`layer:client`, depends on `@nisaba/core` + `@nisaba/schemas` +
`@nisaba/workspace`). `api-client.ts` is a zero-dependency, `fetch`-based typed
client for all Nisaba domain operations with an exhaustive `NisabaErrorCode`
enum (BAD_REQUEST through SERVICE_UNAVAILABLE/ABORTED) and AbortSignal support;
`react-hooks.ts` exposes React bindings. The barrel namespaces both as
`apiClient` and `reactHooks`.

### nisaba-api-client

The generated typed client (`libs/nisaba/api-client/src`, the one entity whose
Nx project name is unprefixed). `client.ts` and `generated/openapi.ts` are
**code-generated** from the domain's OpenAPI spec by
`libs/openapi/scripts/generate-oshun-v1-api-clients.ts` (the file header says
so), re-exporting `components`/`operations`/`paths`/`webhooks` types and typed
model aliases (`Passage`, `Manuscript`, `Edition`, `Translation`,
`LexiconEntry`, `MorphologyEntry`, `Annotation`, `ConceptGraphNode`, …). It is
the spec-canonical client that keeps callers in sync with the published Nisaba
API, complementing the hand-written `@nisaba/client`.

### @nisaba/cross-domain

The outward integration edge (`libs/nisaba/cross-domain/src`, ~413 lines,
depends only on `@nisaba/study-plans`). `nisaba-cross-domain.ts` implements
`buildNisabaCrossDomainBridge`, which turns Nisaba passages, Tara practice
sessions, study plans, Veritas source-depth requests, Nyx cosmology overlays,
and concept-graph signals into prioritised, provenance-stamped recommendation
links across six declared capabilities (tara-passage-companions,
arete-study-plans, veritas-source-depth, nyx-cosmology-overlays,
shared-concept-graph, domain-to-domain-recommendations), and reports coverage
against the required set. It is deliberately thin and dependency-light because
it is the seam other Oshun domains consume.
