Skip to content

Architecture

Architecture Overview

2 min readUpdated Verified against a661527 on 2026-09-26

Page actions

ChatGPT and Claude are third-party services. The link gives them this page's public address and a short instruction. This site records nothing.

The system in one page: who uses it, the containers across three repositories, production deployment and the five data layers.

The whole system on one poster — press Next on the site to build it up step by step:

System landscape The people (sangat and students, Granthis and scholars, engineers), the three surfaces they use (website, iOS app, wiki), the read-only API running as Vercel functions and the pinned database behind it, sggs-data that turns the source Bir PDF into that database, the labelled English layer, and CI as the only way anything reaches production. 01 · System landscape Who uses the SGGS Knowledge Base, what they touch, and where the text comes from SurfacesPlatform Sangat · students — read, search, studySangat · studentsread, search, studyGranthi · scholar — reviews, never editsGranthi · scholarreviews, never editsEngineers · interns — change it by PRsEngineers · internschange it by PRsWebsite — gurbanisoul.com — frontend/Websitegurbanisoul.comfrontend/Gurbani Soul (iOS) — offline, own DB copyGurbani Soul (iOS)offline, own DB copyThis wiki — docs.gurbanisoul.comThis wikidocs.gurbanisoul.com/api/*live widgetsThe API, Python stdlib — Vercel functions, same origin — 29 routes · 5 contextsThe API, Python stdlibVercel functions, same origin29 routes · 5 contextsdb/sggs.sqlite — 60,658 lines · 1,430 Angs — installed by pin, verifieddb/sggs.sqlite60,658 lines · 1,430 Angsinstalled by pin, verifiedby pintranslationsShabadOS / BaniDB — English, a labelled layer — never blended inShabadOS / BaniDBEnglish, a labelled layernever blended insggs-data — source PDF → database — reconciled, gated, ledgeredsggs-datasource PDF → databasereconciled, gated, ledgereddeploysCI gates — tests · contract · integrity — the only way to deployCI gatestests · contract · integritythe only way to deployVercel — the web + the API functions — Render kept on standbyVercelthe web + the API functionsRender kept on standby a personcomponent in this projectdata at restexternal systemgate: fails the build or the deployflow: data or control moves this wayreference: pins, reads or derives from Source of truth: docs/architecture/overview.md · webapp/serve.py ·gateway/routes.json · dataset.lock.json ·.github/workflows/deploy-production.yml v1.3.10 · verified 2026-09-27 · d2f2e41Sri Guru Granth Sahib Ji — Knowledge Base · engineering wiki
Poster 01 — the system landscape: people, surfaces, API, pinned database, sources, CI · open full size

System context (C4 level 1)

Poster 01 above is the system context: three kinds of people, three surfaces, one read-only API, the pinned database, the source Bir and the labelled English layer, and CI as the only way to production.

Containers (C4 level 2)

The containers live in three repositories joined by reviewed lock files — the data repository builds and proves the database, this one pins and serves it and publishes the golden contract, the app vendors both at a release:

Three repositories and their pins sggs-data builds and publishes the scripture database; sggs-platform pins it by commit and sha256, serves the API and website, and publishes the golden contract; gurbani-soul-ios pins the contract at a platform release and builds its own database from the same dataset pin; this wiki pins the sibling repositories’ docs. One version number spans web, API and app. 02 · Three repositories and their pins Nothing is copied by hand between data, platform and app — every hand-off is areviewed lock file with a commit and a checksum sggs-data — the scripturesggs-platform — API and webgurbani-soul-ios Source Bir PDF — sha256 attestedSource Bir PDFsha256 attestedRebuild + gates — char-exact, ledgeredRebuild + gateschar-exact, ledgereddb/sggs.sqlite — commit + sha256db/sggs.sqlitecommit + sha256pinsdataset.lock.json — commit + sha256dataset.lock.jsoncommit + sha256make dataset — verified, atomicmake datasetverified, atomicgeneratesAPI + website — one APP_VERSIONAPI + websiteone APP_VERSIONcontract/ — golden vectors — + the OpenAPI speccontract/golden vectors+ the OpenAPI specpinssame pinvendor.lock.json — contract, by tagvendor.lock.jsoncontract, by tagBundled DB pair — built from the pinBundled DB pairbuilt from the pindataset.lock.json — the same pindataset.lock.jsonthe same pinByte-parity tests — Swift = PythonByte-parity testsSwift = PythonThe app — version = platformThe appversion = platformsources.lock.json — sibling docs (wiki)sources.lock.jsonsibling docs (wiki)One version number — the website = the API = the App Store binaryOne version numberthe website = the API = the App Store binary data at restcomponent in this projectpin: a reviewed lock fileproven, verified stategate: fails the build or the deployflow: data or control moves this wayreference: pins, reads or derives from Source of truth: dataset.lock.json · scripts/data/fetch_dataset.py ·docs-site/sources.lock.json · tools/gen_golden_vectors.py v1.3.10 · verified 2026-09-27 · d85c2adSri Guru Granth Sahib Ji — Knowledge Base · engineering wiki
Poster 02 — three repositories and their pins: sggs-data builds and publishes the database, sggs-platform pins and serves it, gurbani-soul-ios pins the contract and the dataset, one version number · open full size

Deployment (production)

Production deploymentA release merged into main runs deploy-production in CI. It waits for every required check, deploys the Render single API as the standby and verifies it by commit, then builds one Vercel deployment holding the website and the API as Python functions, proves it unaliased and promotes it to gurbanisoul.com, where /api is rewritten internally to the functions as gateway/routes.json says. The iOS app is archived from the release tag and goes to TestFlight and the App Store.proven unaliased, thenpromoted/api/* internal rewritethe release tag

A release merged into main

deploy-productionevery required check

Render: the single APIthe standby, verified by commit

One Vercel deploymentwebsite + API functions

gurbanisoul.com

The API functionsas gateway/routes.json says

iOS X.Y.Z build 1TestFlight, then the App Store

Production deploymentA release merged into main runs deploy-production in CI. It waits for every required check, deploys the Render single API as the standby and verifies it by commit, then builds one Vercel deployment holding the website and the API as Python functions, proves it unaliased and promotes it to gurbanisoul.com, where /api is rewritten internally to the functions as gateway/routes.json says. The iOS app is archived from the release tag and goes to TestFlight and the App Store.proven unaliased, thenpromoted/api/* internal rewritethe release tag

A release merged into main

deploy-productionevery required check

Render: the single APIthe standby, verified by commit

One Vercel deploymentwebsite + API functions

gurbanisoul.com

The API functionsas gateway/routes.json says

iOS X.Y.Z build 1TestFlight, then the App Store

Production deployment

The web frontend and API are same-origin: the browser calls /api/* and Vercel’s internal rewrites send those paths to the API, which runs as Python functions in the same Vercel project (ADR-0011). There is no CORS and the frontend carries no API-base configuration. gateway/routes.json decides the routing per environment:

  • Staging routes each of the five bounded contexts (reader, search, verify, insights, knowledge) to its own function, with all — the whole API — as the catch-all.
  • Production (v1.3.10, and 1.4.0) answers every /api path with all.
  • From a later release, after the app is live on the App Store, production routes the five contexts the same way as staging, all five in that one release (services-production, step 3). It is one line in gateway/routes.json; 1.4.0 leaves it out.

Setting production’s api_platform back to render proxies /api to the Render single API, which every release still deploys as the rollback target until it is retired. See Environments and bounded contexts.

The five layers

  1. Scripture core — lines (60,658 verbatim rows), raags, sections, authors, vaars.
  2. Search indexes — FTS5 (fts, fts_en, fts_shabad; fts_tri is built but no route reads it), variants, word_freq.
  3. Translations — the Khalsa English layer, a separate labelled table (never blended into Gurmukhi).
  4. Analytics / Insight Engine — theme network, stylometry, resonance, semantic neighbours.
  5. Knowledge layer — attributed raag-timing claims (divergence preserved, never adjudicated).

Source of truth vs generated

  • In sggs-data: the PDF-derived corpus and database, the timing seed, the concept definitions and the private translation inputs (fetched from Algorythmos-AI/sggs-source, checksum-verified).
  • Here, source of truth: webapp/serve.py + verify.py + romannorm.py (the behaviour the Swift port mirrors), frontend/src/, and dataset.lock.json (which database is served).
  • Here, generated: contract/*.ndjson + contract/openapi.json, frontend/dist/, webapp/static/; db/sggs.sqlite is installed from the pin, never committed.

See microservices roadmap for how the monolith is factored for a later service split.