# Nitnem / Gutka Sahib — spec & frozen contract
The Nitnem feature (PR #43, v1.2.0) plus the premium pass (v1.3.0). Architecture: ADR-0006.
- Page:
- Updated: 2026-10-27
- Pinned copy of `Algorythmos-AI/gurbani-soul-ios` `docs/nitnem/spec.md` at `a386422`; the canonical file is
- From the Sri Guru Granth Sahib Ji — Knowledge Base wiki. Sri Guru Granth Sahib Ji is quoted verbatim, cited by Ang, and never altered.
---
The Nitnem feature (PR #43, v1.2.0) plus the premium pass (v1.3.0). Architecture: ADR-0006.
## Source policy
- **SGGS lines** are pointers into this project's verbatim corpus (`lines.id`), rendered from
our text and cited "Sri Guru Granth Sahib Ji · Ang N". Proven by the reconcile attestation.
- **Non-SGGS lines** (Sri Dasam Granth, Ardaas) live in `extra_lines`: converted verbatim,
labelled by source, no English, never an Ang, never FTS-indexed, never bookmarkable. They
ship to the App Store only after `ios/Resources/NITNEM-REVIEW.md` records `REVIEWED: true`
and `NitnemReview.extraTextReviewed` is flipped in the same commit; until then the app labels
them "under scholarly review".
- **Variants** share a `key` and differ by `variant` (`UNIQUE(key, variant)`, exactly one default
per key): Rehras `sgpc` (default) / `taksal`; Asa Di Vaar `kirtan` (default, the chhants from
Ang 448–451 interleaved) / `printed` (the Vaar exactly as printed, Ang 462–475, lines
20883…21519 — range-defined with verbatim text anchors, ADR-0006 §4). The API allowlist is
`('', 'sgpc', 'taksal', 'kirtan', 'printed')`; progress is keyed `key/variant`.
- **Numbering** (pauri / ashtapadi / salok / verse) is derived only from `BaniLine.markers`
(bare Gurmukhi digits) or a Dasam line's trailing `॥N॥`, through `BaniOutline`. A strict
validity gate returns `[]` rather than ever showing a guessed number. Numbers appear only in
the Contents sheet, the position bar caption, and a quiet margin label — never in the verse.
## Reading contexts
The same `BaniReaderScreen` serves both surfaces and only its closing chrome differs
(`BaniReaderContext`): **Nitnem** offers the band's next bani, the band-complete card and "Back to
Nitnem"; **Explore** (a composition opened from the Index) offers the next composition on the rail
and "Back to Index", and never consults the time band. Scripture, outline, reading settings and the
saved position are identical — a composition read from the Index completes the same Popular row in
Nitnem, because both use `BaniSummary.id` (`key` or `key/variant`) as the progress identity.
## Reading steps
The bottom bar steps by the composition's printed rhythm whenever `BaniOutline` yields more than
one numbered pauri/ashtapadi (`BaniPager.steps`): Sukhmani Sahib has three registry line-groups —
the ਗੁਰਦੇਵ ਮਾਤਾ salok, the body, the salok again — so "Part 1 of 3" would have offered a
2,027-line part. Banis without such an outline (Rehras Sahib, Aarti) keep part navigation, and a
single-section bani keeps top/end. "Previous" from mid-stanza returns to that stanza's start.
## The Nitnem day
A Nitnem day rolls at **03:00** (`NitnemClock.dayKey(now − 3h)`): Kirtan Sohila read at 22:00 is
still complete at 00:30, and the night band never splits across a calendar midnight. `NitnemClock`
is the single source of "now" (honours `SGGS_CLOCK_NOW`) for the home, reader, widgets and reminders.
## Time bands (wall clock)
03:00–09:00 Amrit Vela · 09:00–17:00 Morning banis · 17:00–21:00 Evening · else Night. Bands only
ORDER the home; nothing is hidden.
## Persistence
- `nitnem-progress.json` (App Group `group.org.sggs`), **schema v1, never migrated**: per-bani
`lastSeq`, `lastReadAt`, `completedDays`, and (v1.3.0, backward-compatible) `anchor` + `nLines`
so a saved position survives a registry rebuild. A file written by a newer schema loads
read-only and is never overwritten.
- The reading journey is computed on the fly from `completedDays` (no new file). My-Nitnem
custom sets will go in a separate file in a later release.
## Frozen XCUITest identifiers & strings (do not change without updating the suite)
Tab / nav: `Nitnem`, each bani's `titleEn` (e.g. "Japji Sahib", "Jaap Sahib"), band title
"Amrit Vela". Rows/actions: `bani_`, `Hukam`, `nitnemContinue`, `nitnemDone`, `nitnemNext`,
`baniBackToNitnem`, `baniOptions` (a Menu holding "Start again", "Contents", "Reading settings",
"Sehaj focus", "Gutka layout"), `verseHeading` (a centred heading line, e.g. a Sri Dasam Granth
chhand title), `gutkaRow` (two half-lines on one row, each a `gutkaHalf`) / `gutkaRowStacked`
(the same pair one per row when it does not fit),
`baniMarkComplete`, `baniPageBar`, `baniPosition` ("Part g of n" / "Line s of n"), `baniStanza`
("Pauri N of M" / "Ashtapadi N of M"), the step buttons "Previous/Next pauri|ashtapadi" (a bani
with a trustworthy outline of more than one numbered section steps by that rhythm; Rehras and
Aarti keep "Previous/Next part"), `compositionBegin`, `bandComplete`, `nitnemJourney`, `rehrasVariantPicker`. Explore → Index compositions:
`composition_` (hero card and "More compositions" row), `compositionNext`, `baniBackToIndex`,
the section header "Major compositions". Reading settings: `gurmukhiSizeSlider`,
`readerLeadingPicker`, `readerTonePicker`, `translitToggle`, `englishToggle`. The Jaap reader must
contain the text "Sri Dasam Granth"; the Rehras row label must contain "Taksal" when that variant
is chosen. Env hooks: `SGGS_CLOCK_NOW`, `SGGS_UITEST`. Wiped prefs: `sggs_rehras_variant`,
`sggs_reader_tone`, `sggs_reader_leading`, `sggs_gurmukhi_size`, `sggs_focus_mode`, `sggs_translit`,
`sggs_gutka_layout` (per-bani overrides of the gutka default, e.g. "anand=1,jaap=0"; the default
is on for jaap, chaupai, savaiye, savaiye_deenan, shabad_hazare_p10 and aarti).
## Deep links & intents
`sggs://nitnem`, `sggs://bani/[?variant=]`, `sggs://composition/[?variant=]`,
"Read a bani" App Intent. A bani link that names a **variant** is an explicit request for one form
and opens as a composition inside Explore; without one it opens the day's bani in Nitnem. Raag Clock is an Explore card. The Nitnem widget (kind `NitnemNow`) reads the App-Group snapshot + progress file, never the DB.
## Out of scope until v1.4.0
Hands-free auto-scroll, gentle reminders, Home-Screen quick actions, Spotlight bani entries,
"Continue my Nitnem" intent, My-Nitnem custom sets, Live Activity, online daily Hukamnama.
(The reading journey and the Nitnem widgets shipped in v1.3.0.)