# Lilith Persona Policy

Lilith is the V1 **contemplative policy substrate** — the deterministic rule
engine that decides _how Oshun is allowed to speak_ whenever a persona, a
generated artifact, or an assistant turn touches contemplative, spiritual,
therapeutic, or safety-sensitive ground. It is a substrate, not a customer
domain: there is no first-read Lilith surface; instead its tone, claim, crisis,
voice, lineage, and unsafe-output rules are meant to fire _inline_ across
whichever surface the member is on — a Tara ritual, a Veritas claim, a Sophia
answer, a Metis tutor exchange, a Living Scene render. This page documents the
policy catalogs and detectors that exist as real, versioned, tested code, names
the concrete TypeScript symbols that back each rule, and is candid about which
parts are fully wired into every runtime surface versus which are
catalog-complete but only partially fanned out. It serves platform and
trust-and-safety readers who need to reason about exactly what Lilith refuses,
where its teeth actually bite, and what is still design intent.

The library lives at `libs/oshun/persona-policy-lilith`. Its `src/index.ts`
re-exports **30 modules** — every catalog, detector, eval suite, and binding
named below is a real export from that barrel. The architectural companion to
this page is
[Lilith — Contemplative Policy Substrate](../architecture/substrate-lilith.md);
the feature hub is [../features.md](../features.md).

## Three things called "Lilith" — do not conflate them

The name is overloaded across the monorepo, and a reader can easily merge three
genuinely distinct things. This page calls it out explicitly because the naming
collision is a real source of confusion:

1. **The persona-policy substrate** (the subject of this page) —
   `libs/oshun/persona-policy-lilith`. A pure policy library: catalogs,
   detectors, eval suites, and adapter wiring. No UI, no server.
2. **The `/lilith` design-system showcase route** —
   `apps/oshun/web/src/app/lilith/page.tsx`. Its own header comment calls it the
   page where _"the whole design system reads as one page"_ — a broadsheet card
   grid (the "cream-paper newspaper-grade design system") where each card is a
   real route into a real component. This is **not** a mount point for crisis
   policy; it is the index of the Oshun web design language.
3. **The `apps/lilith/` meditation product** — an entirely separate application
   tree (`bff`, `svc-ai`, `svc-analytics`, `mobile`, `desktop`, `cli`,
   `seed-corpus`), with its own substrate libraries under `libs/lilith/`
   (`fastify-core`, `sdk`, `service-lib`, `partner-sdk`, `event-publisher`,
   `continuous-video-policy`). This is a full meditation app, distinct from the
   V1 persona-policy substrate. `V1/ARCHITECTURE.md` correctly disambiguates the
   two.

Note also what does **not** exist: there is no `services/lilith`,
`infrastructure/lilith`, or `libs/contracts/lilith` (unlike their psyche
equivalents). Lilith V1 is a library substrate, not a deployed service.

There is no `/lilith/*` customer route, no dedicated `/lilith/crisis` page, and
no canonical first-read surface for crisis policy. The operator-facing Lilith
work lives under
`apps/oshun/web/src/app/operator/{admin,incidents,personas,studio}`, the Lilith
studio at `apps/oshun/web/src/app/lilith-studio/`, the operator depth data at
`apps/oshun/web/src/lib/lilith-data/operator-depth.ts`, and the operator
component at `apps/oshun/web/src/components/lilith/operator.tsx`. (As an honest
triage note: the customer-side `LilithExplore` component in
`apps/oshun/web/src/components/lilith/customer-shell.tsx` is defined but is
imported by **no route** — a real example of the partial-fan-out caveat below.)

## What is real, and what is still wiring

The bright line worth stating up front: **the policy library is overwhelmingly
real and domain-specific**, but the _enforcement fan-out into every surface_ is
partial. Concretely:

- **Real:** deterministic detectors with regex phrase catalogs, versioned policy
  sets, validated taxonomies, the canonical adapter's defense-in-depth crisis
  guarantee, and six named eval suites plus two cross-product harnesses. Every
  enum and constant cited on this page matches the source verbatim.
- **Partial / aspirational:** the completeness audit rates the
  `crisis-aware-tone-policy` and the `arete-living-offering-create` Lilith
  crisis pre-screen as _partial_. The architecture's promise that Lilith is
  "enforced on every assistant turn / Living Scenes render / Tara invitation" is
  the design intent and is encoded as a required-surface binding catalog — but
  uniform runtime fan-out across all surfaces is not fully proven, and the live
  cloned-voice provenance pipeline and the operator-override governance UI were
  not verifiable end-to-end (the catalog logic exists; the runtime/UI wiring is
  less so).

This page documents what is in the code; where something is intent rather than
proven runtime, it says so.

## The canonical adapter and the no-bypass crisis guarantee

