All Decisions

ADR-0015: Reflection Questions — Living Question Bank with Defaults + Custom Questions

DateFebruary 8, 2026
CategoryData Architecture
Tags
data-modelfeature-flags

Context

  • Roadmap open question: Prompt immutability vs customization.
  • Design principle: “Prompts are concise and stable”.
  • We want to later package reflections to an LLM for weekly reflections/advice.
  • The user experience needs a small set of stable questions by default, while still allowing customization.

Constraints:

  • Local-first; no server reconciliation.
  • Weekly synthesis will treat the day’s reflection content as free text; question/answer structure mainly exists to guide daily entry.

Decision

We will support customization via a living question bank.

  • The app ships with a small set of default questions.
  • Users can add custom questions.
  • Questions can be toggled active/inactive.
  • Ordering is controlled by a position value stored on the answer rows at reflection creation time (so the day has a stable display order even if the question list later changes).

We do not version questions at this stage.

To preserve readability of old reflections while allowing question edits, we will store an optional question_text_snapshot on each answer row when it is created (see ADR-0014).

Scope boundaries:

  • UI/UX for prompt set management is out of scope here.

Suggested Persistence Shape (logical)

reflection_questions

  • id
  • question_text (unique)
  • is_default (boolean)
  • is_active (boolean)
  • created_at, updated_at

Invariants:

  • Default questions are inserted at database initialization (is_default = true).
  • Deactivating a question affects only future reflections; existing answers remain.
  • Deleting a question is discouraged; if deletion is allowed, it must not delete existing reflections (either prevent deletion when referenced, or null the FK and rely on question_text_snapshot).

Rationale

  • Matches the product need today: versioning is unnecessary if weekly synthesis consumes reflections as free text.
  • Customization with low complexity: a single questions table is straightforward in Room and easy to manage.
  • Preserves readability without full versioning: question_text_snapshot on answers keeps old reflections understandable even if questions are later edited.
  • Guardrails still possible: is_default enables gentle warnings before removing built-in questions.

Consequences

Positive effects:

  • Simple schema and customization story.
  • Questions can evolve incrementally without migrations.
  • Weekly LLM packaging can render a day as a single free-text block (with optional question/answer formatting).

Known downsides:

  • Without versioning, question edits can change meaning over time.
  • If question_text_snapshot is omitted, old answers can become confusing if questions are rewritten.

Follow-up work:

  • Define the initial default questions.
  • Define rules for deletion vs deactivation of questions (prefer deactivation).
  • Decide whether to allow editing of question text, or treat “edit” as (create new question + deactivate old).

Alternatives Considered

  • Hard-coded questions in app code — rejected: blocks customization.
  • Full prompt set versioning — rejected for now: extra complexity not required if weekly synthesis consumes free text.
  • No questions table (answers only) — rejected: prevents reuse of questions and makes customization harder.

Notes

  • This ADR intentionally mirrors the “defaults + customization” strategy used for categories/contexts in ADR-0012.
  • If later you want stronger historical semantics for LLM-guided longitudinal analysis, we can add versioning then with a migration.