domain/practice_modes — the engine-mode discriminator¶
backend/src/domain/practice_modes.py (32 lines). A practice's mode
selects which engine drives the session and which config fields the
catalog row carries. The enum values are the wire format — stored as
plain strings in practice.mode and emitted verbatim in API responses so
the frontend can branch on them without a translation table
(practice_modes.py:1-8).
The closed enumeration (backend/src/domain/practice_modes.py:15-28),
all 11 modes:
class PracticeMode(StrEnum):
"""Closed enumeration of ritual modes supported by the engine."""
MEDITATION_TIMER = "meditation_timer"
COUNT_UP = "count_up"
METRONOME = "metronome"
INTERVAL_BELL = "interval_bell"
REP_COUNTER = "rep_counter"
SENSE_GROUNDING = "sense_grounding"
TAROT = "tarot"
TALLIED_GROUNDING = "tallied_grounding"
MINDFUL_ANCHOR = "mindful_anchor"
CARD_MEDITATION = "card_meditation"
RANDOM_INTERVAL_BELL = "random_interval_bell"
ALL_MODES is the ordered tuple of wire values "suitable for CHECK
constraints and docs" (practice_modes.py:31-32). Consumers:
models/practice.pygeneratesck_practice_mode_validfromALL_MODESso the DB set cannot drift (backend/src/models/practice.py:9-17).models/practice_recipe.pyrestricts recipes to thesense_grounding/tallied_groundingsubset (RECIPE_MODES,backend/src/models/practice_recipe.py:49-52).schemas/practice_mode_config.pykeys its discriminated-union config validation on the same values (referenced frombackend/src/models/practice.py:53-56).models/practice_session.pydenormalizes the resolved mode into each session row (backend/src/models/practice_session.py:43-47).
Per-mode default config payloads are defined in the practice seed data —
see infrastructure — and per-mode
metadata schemas in backend/src/schemas/practice_session_metadata.py.
Grounded in adepthood@fbc529d, 2026-07-31.