The entry point is `createCanonicalLilithPersonaPolicyAdapter`
(`canonical-adapter.ts`). It wraps an injected `LilithPersonaPolicyApiAdapter`
and exposes the policy surface every consumer calls: `selectPolicy`,
`getToneGuidance`, `assessSafety`, `checkTopicScope`, `buildPromptOverlay`, and
`evaluateInteraction`.

The most important property of this adapter is its **defense-in-depth crisis
guarantee**, and it is a concrete, testable mechanism rather than prose. When
constructed, the adapter binds `createLilithCrisisSafetyAnalyzer()` — the
validated 13-rule crisis catalog — **on by default**:

```ts
// canonical-adapter.ts
const crisisSafetyAnalyzer =
  options.crisisSafetyAnalyzer ?? createLilithCrisisSafetyAnalyzer();
```

On every safety analysis at the adapter boundary, the injected backend's verdict
is merged with the crisis analyzer's verdict via `mergeLilithSafetyAnalyses`,
**always taking the more severe signal on every axis** (category, risk level,
and the boolean `shouldEscalate` / `shouldBlock` / `requiresDisclaimer` flags
are OR-ed; never downgraded). The merge ranks categories
`safe < needs_disclaimer < out_of_scope < needs_escalation < blocked` and risk
levels `none < low < moderate < high < critical`. The practical consequence: an
integrator who injects an always-`"safe"` stub `analyzeSafety` **cannot silently
bypass** the validated crisis catalog — a crisis the catalog detects is honored
regardless of what the injected backend returned. Because the merge can only
escalate, enabling it by default can only make a turn's disposition stricter.
This is the real teeth behind the "no-bypass guarantees" promise: crisis policy
supersedes persona, lineage, pedagogy, and grounding policy and cannot be
overridden by user prompt or admin copilot.

`crisis-safety-analyzer.ts` is the module that supplies this. Its
`analyzeLilithSafetyViaCrisisPolicy` runs `detectLilithCrises`
(severity-ordered) and, on any detection, builds a response plan with
`buildLilithCrisisResponsePlan`, emitting `category: 'needs_escalation'`,
`shouldEscalate: true`, and a `shouldBlock` equal to the plan's `haltSynthesis`.
It is intentionally **fail-closed**: a detected crisis yields a hard block +
escalation so the downstream disposition resolves to `block`/`escalate`. When no
crisis is found, it returns the frozen `SAFE_ANALYSIS` constant — an honest
"nothing detected," not a fabricated success.

> Accuracy note: `V1/ARCHITECTURE.md` (§ Lilith · Adapter) once described the
> adapter as `src/adapter.ts` plus `contemplative-tone-policy.ts`,
> `assistant-persona-binding.ts`, and `content-qa-hooks.ts`. All four files
> exist, but that list names 3 of ~30 modules and omits the largest, most
> load-bearing policy files — `crisis-behavior-policy.ts` (68 KB),
> `unsafe-claim-policy.ts` (65 KB), `voice-policy.ts` (62 KB),
> `spiritual-boundary-policy.ts` (43 KB), `policy-model.ts` (38 KB),
> `surface-policy-binding.ts` (34 KB), `generation-gentleness-floor.ts` (33 KB),
> `teacher-safety-policy.ts` (32 KB) — plus the `crisis-recovery/`,
> `sacred-symbols/`, and `tone-bands/` subtrees. The canonical entry is
> `canonical-adapter.ts` (`createCanonicalLilithPersonaPolicyAdapter`), not the
> bare `adapter.ts`.

## Persona taxonomy — the seven canonical roles

Every Lilith-governed persona inherits from exactly one of seven typed roles.
This is the single canonical persona taxonomy for V1; the Persona Registry, the
assistant persona-handoff surface, and every Lilith eval suite reference these
role names verbatim. The enum is `LINEAGE_PERSONA_ROLES`
(`sacred-symbols/lineage-binding.ts:20`) and the count is exactly seven:

| Role          | Where it serves                                             | Capabilities                                                  | Hard bans                                                                     |
| ------------- | ----------------------------------------------------------- | ------------------------------------------------------------- | ----------------------------------------------------------------------------- |
| `teacher`     | Tara teachers, Metis tutors, Nisaba scholar-personas        | instruction, scaffolded guidance, source citation             | clinical diagnoses, treatment plans, prophecy, financial advice, legal advice |
| `coach`       | Arete coaches, recovery-aware support personas              | humane prompting, accountability, plan re-scope, friction     | shaming language, escalating-stake framing, punitive streak rhetoric          |
| `comparative` | cross-lineage comparative-religion / comparative-philosophy | even-handed comparison with named-source attribution          | syncretic erasure of declared lineages, prescriptive synthesis                |
| `explainer`   | Veritas explainers, Nyx narrators, Metis lecture voices     | grounded explanation with citation, counterclaim presentation | editorialization beyond source warrant, speculation framed as fact            |
| `narrator`    | Living Scenes narration personas                            | scene narration, time-aligned cues, mood pacing               | outside-script improvisation, source citation in live scene flow              |
| `steward`     | admin-copilot, operator assistant, moderation/review-triage | operational tooling, audit-aware suggestion, policy reference | substituting for a human reviewer/moderator on consequential decisions        |
| `assistant`   | the general-purpose customer assistant                      | navigation, recall, light explanation, domain hand-off        | pretending to be a teacher/coach/steward when one is specifically required    |

Role inheritance is **final**: a `Persona` record fixes the capability ceiling
and default tone band on construction and **cannot widen** its inherited
capability set; tenant policy can only narrow it further. The specific persona
record adds named voice, avatar, lineage binding, locale, and approval state on
top of the inherited role. (`teacher-safety-policy.ts` carries a parallel
persona-family notion — `coach`, `support`, `contemplative_teacher` — used to
scope which teacher-safety policy set applies via `fitsPersonaFamilies`.)

## Tone band catalog and per-band capability caps

Tone bands are the named, ordered axis Lilith uses to gate behavior per surface,
persona, and context. The catalog is fully data-modeled in
`tone-bands/catalog.ts`: `TONE_BAND_IDS` declares the **8 bands in
strictest-first order**, and `TONE_BANDS` is an array of `ToneBandCap` records
carrying the actual ceilings:

| Band                   | `order` | Motion level (`motionMax`) | `audacityMax` | Share policy             | Generation tiers              |
| ---------------------- | ------- | -------------------------- | ------------- | ------------------------ | ----------------------------- |
| `contemplative-strict` | 0       | `reduced-motion` (0.1)     | 0             | `opt-in-redacted-intent` | `customer` (gated)            |
| `contemplative`        | 1       | `low` (0.25)               | 1             | `opt-in`                 | `customer`                    |
| `reflective`           | 2       | `low` (0.25)               | 1             | `opt-in`                 | `customer`                    |
| `neutral`              | 3       | `medium` (0.5)             | 2             | `allowed`                | `customer`, `curated-creator` |
| `briefing`             | 4       | `medium` (0.5)             | 2             | `allowed-with-citations` | `customer`, `curated-creator` |
| `instructional`        | 5       | `medium` (0.5)             | 2             | `allowed-with-citations` | `customer`, `curated-creator` |
| `celebratory`          | 6       | `high-pse-safe` (0.8)      | 3             | `allowed`                | `customer`, `curated-creator` |
| `urgent-safe`          | 7       | `low` (0.25)               | 0             | `operational-only`       | `operator` (platform-emitted) |

The `contemplative-strict` band sets `customerGenerationGated: true` — its
customer generation requires an explicit product gate. The `urgent-safe` band is
the only one with `shareAllowed: false`; it is reserved for operational
notifications about safety-relevant state (degraded service, crisis-frame entry,
account security).

`audacity` is a 0–5 scale that Isis uses to cap generation parameters (style
intensity, motion magnitude, narrative novelty). `clampAudacity` enforces the
ordering literally:
`Math.min(requested, bandCeiling, tenantCeiling ?? 5, userCeiling ?? 5)`.
**Bands cap the ceiling; tenant policy may lower further; user preference may
lower further still — none can widen.** `narrowestBand` returns whichever of a
set of bands has the lowest `order`, the mechanism by which a persona's default
band is merged with tenant/user narrowings.

`validateToneBandCatalog` is a real structural validator: it enforces canonical
ordering (`order === index`), motion-max in `[0, 1]`, valid generation tiers,
and the coherence rule that `operational-only` and `shareAllowed` cannot
disagree. Lilith also publishes a per-surface **transition graph**
(`tone-bands/transitions.ts`) declaring which bands may follow which within a
session (for example, `contemplative-strict` may transition to `contemplative`
for a closing reflection but not directly to `briefing`); forbidden transitions
are rendered as section breaks, and the band caps are enforced downstream in
`tone-bands/enforcement.ts`.

## Contemplative tone rubric

`contemplative-tone-policy.ts` models the tone rubric as data, not adjectives.
It exports `LILITH_CONTEMPLATIVE_TONE_POLICY_IDS`, the pace axis
`LILITH_TONE_PACE_LEVELS`, `LILITH_TONE_SILENCE_TOLERANCES`,
`LILITH_TONE_METAPHOR_USAGES` (`sparing | moderate | generous | poetic`),
`LILITH_TONE_WARMTH_LEVELS` (`reserved | warm | tender | effusive`), and
per-policy ceilings in `LILITH_CONTEMPLATIVE_TONE_CEILINGS`. The
certainty-marker rule is concrete: the contemplative band's `avoidPhrases`
catalog literally contains `'obviously'`, `'everyone knows'`, `'the truth is'`,
and `'beyond debate'` — the prohibited absolute claims the feature spec names.

### Gentleness floor

`generation-gentleness-floor.ts` is the pre-synthesis guard for any voiced or
contemplative generation. `LILITH_PROHIBITED_GENERATION_LANGUAGE_CATEGORIES`
includes `'fear-inducing-framing'`, backed by a real regex —

```
/\b(if you don'?t|or else|you'?ll fail|you are unsafe unless|something bad will happen|you will suffer|dangerous to stop)\b/i
```

— which directly implements the spec's certainty-marker prohibitions. The module
also encodes `LILITH_INTERPRETIVE_UNCERTAINTY_MARKERS` (the required-hedging
side), `LILITH_AUTHORITY_POSITIONING_CATEGORIES` (a regex catching
`/\bi am (?!not\b)(?:your\s+)?(?:guru|prophet|healer|master|sole authority)\b/i`,
the voice-of-authority avoidance rule), and
`LILITH_MEDITATION_FRAMING_CATEGORIES` (the descriptive-not-prescriptive
sensory-language rule). On failure, the prescribed runtime behavior is to **not
synthesize** and fall back to text until the draft is revised — the floor is
fail-closed, not advisory.

## Teacher persona safety policy

`teacher-safety-policy.ts` (version `LILITH_TEACHER_SAFETY_POLICY_VERSION = 1`)
governs persona-bound promises. It declares `LILITH_TEACHER_SAFETY_POLICY_IDS`
(including `coach-practitioner`, `mental-health-support`), an
`LILITH_TEACHER_ABSOLUTE_NEVER` list of advice categories that are categorically
banned, `LILITH_TEACHER_CLAIM_SCOPES`, and
`LILITH_TEACHER_VETTING_EVIDENCE_KINDS` for persona review. The
prohibited-promise catalog covers enlightenment, healing of medical conditions,
prophetic foreknowledge, romantic and financial outcomes, and guaranteed
transformation timelines; a missing `financial-disclaimer` maps to the required
`"financial advisor"` hand-off disclaimer. Required disclaimers include
present-time-only language, the "consult a qualified
[physician/therapist/financial advisor]" hand-off pattern for medical,
psychiatric, and financial framings, and synthetic-content disclosure on every
voiced or avatar persona. Identity rules forbid impersonation of named living
individuals without consent and contract, and of named historical or religious
figures without an explicit, reviewed lineage frame.

## Crisis-aware behavior

`crisis-behavior-policy.ts` (the 68 KB core) holds the **validated 13-rule
crisis catalog**. `LILITH_CRISIS_TYPES` is the canonical 13-entry enum:

`suicide-ideation`, `active-self-harm`, `acute-panic`, `dissociation`,
`trauma-resurfacing`, `substance-crisis`, `interpersonal-violence`,
`violence-toward-others`, `abuse-disclosure`, `eating-disorder`, `child-safety`,
`psychosis-adjacent`, `acute-grief`.

> Staleness note: the prose in `V1/features.md` once described the signal
> taxonomy as "suicidal ideation (active, passive, planned), self-harm (active,
> ideation)… psychotic-symptom indicators, child-protection signals." That prose
> does **not** map 1:1 to the code enum: the canonical enum uses `child-safety`
> (not "child-protection") and `psychosis-adjacent` (not "psychotic-symptom"),
> adds `trauma-resurfacing` and `acute-grief` (absent from the old prose), and
> does **not** break suicide into separate `active`/`passive`/`planned` enum
> members at the _type_ level. Those sub-qualifiers live one layer down, in the
> **signal** taxonomy.

Beneath the 13 response types is a finer-grained **signal** layer:
`LILITH_CRISIS_SIGNAL_TYPES` (15 entries, including `suicide-active`,
`suicide-passive`, `suicide-planned`, `self-harm-active`, `self-harm-ideation`,
`domestic-violence`, `psychotic-symptom`, `child-protection`) and the
`LILITH_CRISIS_SIGNAL_TAXONOMY` — an array of `LilithCrisisSignalTaxonomyRule`
records, each mapping a `signalType` to a `responseCrisisType`, a human label,
`phrasePatterns` (e.g. `'kill myself'`, `'end my life'`, `'want to die'` for
`suicide-active`, with `minimumRiskLevel: 'critical'`), advisory
`contextSignals`, and a forced `minimumRiskLevel`. `detectLilithCrisisSignals()`
runs the catalog against an utterance.

Crisis resources are first-class: `LILITH_CRISIS_RESOURCE_KINDS` includes
`suicide-hotline`, `crisis-text-line`, `emergency-services`,
`domestic-violence-hotline`, and `eating-disorder-hotline`, resolved
region-aware (universal + regional registries, with a `'DEFAULT'` fallback).
`buildLilithCrisisResponsePlan` assembles the `resourcesToSurface`,
`statementsToDeliver`, `mustBreakPersona`, and `haltSynthesis` directives for a
detection.

The per-signal response is fail-closed and well-defined: break persona to plain
operator voice, surface region-aware crisis resources, **halt synthesis** (no
ritual continuation, no avatar/voice rendering), suspend persona memory writes
for the session, and open a parallel safety-incident record routed to
crisis-trained reviewers. During an open crisis frame: no recall of prior
contemplative scripts that would re-enter the crisis state, no generative
summarization, no recommendation of contemplative practices, and no
admin-copilot inspection without elevated authorization.

### Crisis recovery journey

The crisis frame is only half the story; the recovery journey is the
_user-facing_ path back into the product, implemented as the `crisis-recovery/`
subtree (not just prose):

- **`stillness-window.ts`** — after a crisis frame fires, every non-safety
  surface is suspended. `STILLNESS_WINDOW_DEFAULT_SECONDS = 600` (10 minutes),
  `STILLNESS_WINDOW_FLOOR_SECONDS = 180` (the floor is **never less than 3
  minutes**), and `STILLNESS_WINDOW_EXTENSION_CEILING_SECONDS = 7200`. The
  module enumerates `NON_SAFETY_SURFACES` (`teaching`, `invitation`,
  `scheduled-generation`, `companion-suggestion`, `studio`, `gallery`,
  `voice-clone`, `live-scene`) that are suspended, and `SAFETY_SURFACES`
  (`crisis-resources`, `safety-resources`, `audit-platform`, `support-handoff`,
  `incident-record`, `reentry-prompt`) that remain available. Extensions carry a
  typed reason (`crisis-reframe | new-indicator | operator-extension`).
- **`reentry-flow.ts`** — at the end of the window the product asks **once**
  whether the member wants to continue; declining routes to an idle-safe surface
  and the product does not re-ask until a fresh session. On accept, the member
  lands on a re-entry home with conservative defaults (`contemplative-strict`
  band, no scheduled invitations, no sensitive-category recommendations).
- **`reframe-protection.ts`** — if a new crisis indicator lands inside an open
  stillness window or within 24h of frame close
  (`REFRAME_PROTECTION_AFTER_CLOSE_SECONDS = 24 * 3600`), `decideReframe`
  **extends** the existing frame (`kind: 'extend'`,
  `REFRAME_EXTENSION_SECONDS = 600`) rather than re-firing a fresh one —
  guarding against thrash and re-traumatization (double-surfaced resources,
  double-restart of the window).
- **`check-ins.ts`** — `CHECK_IN_KINDS = ['24h', '7d']` with
  `CHECK_IN_DELAY_SECONDS = { '24h': 86400, '7d': 604800 }`. Soft follow-ups are
  default opt-in, user-disable-able, delivered via the assistant only — never
  via push or notification. `scheduleCheckIns`, `applyCheckInEvent`, and
  `listDueCheckIns` model the lifecycle.
- **`incident-record.ts`** — every crisis frame generates an `Incident` record
  (TODOS §1.2); operator review is required within the tenant-policy time-box.
- **`locales.ts`** — support-resource sets and operator voice strings are
  localized per V1 launch locale and declared frame.

The member also gets a "what happened" surface in profile/safety that shows the
audit-platform-visible record of the frame (entry time, exit time, suppressed
surfaces, operator actions) — the member owns the record of what occurred.

### Launch locales

The V1 launch-locale set is canonical and exact: `OSHUN_LAUNCH_LOCALES`
(`libs/oshun/i18n/src/index.ts:26`) = **`en-US`, `es-US`, `fr-FR`, `de-DE`,
`ar`, `he`, `ja-JP`, `pt-BR`** (8 locales), with
`OSHUN_DEFAULT_LAUNCH_LOCALE = 'en-US'` and `ar` / `he` being RTL. The web shell
consumes this via `apps/oshun/web/src/i18n/config.ts` (which imports
`OSHUN_LAUNCH_LANGUAGE_PREFERENCES` and `RTL_LOCALES` from the same i18n
package). Both doc-cited paths resolve. Default-frame crisis copy must be
reviewed by a regional safety advisor before launch in a new locale; every
reference to "V1 launch locales" in the feature docs means exactly this set.

## Voice-quality and voice-abuse policy

`voice-policy.ts` (62 KB) backs both the voice-quality and voice-abuse rules.

**Domains and quality.** `LILITH_VOICE_DOMAINS` = `guided-practice`, `teaching`,
`sacred-reading`, `breathwork`, `silent-sitting`, `crisis-response`. The
`LilithVoiceQualityTarget` interface models acoustic targets a contemplative
voice must meet — pace WPM band, inter-clause pause band, loudness in integrated
LUFS, a true-peak ceiling in dBTP (loudness-war mastering is prohibited in
practice audio), minimum SNR, pitch-variation band in semitones (too flat is
robotic, too wild is theatrical), and a sibilance-harshness ceiling.
`LilithVoiceNaturalnessFloor` is the minimum-naturalness gate (below floor
forces fallback to text), `LILITH_VOICE_DOMAIN_TIMING_POLICY_SET` carries
per-domain pace bands (a Tara meditation pace ≠ a Veritas explainer pace), and
`LilithVoiceRerenderPolicy` caps re-render attempts per turn. The runtime checks
are `checkLilithVoiceQuality(...)` and `checkLilithVoiceDomainTiming(...)`.

**Abuse and provenance.** `LILITH_VOICE_ABUSE_PATTERNS` is a 16-entry catalog —
`sustained-shout`, `coercive-command-cadence`, `manic-cadence`,
`deceptive-warmth`, `simulated-confidant-intimacy`,
`simulated-breathing-inconsistent-with-content`,
`hypnotic-induction-without-disclosure`, `rapid-gasping-loop`,
`subliminal-layer`, `impersonation-of-real-teacher`,
`impersonation-of-clinician`, `parasocial-intimacy-escalation`,
`sexualized-prosody`, `infrasound-entrainment`, `unwatermarked-cloned-output`,
and `identity-drift-from-consented-profile`. `LILITH_VOICE_WATERMARK_ALGORITHMS`
names the two real algorithm identifiers (`oshun-phase-watermark-v1`,
`oshun-spread-spectrum-v1`).
`LILITH_CLONED_VOICE_CONSENT_STATUSES = ['signed', 'revoked', 'expired']` gates
cloned voices, and `LilithVoiceProvenanceRequirements` models the immutable
provenance record (consent ID, prompt, model, watermark hash, timestamp,
invoking user, tenant). Above-threshold abuse halts generation, notifies the
operator, suspends entitlement, and opens review; consent revocation cascades
across all generated assets.

> Honest caveat: the catalog logic above is real and tested, but the _live_
> cloned-voice provenance pipeline — end-to-end from consent record through
> watermarked render to immutable provenance — was not verifiable end-to-end at
> the runtime/UI level. Treat the runtime fan-out as design intent backed by
> real policy primitives.

## Spiritual-domain boundary rules

`spiritual-boundary-policy.ts` (43 KB) encodes declared-lineage respect and
extractive-syncretism prevention. `LILITH_SPIRITUAL_BOUNDARY_RULE_IDS` covers
`within-tradition-exegesis`, `cross-tradition-comparison`,
`cross-tradition-practice-transfer`, `inter-tradition-conversion-pressure`,
`claiming-universal-truth`, `supernatural-claim`,
`initiation-or-empowerment-claim`, `protected-lineage-disclosure`,
`secular-translation`, and `scholarly-citation`. Each rule resolves to one of
four `LILITH_BOUNDARY_STANCES` — `permit`, `permit-with-attribution`,
`redirect`, or `refuse`. `LILITH_PROHIBITED_SPIRITUAL_CLAIM_CLASSES` includes
`prophecy`, `soteriological-guarantee`, `spiritual-level-diagnosis`,
`karmic-pronouncement`, and `cosmology-as-fact`, each with a phrase catalog —
e.g. the `soteriological-guarantee` class catches `'you will reach nirvana'` and
the boundary catalog catches `'you will enter samadhi'`.
`LILITH_TRADITION_SENSITIVITIES` (`closed-practice`, `initiation-required`,
`oral-transmission-only`, `gendered-role-restricted`, `age-restricted`,
`community-gatekept`, `tribal-sovereignty-protected`) tags traditions whose
practices require extra care.

## Cultural and lineage sensitivity policy

`sacred-symbols/lineage-binding.ts` is the validator behind declared-lineage
respect. `checkPublishLineage` rejects an artifact at composition time with a
typed `LineageBlockReason` — `missing-lineage-tag`,
`cross-lineage-without-comparative`, `invalid-lineage`, or `duplicate-lineage` —
across the `PUBLISHABLE_KINDS` set (Tara passage, Nisaba passage, Veritas story,
Living Scene template, etc.). The **comparative-only mixing gate** is literal:
only a `comparative` persona may juxtapose lineages within a single arc;
`teacher` and `coach` personas must hold to a single declared lineage per arc.
`recommendationFraming` surfaces a recommendation from outside the member's
declared frame as "comparative" with a soft notice, and `emitLineageBinding` /
`captureLineageBindingAuditRecord` /
`attachLineageBindingToLivingScenesRenderEnvelope` emit the per-session
`LineageBinding` attestation captured in the audit trail and the Living Scenes
Render Envelope. The companion `sacred-symbols/register.ts` is the curated
catalog of symbols/elements declared sacred-in-context, whose first-time use in
any surface requires operator-tier approval.

## Unsafe-claim handling

`unsafe-claim-policy.ts` (65 KB) is the claim engine.
`LILITH_UNSAFE_CLAIM_CLASSES` is the **9-class** taxonomy: `medical`,
`psychiatric`, `financial`, `legal`, `prophetic`, `conspiratorial`,
`defamatory`, `retaliatory`, `electoral-influence`.
`LILITH_UNSAFE_CLAIM_CLASS_TAXONOMY` maps each class to a
`LilithUnsafeClaimClassRule` carrying a `defaultSeverity` (one of
`LILITH_UNSAFE_CLAIM_SEVERITIES = ['elevated', 'high', 'critical']`), linked
category IDs, and a `detectionPhrases` catalog — for example, the `medical`
class defaults to `critical` severity, links the `miracle-cure-physical`,
`reject-medical-care`, and `dangerous-breathwork` categories, and detects
phrases like `'cure'`, `'medical treatment'`, `'surgery'`, `'chemotherapy'`,
`'vaccine'`.

The per-class default response is one of the seven
`LILITH_UNSAFE_CLAIM_CLASS_RESPONSE_TYPES`: `refuse`, `refuse-with-resources`,
`hedge-with-redirect`, `allow-with-citation-mandatory`, `allow-with-disclaimer`,
`allow-only-from-approved-source-set`, `expert-handoff`. The engine ranks these
when multiple fire so the most-restrictive dominates, and every claim-handling
decision is logged with classifier output, the response chosen, the source set
used, and a user-feedback receipt.

## Surface wiring, override governance, tenant constraints, and versioning

These are the operational seams the feature docs describe narratively but which
exist as concrete modules.

**Surface binding.** `surface-policy-binding.ts`
(`LILITH_SURFACE_POLICY_BINDING_VERSION = 1`) binds policy to named consumers.
`LILITH_REQUIRED_SURFACE_WIRING_IDS` enumerates the ten wiring points the docs
list as prose: `tara-teacher-personas`, `contemplative-assistant-personas`,
`ritual-script-generation`, `meditation-script-narration`, `voice-rendering`,
`avatar-rendering`, `veritas-explainer-generation`, `sophia-grounded-answers`,
`metis-tutor-responses`, `support-copilot`. Each binding runs through the
`LILITH_SURFACE_POLICY_STAGES` pipeline (`registration`, `pre-generation`,
`draft-review`, `pre-render`, `post-render`, `audit`) and selects from the 19
`LILITH_SURFACE_POLICY_CHECK_IDS` (`teacher-safety`, `contemplative-tone`,
`generation-gentleness-floor`, `crisis-behavior`, `spiritual-boundary`,
`ritual-content-rules`, `unsafe-claim`, `citation-mandatory`,
`approved-source-set`, `voice-quality`, `voice-abuse`,
`cloned-voice-provenance`, `voice-watermark`, `avatar-persona-release`,
`synthetic-content-disclosure`, `operator-human-review`,
`operator-override-governance`, `tenant-policy-floor`, `claim-handling-audit`).
`validateLilithSurfacePolicyBindingSet` proves the set is complete and
well-formed. This catalog is the concrete encoding of the "wiring points" — but,
per the candor section above, the _runtime fan-out_ across every one of these
surfaces is the part rated partial; the binding catalog asserts the contract,
not that every surface currently executes it.

**Override governance.** `operator-override-governance.ts`
(`LILITH_OPERATOR_OVERRIDE_GOVERNANCE_VERSION = 1`) requires elevated
authorization for any operator override:
`LILITH_OPERATOR_OVERRIDE_AUTHORIZATION_ROLES` = `governance-lead`,
`trust-safety-operator`, `safety-engineer`, `clinical-advisor`, `legal`;
authorization statuses are `approved | pending | rejected | expired`; outcomes
are
`allow | allow-with-disclaimer | redirect | escalate | block | send-to-human-review`.
Overrides are time-bound (`LilithOperatorOverrideScope`), rationale-captured,
and audited (`LilithOperatorOverrideAuditRecord`), and recurring overrides trip
the `LILITH_OPERATOR_OVERRIDE_RECURRING_POLICY` review trigger. (The governance
_UI_ that drives this was not verifiable end-to-end; the policy logic is real.)

**Tenant constraints.** `tenant-policy-constraints.ts`
(`LILITH_TENANT_POLICY_CONSTRAINT_POLICY_ID = 'tenant-policy-constraint-floor'`)
encodes the asymmetry: a tenant **cannot loosen** the operator baseline and
**can only tighten** it. `validateLilithTenantPolicyConstraint` literally
rejects with errors like
`tenant cannot loosen operator baseline: missing check "…"`,
`…added modality "…"`, a weaker grounding requirement, or a more permissive
memory envelope — so, e.g., an institutional Metis can tighten unsafe-claim
thresholds but never relax them.

**Versioning and moderation.** `policy-versioning.ts` makes every Lilith policy
a versioned artifact with changelog, evaluation evidence, rollout cohort, and
rollback plan; `persona-release-metadata.ts` carries the persona-release bundle
and lifecycle
(`proposed → in-review → approved → deployed → maintained → deprecated → retired`,
every transition writing a `PersonaLifecycleEvent`); and
`moderation-queue-binding.ts` routes flagged output into the review queue.

## Evaluation suites

The eval modules are real, not placeholders, and directly back the feature docs'
"Evaluation suites" promise:

| Suite                           | What it gates                                               |
| ------------------------------- | ----------------------------------------------------------- |
| `eval-tone-quality`             | gentleness, certainty markers, lineage attribution          |
| `eval-crisis-handling`          | per-signal response correctness and the no-bypass guarantee |
| `eval-clone-abuse-resistance`   | cloned-voice abuse resistance                               |
| `eval-spiritual-boundary`       | boundary-class refusals and stances                         |
| `eval-unsafe-claim`             | per-claim-class default response correctness                |
| `eval-regression-blockers`      | release-blocking regression suite for safety degradation    |
| `tone-cross-product-harness`    | the band × persona × context cross-product                  |
| `lineage-per-tradition-harness` | per-tradition lineage policy parity                         |

Each ships with a co-located `.test.ts` exercising it. The regression blockers
suite is the gate that blocks a release when safety quality degrades.

## Continuous-video tone class (Living Scenes)

For Living Scenes, Lilith adds a continuous-video tone class covering
rhythmic-pattern + strobe detection (PSE-safe per ITU-R BT.1702-2 / WCAG, hard
kill before frames reach the user), per-persona luminance / contrast /
motion-density caps, color-cycle and flicker bands, narrative-cadence pacing
bands, the live-cue policy gate, sensitive-topic pre-roll on kept artifacts, and
a scene crisis frame (fade-to-still + plain operator voice + Iris memory-write
suspension + safety-incident record creation) that supersedes persona, lineage,
pedagogy, grounding, and any user/admin override. See
[Scene Safety, Determinism, Provenance, and Cue Privacy](./scene-governance.md)
for the full scene safety surface; the separate
`libs/lilith/continuous-video-policy` library belongs to the meditation app, not
this substrate.

## Tests (invariants worth naming)

- Persona taxonomy: every persona inherits exactly one role; capability widening
  is rejected at construction.
- Tone-band caps: every band's caps are enforced in Isis generation, Living
  Scenes, and share controls; `validateToneBandCatalog` enforces canonical order
  and coherence.
- Band transition graph: forbidden transitions render as section breaks; allowed
  transitions emit no break.
- Lineage policy: comparative-only mixing enforced; sacred-symbol register
  triggers a per-symbol approval gate; user-declared frame respected in
  recommendations.
- Crisis: `mergeLilithSafetyAnalyses` only ever escalates; the canonical adapter
  binds the 13-rule catalog by default so an always-`"safe"` injected backend
  cannot bypass it.
- Crisis recovery: stillness-window minimum (3-minute floor) honored; re-frame
  protection extends rather than re-fires; localization parity across the 8 V1
  launch locales; check-in cadence respects opt-out.

## Related

- [Assistant Experience](./assistant-experience.md) — the conversational surface
  where persona roles and tone bands are applied per turn.
- [Persona, Avatar, and Voice Packs](./persona-avatar-voice-packs.md) — the
  governed assets whose release lifecycle and voice policy this page gates.
- [Iris Memory and Identity](./iris-memory-identity.md) — the memory substrate
  whose writes a crisis frame suspends.
- [Psyche Real-Time Runtime](./psyche-realtime-runtime.md) — the live session
  runtime that carries crisis-frame continuity.
- [Isis Generation Control](./isis-generation-control.md) — the generation
  control plane that consumes tone-band audacity caps and generation tiers.
- [Sophia Grounding](./sophia-grounding.md) — the grounding gate the
  unsafe-claim and explainer policies sit beside.
- [Review, Compliance, and Trust & Safety](./review-trust-safety.md) — the
  operator queues and crisis-incident workflow Lilith feeds.
- [Living Scenes — Concept and Customer Promise](./living-scenes-overview.md)
  and
  [Scene Safety, Determinism, Provenance, and Cue Privacy](./scene-governance.md)
  — the continuous-video tone class and scene crisis frame.
- [Lilith — Contemplative Policy Substrate](../architecture/substrate-lilith.md)
  — the architectural deep-dive.
- [../features.md](../features.md) — the feature hub. Backlog: §1.2 (Incident),
  §12.9 (tone bands), and §12.12 (crisis recovery) in
  [`../TODOS.md`](../TODOS.md); dependency ordering in
  [`../DEPENDENCIES.md`](../DEPENDENCIES.md).
