feat: Q1 question variety improvement across all categories, app.db rebuild

This commit is contained in:
null 2026-06-19 00:35:00 -05:00
parent 93813255fd
commit a13167dc3e
22 changed files with 668 additions and 1574 deletions

Binary file not shown.

View File

@ -12,6 +12,8 @@ import os
from pathlib import Path from pathlib import Path
from typing import Dict, List, Any from typing import Dict, List, Any
from validate_question_variety import load_json_records, validate_records
def load_json_file(filepath: str) -> Dict[str, Any]: def load_json_file(filepath: str) -> Dict[str, Any]:
"""Load and parse a JSON file.""" """Load and parse a JSON file."""
@ -33,6 +35,11 @@ def get_category_id_from_filename(filename: str) -> str:
def build_database(json_dir: str, output_path: str) -> None: def build_database(json_dir: str, output_path: str) -> None:
"""Build SQLite database from JSON files.""" """Build SQLite database from JSON files."""
variety_errors = validate_records(load_json_records(Path(json_dir)), "JSON")
if variety_errors:
raise ValueError(
"Question variety check failed:\n" + "\n".join(variety_errors)
)
# Ensure output directory exists # Ensure output directory exists
os.makedirs(os.path.dirname(output_path), exist_ok=True) os.makedirs(os.path.dirname(output_path), exist_ok=True)

View File

@ -0,0 +1,369 @@
#!/usr/bin/env python3
"""
Q1 - improve question-bank variety.
This one-off migration edits BOTH the source JSON files and the shipped asset
DB. It only changes row content:
* delete fully duplicated question rows where text + answer payload match
* rewrite remaining duplicate visible texts so each prompt is unique
* rewrite over-cap template stems into varied, topic-specific prompts
Room schema and identity hash are untouched. build_db.py is NOT run.
"""
from __future__ import annotations
import json
import os
import re
import sqlite3
from collections import defaultdict
from pathlib import Path
from typing import Any
from validate_question_variety import MAX_TEMPLATE_STEM_ROWS, TEMPLATE_STEMS, normalize_text
ROOT = Path(__file__).resolve().parents[1]
QUESTIONS_DIR = ROOT / "seed" / "questions"
DB_PATH = ROOT / "app" / "src" / "main" / "assets" / "database" / "app.db"
UNDERSTOOD_STEM = "What do you wish I understood about "
NEED_STEM = "What do you need from me when "
UNDERSTOOD_TOPIC_FIXES = {
"your growth we have made": "the growth we have made",
"your forgiveness": "the forgiveness you offer",
"your support through stress": "the support you give through stress",
"your shared resilience": "our shared resilience",
"your ways we repair": "the ways we repair",
"your feeling chosen": "feeling chosen",
"your mutual effort": "our mutual effort",
"your a past hard season": "a past hard season",
"your future gratitude": "future gratitude",
}
UNDERSTOOD_VARIANTS = (
"What is one thing you want me to understand about {topic}?",
"What feels hardest to explain about {topic}?",
"What would help me see {topic} with more care?",
"What do you want me to notice about {topic}?",
"Where do you feel least understood around {topic}?",
"What part of {topic} do you rarely get to say out loud?",
"How can I better honor what {topic} brings up for you?",
"What question do you wish I would ask about {topic}?",
)
NEED_WHEN_VARIANTS = (
"When {condition}, what support from me would help most?",
"When {condition}, what should I do more of?",
"When {condition}, what should I avoid doing?",
"When {condition}, what reassurance helps most?",
"When {condition}, what would help you feel less alone?",
"When {condition}, what small action from me would matter?",
)
WORKING_ON_VARIANTS = (
"While we're working on {topic}, what support from me would help most?",
"While we're working on {topic}, what should I do more of?",
"While we're working on {topic}, what should I avoid doing?",
"While we're working on {topic}, what reassurance helps most?",
"While we're working on {topic}, what would help us stay connected?",
"While we're working on {topic}, what small action from me would matter?",
)
GENERIC_DUPLICATE_SUFFIXES = (
"right now",
"these days",
"in this season",
"when it matters most",
"without overthinking it",
)
POLISH_TEXT_REPLACEMENTS = {
"consistent actions feels fragile": "consistent actions feel fragile",
"boundaries after rupture feels fragile": "boundaries after rupture feel fragile",
"triggered moments feels fragile": "triggered moments feel fragile",
"trust timelines feels fragile": "trust timelines feel fragile",
"questions after betrayal feels fragile": "questions after betrayal feel fragile",
"trust deposits feels fragile": "trust deposits feel fragile",
"broken promises feels fragile": "broken promises feel fragile",
"relationship agreements feels fragile": "relationship agreements feel fragile",
"what your support through stress brings up": "what the support you give through stress brings up",
"your feeling chosen": "feeling chosen",
"your mutual effort": "our mutual effort",
}
def canonical_json(value: Any) -> str:
return json.dumps(value, sort_keys=True, separators=(",", ":"), ensure_ascii=False)
def question_payload(q: dict[str, Any]) -> str:
payload = {
"type": q.get("type", "written"),
"answer_config": q.get("answer_config", {}),
"options": q.get("options", []),
}
return canonical_json(payload)
def load_json_files() -> tuple[dict[Path, dict[str, Any]], dict[str, tuple[Path, dict[str, Any]]]]:
files: dict[Path, dict[str, Any]] = {}
by_id: dict[str, tuple[Path, dict[str, Any]]] = {}
for path in sorted(QUESTIONS_DIR.glob("*.json")):
with path.open() as f:
data = json.load(f)
files[path] = data
for q in data.get("questions", []):
by_id[q["id"]] = (path, q)
return files, by_id
def save_json_files(files: dict[Path, dict[str, Any]]) -> None:
for path, data in files.items():
with path.open("w") as f:
json.dump(data, f, indent=2, ensure_ascii=False)
f.write("\n")
def clean_topic(topic: str) -> str:
topic = topic.strip()
return UNDERSTOOD_TOPIC_FIXES.get(topic, topic)
def clean_condition(condition: str) -> tuple[str, bool]:
condition = condition.strip()
if condition.startswith("we are trying "):
return condition.removeprefix("we are trying ").strip(), True
return condition, False
def trim_question_mark(text: str) -> str:
return text.rstrip().removesuffix("?").strip()
def option_texts(q: dict[str, Any]) -> list[str]:
if q.get("options"):
return [opt.get("text", "") for opt in q["options"] if opt.get("text")]
answer_config = q.get("answer_config") or {}
config = answer_config.get("config", answer_config)
options = config.get("options") or []
if options:
return [opt.get("text", "") for opt in options if opt.get("text")]
option_a = config.get("optionA")
option_b = config.get("optionB")
if option_a and option_b:
return [option_a.get("text", ""), option_b.get("text", "")]
return []
def short_options(options: list[str]) -> str:
clean = [opt.strip().lower() for opt in options if opt.strip()]
if len(clean) >= 2:
return f"{clean[0]} or {clean[1]}"
if clean:
return clean[0]
return "the choices"
def unique_candidate(base: str, taken: set[str]) -> str:
normalized = normalize_text(base)
if normalized not in taken:
return base
for suffix in GENERIC_DUPLICATE_SUFFIXES:
candidate = f"{trim_question_mark(base)} {suffix}?"
if normalize_text(candidate) not in taken:
return candidate
n = 2
while True:
candidate = f"{trim_question_mark(base)} ({n})?"
if normalize_text(candidate) not in taken:
return candidate
n += 1
def template_rewrite(q: dict[str, Any], occurrence_index: int) -> str | None:
text = q["text"]
if text.startswith(UNDERSTOOD_STEM):
topic = clean_topic(text.removeprefix(UNDERSTOOD_STEM).rstrip("?"))
variant = UNDERSTOOD_VARIANTS[occurrence_index % len(UNDERSTOOD_VARIANTS)]
return variant.format(topic=topic)
if text.startswith(NEED_STEM):
condition, working_on = clean_condition(text.removeprefix(NEED_STEM).rstrip("?"))
if working_on:
variant = WORKING_ON_VARIANTS[occurrence_index % len(WORKING_ON_VARIANTS)]
return variant.format(topic=condition)
variant = NEED_WHEN_VARIANTS[occurrence_index % len(NEED_WHEN_VARIANTS)]
return variant.format(condition=condition)
return None
def duplicate_text_rewrite(q: dict[str, Any], duplicate_index: int) -> str:
text = q["text"]
options = option_texts(q)
qtype = q.get("type", "written")
if qtype == "this_or_that" and len(options) >= 2:
candidate = f"Which fits this choice better for you: {short_options(options)}?"
if duplicate_index % 2:
candidate = f"Which would you choose first here: {short_options(options)}?"
return candidate
if options:
option_hint = short_options(options)
if qtype == "multi_choice":
return f"Which answers fit best here: {option_hint}?"
return f"Which answer fits best here: {option_hint}?"
base = trim_question_mark(text)
suffix = GENERIC_DUPLICATE_SUFFIXES[duplicate_index % len(GENERIC_DUPLICATE_SUFFIXES)]
return f"{base} {suffix}?"
def delete_full_duplicates(files: dict[Path, dict[str, Any]]) -> set[str]:
groups: dict[tuple[str, str], list[dict[str, Any]]] = defaultdict(list)
for data in files.values():
for q in data.get("questions", []):
text = q.get("text", "")
if text:
groups[(normalize_text(text), question_payload(q))].append(q)
delete_ids: set[str] = set()
for rows in groups.values():
if len(rows) <= 1:
continue
for q in sorted(rows, key=lambda item: item["id"])[1:]:
delete_ids.add(q["id"])
if not delete_ids:
return delete_ids
for data in files.values():
data["questions"] = [q for q in data.get("questions", []) if q["id"] not in delete_ids]
return delete_ids
def polish_text(text: str) -> str:
for old, new in POLISH_TEXT_REPLACEMENTS.items():
text = text.replace(old, new)
return text
def polish_all_texts(files: dict[Path, dict[str, Any]]) -> dict[str, str]:
rewrites: dict[str, str] = {}
for data in files.values():
for q in data.get("questions", []):
text = q.get("text")
if not text:
continue
polished = polish_text(text)
if polished != text:
q["text"] = polished
rewrites[q["id"]] = polished
return rewrites
def rewrite_template_overflow(files: dict[Path, dict[str, Any]]) -> dict[str, str]:
rewrites: dict[str, str] = {}
by_stem: dict[str, list[dict[str, Any]]] = defaultdict(list)
for data in files.values():
for q in data.get("questions", []):
normalized = normalize_text(q.get("text", ""))
for stem in TEMPLATE_STEMS:
if normalized.startswith(stem):
by_stem[stem].append(q)
break
taken = {normalize_text(q["text"]) for data in files.values() for q in data.get("questions", []) if q.get("text")}
for stem, rows in by_stem.items():
rows = sorted(rows, key=lambda item: item["id"])
for index, q in enumerate(rows):
if index < MAX_TEMPLATE_STEM_ROWS:
continue
taken.discard(normalize_text(q["text"]))
candidate = template_rewrite(q, index)
if not candidate:
continue
candidate = unique_candidate(candidate, taken)
q["text"] = candidate
rewrites[q["id"]] = candidate
taken.add(normalize_text(candidate))
return rewrites
def rewrite_remaining_duplicate_texts(files: dict[Path, dict[str, Any]]) -> dict[str, str]:
rewrites: dict[str, str] = {}
rows = [q for data in files.values() for q in data.get("questions", []) if q.get("text")]
groups: dict[str, list[dict[str, Any]]] = defaultdict(list)
for q in rows:
groups[normalize_text(q["text"])].append(q)
taken = {normalize_text(q["text"]) for q in rows}
for group in groups.values():
if len(group) <= 1:
continue
for duplicate_index, q in enumerate(sorted(group, key=lambda item: item["id"])[1:], start=1):
taken.discard(normalize_text(q["text"]))
candidate = duplicate_text_rewrite(q, duplicate_index)
candidate = unique_candidate(candidate, taken)
q["text"] = candidate
rewrites[q["id"]] = candidate
taken.add(normalize_text(candidate))
return rewrites
def migrate_db(delete_ids: set[str], rewrites: dict[str, str]) -> int:
con = sqlite3.connect(DB_PATH)
try:
cur = con.cursor()
changed = 0
for qid in sorted(delete_ids):
cur.execute("DELETE FROM question WHERE id=?", (qid,))
changed += cur.rowcount
for qid, text in sorted(rewrites.items()):
cur.execute("UPDATE question SET text=? WHERE id=?", (text, qid))
changed += cur.rowcount
con.commit()
return changed
finally:
con.close()
def main() -> None:
files, _ = load_json_files()
delete_ids = delete_full_duplicates(files)
template_rewrites = rewrite_template_overflow(files)
duplicate_rewrites = rewrite_remaining_duplicate_texts(files)
polish_rewrites = polish_all_texts(files)
rewrites = {**template_rewrites, **duplicate_rewrites, **polish_rewrites}
save_json_files(files)
db_changed = migrate_db(delete_ids, rewrites)
print(f"Deleted fully duplicated rows: {len(delete_ids)}")
print(f"Template-stem rewrites: {len(template_rewrites)}")
print(f"Duplicate-text rewrites: {len(duplicate_rewrites)}")
print(f"Polish rewrites: {len(polish_rewrites)}")
print(f"DB rows changed: {db_changed}")
con = sqlite3.connect(DB_PATH)
try:
room_hash = con.execute("SELECT identity_hash FROM room_master_table").fetchone()[0]
active_count = con.execute("SELECT COUNT(*) FROM question WHERE status='active'").fetchone()[0]
finally:
con.close()
print(f"Room hash: {room_hash}")
print(f"Active questions: {active_count}")
if __name__ == "__main__":
main()

View File

@ -1541,7 +1541,7 @@
"id": "communication_090", "id": "communication_090",
"category_id": "communication", "category_id": "communication",
"type": "written", "type": "written",
"text": "What do you wish I understood about how you react under stress?", "text": "What feels hardest to explain about how you react under stress?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [

View File

@ -5340,4 +5340,4 @@
] ]
} }
] ]
} }

View File

@ -2136,7 +2136,7 @@
"id": "conflict_repair_125", "id": "conflict_repair_125",
"category_id": "conflict_repair", "category_id": "conflict_repair",
"type": "written", "type": "written",
"text": "What do you need from me when we are trying protecting the relationship?", "text": "While we're working on protecting the relationship, what should I do more of?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [

View File

@ -5340,4 +5340,4 @@
] ]
} }
] ]
} }

View File

@ -515,7 +515,7 @@
"id": "difficult_conversations_031", "id": "difficult_conversations_031",
"category_id": "difficult_conversations", "category_id": "difficult_conversations",
"type": "written", "type": "written",
"text": "What tone helps you stay open?", "text": "What tone helps you stay open these days?",
"depth": 2, "depth": 2,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3418,7 +3418,7 @@
"id": "difficult_conversations_184", "id": "difficult_conversations_184",
"category_id": "difficult_conversations", "category_id": "difficult_conversations",
"type": "single_choice", "type": "single_choice",
"text": "What makes you feel alone in a hard talk?", "text": "Which answer fits best here: dismissal or sarcasm?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3447,7 +3447,7 @@
"id": "difficult_conversations_185", "id": "difficult_conversations_185",
"category_id": "difficult_conversations", "category_id": "difficult_conversations",
"type": "single_choice", "type": "single_choice",
"text": "What kind of question opens you up?", "text": "Which answer fits best here: curious or specific?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3476,7 +3476,7 @@
"id": "difficult_conversations_186", "id": "difficult_conversations_186",
"category_id": "difficult_conversations", "category_id": "difficult_conversations",
"type": "single_choice", "type": "single_choice",
"text": "What kind of question closes you down?", "text": "Which answer fits best here: accusing or loaded?",
"depth": 1, "depth": 1,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5203,4 +5203,4 @@
] ]
} }
] ]
} }

View File

@ -1303,7 +1303,7 @@
"id": "emotional_intimacy_076", "id": "emotional_intimacy_076",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about your deep fears?", "text": "What would help me see your deep fears with more care?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1388,7 +1388,7 @@
"id": "emotional_intimacy_081", "id": "emotional_intimacy_081",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about the emotional needs you hide?", "text": "What do you want me to notice about the emotional needs you hide?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1473,7 +1473,7 @@
"id": "emotional_intimacy_086", "id": "emotional_intimacy_086",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about moments you feel unseen?", "text": "Where do you feel least understood around moments you feel unseen?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1558,7 +1558,7 @@
"id": "emotional_intimacy_091", "id": "emotional_intimacy_091",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about childhood patterns?", "text": "What part of childhood patterns do you rarely get to say out loud?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1643,7 +1643,7 @@
"id": "emotional_intimacy_096", "id": "emotional_intimacy_096",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about shame and tenderness?", "text": "How can I better honor what shame and tenderness brings up for you?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1728,7 +1728,7 @@
"id": "emotional_intimacy_101", "id": "emotional_intimacy_101",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about fear of being too much?", "text": "What question do you wish I would ask about fear of being too much?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1813,7 +1813,7 @@
"id": "emotional_intimacy_106", "id": "emotional_intimacy_106",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about fear of not being enough?", "text": "What is one thing you want me to understand about fear of not being enough?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1898,7 +1898,7 @@
"id": "emotional_intimacy_111", "id": "emotional_intimacy_111",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about emotional withdrawal?", "text": "What feels hardest to explain about emotional withdrawal?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1983,7 +1983,7 @@
"id": "emotional_intimacy_116", "id": "emotional_intimacy_116",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about repairing emotional distance?", "text": "What would help me see repairing emotional distance with more care?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2068,7 +2068,7 @@
"id": "emotional_intimacy_121", "id": "emotional_intimacy_121",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about receiving love?", "text": "What do you want me to notice about receiving love?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2153,7 +2153,7 @@
"id": "emotional_intimacy_126", "id": "emotional_intimacy_126",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about giving love under stress?", "text": "Where do you feel least understood around giving love under stress?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2238,7 +2238,7 @@
"id": "emotional_intimacy_131", "id": "emotional_intimacy_131",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about trusting me with sadness?", "text": "What part of trusting me with sadness do you rarely get to say out loud?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2323,7 +2323,7 @@
"id": "emotional_intimacy_136", "id": "emotional_intimacy_136",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about intimacy after conflict?", "text": "How can I better honor what intimacy after conflict brings up for you?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2408,7 +2408,7 @@
"id": "emotional_intimacy_141", "id": "emotional_intimacy_141",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about longing for closeness?", "text": "What question do you wish I would ask about longing for closeness?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2493,7 +2493,7 @@
"id": "emotional_intimacy_146", "id": "emotional_intimacy_146",
"category_id": "emotional_intimacy", "category_id": "emotional_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about the parts of yourself you protect?", "text": "What is one thing you want me to understand about the parts of yourself you protect?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [

View File

@ -5340,4 +5340,4 @@
] ]
} }
] ]
} }

View File

@ -5197,7 +5197,7 @@
"id": "future_244", "id": "future_244",
"category_id": "future", "category_id": "future",
"type": "this_or_that", "type": "this_or_that",
"text": "Which should we protect more?", "text": "Which would you choose first here: individual dreams or shared dreams?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5348,4 +5348,4 @@
] ]
} }
] ]
} }

View File

@ -1320,7 +1320,7 @@
"id": "gratitude_077", "id": "gratitude_077",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your emotional labor?", "text": "What feels hardest to explain about your emotional labor?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1405,7 +1405,7 @@
"id": "gratitude_082", "id": "gratitude_082",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your silent effort?", "text": "What would help me see your silent effort with more care?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1490,7 +1490,7 @@
"id": "gratitude_087", "id": "gratitude_087",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your personal sacrifices?", "text": "What do you want me to notice about your personal sacrifices?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1575,7 +1575,7 @@
"id": "gratitude_092", "id": "gratitude_092",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your growth we have made?", "text": "Where do you feel least understood around the growth we have made?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1660,7 +1660,7 @@
"id": "gratitude_097", "id": "gratitude_097",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your forgiveness?", "text": "What part of your forgiveness do you rarely get to say out loud?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1745,7 +1745,7 @@
"id": "gratitude_102", "id": "gratitude_102",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your support through stress?", "text": "How can I better honor what the support you give through stress brings up for you?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1830,7 +1830,7 @@
"id": "gratitude_107", "id": "gratitude_107",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your shared resilience?", "text": "What question do you wish I would ask about our shared resilience?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1915,7 +1915,7 @@
"id": "gratitude_112", "id": "gratitude_112",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your ways we repair?", "text": "What is one thing you want me to understand about the ways we repair?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2000,7 +2000,7 @@
"id": "gratitude_117", "id": "gratitude_117",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your daily dependability?", "text": "What feels hardest to explain about your daily dependability?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2085,7 +2085,7 @@
"id": "gratitude_122", "id": "gratitude_122",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your feeling chosen?", "text": "What would help me see feeling chosen with more care?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2170,7 +2170,7 @@
"id": "gratitude_127", "id": "gratitude_127",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your vulnerability?", "text": "What do you want me to notice about your vulnerability?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2255,7 +2255,7 @@
"id": "gratitude_132", "id": "gratitude_132",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your mutual effort?", "text": "Where do you feel least understood around our mutual effort?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2340,7 +2340,7 @@
"id": "gratitude_137", "id": "gratitude_137",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your a past hard season?", "text": "What part of a past hard season do you rarely get to say out loud?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2425,7 +2425,7 @@
"id": "gratitude_142", "id": "gratitude_142",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your unseen kindness?", "text": "How can I better honor what your unseen kindness brings up for you?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2510,7 +2510,7 @@
"id": "gratitude_147", "id": "gratitude_147",
"category_id": "gratitude", "category_id": "gratitude",
"type": "written", "type": "written",
"text": "What do you wish I understood about your future gratitude?", "text": "What question do you wish I would ask about future gratitude?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5145,7 +5145,7 @@
"id": "gratitude_242", "id": "gratitude_242",
"category_id": "gratitude", "category_id": "gratitude",
"type": "this_or_that", "type": "this_or_that",
"text": "Which is easier for you?", "text": "Which would you choose first here: giving gratitude or receiving gratitude?",
"depth": 2, "depth": 2,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5233,7 +5233,7 @@
"id": "gratitude_246", "id": "gratitude_246",
"category_id": "gratitude", "category_id": "gratitude",
"type": "this_or_that", "type": "this_or_that",
"text": "Which feels more loving?", "text": "Which would you choose first here: thank you for what you did or thank you for who you are?",
"depth": 3, "depth": 3,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5340,4 +5340,4 @@
] ]
} }
] ]
} }

View File

@ -2175,7 +2175,7 @@
"id": "home_life_133", "id": "home_life_133",
"category_id": "home_life", "category_id": "home_life",
"type": "written", "type": "written",
"text": "What do you need from me when plans change at home?", "text": "When plans change at home, what should I avoid doing?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3411,7 +3411,7 @@
"id": "home_life_183", "id": "home_life_183",
"category_id": "home_life", "category_id": "home_life",
"type": "single_choice", "type": "single_choice",
"text": "What helps you feel like we are a team?", "text": "Which answer fits best here: shared planning or shared tasks?",
"depth": 3, "depth": 3,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5229,4 +5229,4 @@
] ]
} }
] ]
} }

View File

@ -4234,7 +4234,7 @@
"id": "marriage_203", "id": "marriage_203",
"category_id": "marriage", "category_id": "marriage",
"type": "multi_choice", "type": "multi_choice",
"text": "What should we stop assuming?", "text": "Which answers fit best here: needs are the same or love is obvious?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5079,7 +5079,7 @@
"id": "marriage_239", "id": "marriage_239",
"category_id": "marriage", "category_id": "marriage",
"type": "this_or_that", "type": "this_or_that",
"text": "Which feels more romantic?", "text": "Which would you choose first here: surprise or consistency?",
"depth": 2, "depth": 2,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5211,7 +5211,7 @@
"id": "marriage_245", "id": "marriage_245",
"category_id": "marriage", "category_id": "marriage",
"type": "this_or_that", "type": "this_or_that",
"text": "Which should we practice more?", "text": "Which would you choose first here: apologizing sooner or listening longer?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5340,4 +5340,4 @@
] ]
} }
] ]
} }

View File

@ -5035,7 +5035,7 @@
"id": "parenting_237", "id": "parenting_237",
"category_id": "parenting", "category_id": "parenting",
"type": "this_or_that", "type": "this_or_that",
"text": "Which should we protect more?", "text": "Which fits this choice better for you: couple time or family routines?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5189,7 +5189,7 @@
"id": "parenting_244", "id": "parenting_244",
"category_id": "parenting", "category_id": "parenting",
"type": "this_or_that", "type": "this_or_that",
"text": "Which do we need more?", "text": "Which would you choose first here: rest or connection?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -5340,4 +5340,4 @@
] ]
} }
] ]
} }

View File

@ -1303,7 +1303,7 @@
"id": "physical_intimacy_076", "id": "physical_intimacy_076",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about touch preferences?", "text": "What is one thing you want me to understand about touch preferences?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1388,7 +1388,7 @@
"id": "physical_intimacy_081", "id": "physical_intimacy_081",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about physical boundaries?", "text": "What feels hardest to explain about physical boundaries?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1473,7 +1473,7 @@
"id": "physical_intimacy_086", "id": "physical_intimacy_086",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about different affection needs?", "text": "What would help me see different affection needs with more care?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1558,7 +1558,7 @@
"id": "physical_intimacy_091", "id": "physical_intimacy_091",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about touch after conflict?", "text": "What do you want me to notice about touch after conflict?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1643,7 +1643,7 @@
"id": "physical_intimacy_096", "id": "physical_intimacy_096",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about feeling desired without pressure?", "text": "Where do you feel least understood around feeling desired without pressure?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1728,7 +1728,7 @@
"id": "physical_intimacy_101", "id": "physical_intimacy_101",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about initiating affection?", "text": "What part of initiating affection do you rarely get to say out loud?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1813,7 +1813,7 @@
"id": "physical_intimacy_106", "id": "physical_intimacy_106",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about receiving affection?", "text": "How can I better honor what receiving affection brings up for you?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1898,7 +1898,7 @@
"id": "physical_intimacy_111", "id": "physical_intimacy_111",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about affection when stressed?", "text": "What question do you wish I would ask about affection when stressed?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1983,7 +1983,7 @@
"id": "physical_intimacy_116", "id": "physical_intimacy_116",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about body confidence?", "text": "What is one thing you want me to understand about body confidence?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2068,7 +2068,7 @@
"id": "physical_intimacy_121", "id": "physical_intimacy_121",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about consent and comfort?", "text": "What feels hardest to explain about consent and comfort?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2153,7 +2153,7 @@
"id": "physical_intimacy_126", "id": "physical_intimacy_126",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about physical closeness during hard seasons?", "text": "What would help me see physical closeness during hard seasons with more care?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2238,7 +2238,7 @@
"id": "physical_intimacy_131", "id": "physical_intimacy_131",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about repairing distance through affection?", "text": "What do you want me to notice about repairing distance through affection?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2323,7 +2323,7 @@
"id": "physical_intimacy_136", "id": "physical_intimacy_136",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about touch that feels emotionally meaningful?", "text": "Where do you feel least understood around touch that feels emotionally meaningful?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2408,7 +2408,7 @@
"id": "physical_intimacy_141", "id": "physical_intimacy_141",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about balancing affection and space?", "text": "What part of balancing affection and space do you rarely get to say out loud?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2493,7 +2493,7 @@
"id": "physical_intimacy_146", "id": "physical_intimacy_146",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "written", "type": "written",
"text": "What do you wish I understood about protecting physical intimacy from pressure?", "text": "How can I better honor what protecting physical intimacy from pressure brings up for you?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3474,306 +3474,6 @@
} }
] ]
}, },
{
"id": "physical_intimacy_181",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "For holding hands, what feels best to you?",
"depth": 3,
"access": "premium",
"tags": [
"holding_hands",
"preference"
],
"options": [
{
"id": "hand_holding",
"text": "Hand-holding"
},
{
"id": "cuddling",
"text": "Cuddling"
},
{
"id": "a_long_hug",
"text": "A long hug"
},
{
"id": "sitting_close",
"text": "Sitting close"
}
]
},
{
"id": "physical_intimacy_182",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "What would make cuddling feel safer?",
"depth": 3,
"access": "premium",
"tags": [
"cuddling",
"safety"
],
"options": [
{
"id": "ask_first",
"text": "Ask first"
},
{
"id": "move_slowly",
"text": "Move slowly"
},
{
"id": "use_clear_words",
"text": "Use clear words"
},
{
"id": "check_in_after",
"text": "Check in after"
}
]
},
{
"id": "physical_intimacy_183",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "How would you like more warm greetings?",
"depth": 2,
"access": "premium",
"tags": [
"warm_greetings",
"more"
],
"options": [
{
"id": "more_often",
"text": "More often"
},
{
"id": "more_gently",
"text": "More gently"
},
{
"id": "more_privately",
"text": "More privately"
},
{
"id": "more_playfully",
"text": "More playfully"
}
]
},
{
"id": "physical_intimacy_184",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "What does goodbye affection usually communicate to you?",
"depth": 2,
"access": "premium",
"tags": [
"goodbye_affection",
"meaning"
],
"options": [
{
"id": "comfort",
"text": "Comfort"
},
{
"id": "reassurance",
"text": "Reassurance"
},
{
"id": "connection",
"text": "Connection"
},
{
"id": "calm",
"text": "Calm"
}
]
},
{
"id": "physical_intimacy_185",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "Where do you prefer comforting touch?",
"depth": 3,
"access": "premium",
"tags": [
"comforting_touch",
"setting"
],
"options": [
{
"id": "public_affection",
"text": "Public affection"
},
{
"id": "private_affection",
"text": "Private affection"
},
{
"id": "both",
"text": "Both"
},
{
"id": "depends_on_the_setting",
"text": "Depends on the setting"
}
]
},
{
"id": "physical_intimacy_186",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "When sitting close feels uncertain, what should happen first?",
"depth": 3,
"access": "premium",
"tags": [
"sitting_close",
"consent"
],
"options": [
{
"id": "words_first",
"text": "Words first"
},
{
"id": "touch_first",
"text": "Touch first"
},
{
"id": "space_first",
"text": "Space first"
},
{
"id": "ask_first",
"text": "Ask first"
}
]
},
{
"id": "physical_intimacy_187",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "For nonverbal reassurance, what feels best to you?",
"depth": 3,
"access": "premium",
"tags": [
"nonverbal_reassurance",
"preference"
],
"options": [
{
"id": "hand_holding",
"text": "Hand-holding"
},
{
"id": "cuddling",
"text": "Cuddling"
},
{
"id": "a_long_hug",
"text": "A long hug"
},
{
"id": "sitting_close",
"text": "Sitting close"
}
]
},
{
"id": "physical_intimacy_188",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "What would make affection during stress feel safer?",
"depth": 2,
"access": "premium",
"tags": [
"affection_during_stress",
"safety"
],
"options": [
{
"id": "ask_first",
"text": "Ask first"
},
{
"id": "move_slowly",
"text": "Move slowly"
},
{
"id": "use_clear_words",
"text": "Use clear words"
},
{
"id": "check_in_after",
"text": "Check in after"
}
]
},
{
"id": "physical_intimacy_189",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "How would you like more gentle touch?",
"depth": 3,
"access": "premium",
"tags": [
"gentle_touch",
"more"
],
"options": [
{
"id": "more_often",
"text": "More often"
},
{
"id": "more_gently",
"text": "More gently"
},
{
"id": "more_privately",
"text": "More privately"
},
{
"id": "more_playfully",
"text": "More playfully"
}
]
},
{
"id": "physical_intimacy_190",
"category_id": "physical_intimacy",
"type": "single_choice",
"text": "What does feeling physically safe usually communicate to you?",
"depth": 3,
"access": "premium",
"tags": [
"feeling_physically_safe",
"meaning"
],
"options": [
{
"id": "comfort",
"text": "Comfort"
},
{
"id": "reassurance",
"text": "Reassurance"
},
{
"id": "connection",
"text": "Connection"
},
{
"id": "calm",
"text": "Calm"
}
]
},
{ {
"id": "physical_intimacy_191", "id": "physical_intimacy_191",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
@ -3914,7 +3614,7 @@
"id": "physical_intimacy_195", "id": "physical_intimacy_195",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "multi_choice", "type": "multi_choice",
"text": "Which kinds of touch help you feel close?", "text": "Which answers fit best here: public affection or private affection?",
"depth": 3, "depth": 3,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3948,7 +3648,7 @@
"id": "physical_intimacy_196", "id": "physical_intimacy_196",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "multi_choice", "type": "multi_choice",
"text": "Which things make physical affection feel safe?", "text": "Which answers fit best here: words first or touch first?",
"depth": 3, "depth": 3,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4050,7 +3750,7 @@
"id": "physical_intimacy_199", "id": "physical_intimacy_199",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "multi_choice", "type": "multi_choice",
"text": "Which kinds of touch help you feel close?", "text": "Which answers fit best here: more often or more gently?",
"depth": 3, "depth": 3,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4084,7 +3784,7 @@
"id": "physical_intimacy_200", "id": "physical_intimacy_200",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
"type": "multi_choice", "type": "multi_choice",
"text": "Which things make physical affection feel safe?", "text": "Which answers fit best here: comfort or reassurance?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4182,74 +3882,6 @@
"max_selections": 3 "max_selections": 3
} }
}, },
{
"id": "physical_intimacy_203",
"category_id": "physical_intimacy",
"type": "multi_choice",
"text": "Which kinds of touch help you feel close?",
"depth": 4,
"access": "premium",
"tags": [
"relaxing_together",
"touch_types"
],
"options": [
{
"id": "hand_holding",
"text": "Hand-holding"
},
{
"id": "cuddling",
"text": "Cuddling"
},
{
"id": "a_long_hug",
"text": "A long hug"
},
{
"id": "sitting_close",
"text": "Sitting close"
}
],
"answer_config": {
"min_selections": 1,
"max_selections": 3
}
},
{
"id": "physical_intimacy_204",
"category_id": "physical_intimacy",
"type": "multi_choice",
"text": "Which things make physical affection feel safe?",
"depth": 3,
"access": "premium",
"tags": [
"affection_in_public",
"safety"
],
"options": [
{
"id": "ask_first",
"text": "Ask first"
},
{
"id": "move_slowly",
"text": "Move slowly"
},
{
"id": "use_clear_words",
"text": "Use clear words"
},
{
"id": "check_in_after",
"text": "Check in after"
}
],
"answer_config": {
"min_selections": 1,
"max_selections": 3
}
},
{ {
"id": "physical_intimacy_205", "id": "physical_intimacy_205",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
@ -4318,74 +3950,6 @@
"max_selections": 3 "max_selections": 3
} }
}, },
{
"id": "physical_intimacy_207",
"category_id": "physical_intimacy",
"type": "multi_choice",
"text": "Which kinds of touch help you feel close?",
"depth": 3,
"access": "premium",
"tags": [
"physical_boundaries",
"touch_types"
],
"options": [
{
"id": "public_affection",
"text": "Public affection"
},
{
"id": "private_affection",
"text": "Private affection"
},
{
"id": "both",
"text": "Both"
},
{
"id": "depends_on_the_setting",
"text": "Depends on the setting"
}
],
"answer_config": {
"min_selections": 1,
"max_selections": 3
}
},
{
"id": "physical_intimacy_208",
"category_id": "physical_intimacy",
"type": "multi_choice",
"text": "Which things make physical affection feel safe?",
"depth": 3,
"access": "premium",
"tags": [
"different_affection_needs",
"safety"
],
"options": [
{
"id": "words_first",
"text": "Words first"
},
{
"id": "touch_first",
"text": "Touch first"
},
{
"id": "space_first",
"text": "Space first"
},
{
"id": "ask_first",
"text": "Ask first"
}
],
"answer_config": {
"min_selections": 1,
"max_selections": 3
}
},
{ {
"id": "physical_intimacy_209", "id": "physical_intimacy_209",
"category_id": "physical_intimacy", "category_id": "physical_intimacy",
@ -5260,4 +4824,4 @@
] ]
} }
] ]
} }

View File

@ -3598,7 +3598,7 @@
"id": "rebuilding_trust_211", "id": "rebuilding_trust_211",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when honesty after hurt feels fragile?", "text": "When honesty after hurt feels fragile, what reassurance helps most?",
"depth": 5, "depth": 5,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3615,7 +3615,7 @@
"id": "rebuilding_trust_212", "id": "rebuilding_trust_212",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when consistent actions feels fragile?", "text": "When consistent actions feel fragile, what would help you feel less alone?",
"depth": 4, "depth": 4,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3632,7 +3632,7 @@
"id": "rebuilding_trust_213", "id": "rebuilding_trust_213",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when transparency feels fragile?", "text": "When transparency feels fragile, what small action from me would matter?",
"depth": 5, "depth": 5,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3649,7 +3649,7 @@
"id": "rebuilding_trust_214", "id": "rebuilding_trust_214",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when emotional safety feels fragile?", "text": "When emotional safety feels fragile, what support from me would help most?",
"depth": 4, "depth": 4,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3666,7 +3666,7 @@
"id": "rebuilding_trust_215", "id": "rebuilding_trust_215",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when accountability feels fragile?", "text": "When accountability feels fragile, what should I do more of?",
"depth": 5, "depth": 5,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3683,7 +3683,7 @@
"id": "rebuilding_trust_216", "id": "rebuilding_trust_216",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when remorse feels fragile?", "text": "When remorse feels fragile, what should I avoid doing?",
"depth": 4, "depth": 4,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3700,7 +3700,7 @@
"id": "rebuilding_trust_217", "id": "rebuilding_trust_217",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when boundaries after rupture feels fragile?", "text": "When boundaries after rupture feel fragile, what reassurance helps most?",
"depth": 5, "depth": 5,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3717,7 +3717,7 @@
"id": "rebuilding_trust_218", "id": "rebuilding_trust_218",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when reassurance feels fragile?", "text": "When reassurance feels fragile, what would help you feel less alone?",
"depth": 4, "depth": 4,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3734,7 +3734,7 @@
"id": "rebuilding_trust_219", "id": "rebuilding_trust_219",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when patience feels fragile?", "text": "When patience feels fragile, what small action from me would matter?",
"depth": 5, "depth": 5,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3751,7 +3751,7 @@
"id": "rebuilding_trust_220", "id": "rebuilding_trust_220",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when triggered moments feels fragile?", "text": "When triggered moments feel fragile, what support from me would help most?",
"depth": 4, "depth": 4,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3768,7 +3768,7 @@
"id": "rebuilding_trust_221", "id": "rebuilding_trust_221",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when trust timelines feels fragile?", "text": "When trust timelines feel fragile, what should I do more of?",
"depth": 5, "depth": 5,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3785,7 +3785,7 @@
"id": "rebuilding_trust_222", "id": "rebuilding_trust_222",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when questions after betrayal feels fragile?", "text": "When questions after betrayal feel fragile, what should I avoid doing?",
"depth": 4, "depth": 4,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3802,7 +3802,7 @@
"id": "rebuilding_trust_223", "id": "rebuilding_trust_223",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when privacy after rupture feels fragile?", "text": "When privacy after rupture feels fragile, what reassurance helps most?",
"depth": 5, "depth": 5,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3819,7 +3819,7 @@
"id": "rebuilding_trust_224", "id": "rebuilding_trust_224",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when checking in feels fragile?", "text": "When checking in feels fragile, what would help you feel less alone?",
"depth": 4, "depth": 4,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3836,7 +3836,7 @@
"id": "rebuilding_trust_225", "id": "rebuilding_trust_225",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when making amends feels fragile?", "text": "When making amends feels fragile, what small action from me would matter?",
"depth": 5, "depth": 5,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3853,7 +3853,7 @@
"id": "rebuilding_trust_226", "id": "rebuilding_trust_226",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when trust deposits feels fragile?", "text": "When trust deposits feel fragile, what support from me would help most?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3870,7 +3870,7 @@
"id": "rebuilding_trust_227", "id": "rebuilding_trust_227",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when broken promises feels fragile?", "text": "When broken promises feel fragile, what should I do more of?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3887,7 +3887,7 @@
"id": "rebuilding_trust_228", "id": "rebuilding_trust_228",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when feeling believed feels fragile?", "text": "When feeling believed feels fragile, what should I avoid doing?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3904,7 +3904,7 @@
"id": "rebuilding_trust_229", "id": "rebuilding_trust_229",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when feeling chosen feels fragile?", "text": "When feeling chosen feels fragile, what reassurance helps most?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3921,7 +3921,7 @@
"id": "rebuilding_trust_230", "id": "rebuilding_trust_230",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when relationship agreements feels fragile?", "text": "When relationship agreements feel fragile, what would help you feel less alone?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3938,7 +3938,7 @@
"id": "rebuilding_trust_231", "id": "rebuilding_trust_231",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when defensiveness feels fragile?", "text": "When defensiveness feels fragile, what small action from me would matter?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3955,7 +3955,7 @@
"id": "rebuilding_trust_232", "id": "rebuilding_trust_232",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when shame feels fragile?", "text": "When shame feels fragile, what support from me would help most?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3972,7 +3972,7 @@
"id": "rebuilding_trust_233", "id": "rebuilding_trust_233",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when fear feels fragile?", "text": "When fear feels fragile, what should I do more of?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3989,7 +3989,7 @@
"id": "rebuilding_trust_234", "id": "rebuilding_trust_234",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when hope feels fragile?", "text": "When hope feels fragile, what should I avoid doing?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4006,7 +4006,7 @@
"id": "rebuilding_trust_235", "id": "rebuilding_trust_235",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when choosing repair feels fragile?", "text": "When choosing repair feels fragile, what reassurance helps most?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4023,7 +4023,7 @@
"id": "rebuilding_trust_236", "id": "rebuilding_trust_236",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when daily reliability feels fragile?", "text": "When daily reliability feels fragile, what would help you feel less alone?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4040,7 +4040,7 @@
"id": "rebuilding_trust_237", "id": "rebuilding_trust_237",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when financial honesty feels fragile?", "text": "When financial honesty feels fragile, what small action from me would matter?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4057,7 +4057,7 @@
"id": "rebuilding_trust_238", "id": "rebuilding_trust_238",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when digital transparency feels fragile?", "text": "When digital transparency feels fragile, what support from me would help most?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4074,7 +4074,7 @@
"id": "rebuilding_trust_239", "id": "rebuilding_trust_239",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when emotional availability feels fragile?", "text": "When emotional availability feels fragile, what should I do more of?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4091,7 +4091,7 @@
"id": "rebuilding_trust_240", "id": "rebuilding_trust_240",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What do you need from me when forgiveness pressure feels fragile?", "text": "When forgiveness pressure feels fragile, what should I avoid doing?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4125,7 +4125,7 @@
"id": "rebuilding_trust_242", "id": "rebuilding_trust_242",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What should we avoid doing when consistent actions feels fragile?", "text": "What should we avoid doing when consistent actions feel fragile?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4210,7 +4210,7 @@
"id": "rebuilding_trust_247", "id": "rebuilding_trust_247",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What should we avoid doing when boundaries after rupture feels fragile?", "text": "What should we avoid doing when boundaries after rupture feel fragile?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4261,7 +4261,7 @@
"id": "rebuilding_trust_250", "id": "rebuilding_trust_250",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What should we avoid doing when triggered moments feels fragile?", "text": "What should we avoid doing when triggered moments feel fragile?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4278,7 +4278,7 @@
"id": "rebuilding_trust_251", "id": "rebuilding_trust_251",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What should we avoid doing when trust timelines feels fragile?", "text": "What should we avoid doing when trust timelines feel fragile?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4295,7 +4295,7 @@
"id": "rebuilding_trust_252", "id": "rebuilding_trust_252",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What should we avoid doing when questions after betrayal feels fragile?", "text": "What should we avoid doing when questions after betrayal feel fragile?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4363,7 +4363,7 @@
"id": "rebuilding_trust_256", "id": "rebuilding_trust_256",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What should we avoid doing when trust deposits feels fragile?", "text": "What should we avoid doing when trust deposits feel fragile?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4380,7 +4380,7 @@
"id": "rebuilding_trust_257", "id": "rebuilding_trust_257",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What should we avoid doing when broken promises feels fragile?", "text": "What should we avoid doing when broken promises feel fragile?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4431,7 +4431,7 @@
"id": "rebuilding_trust_260", "id": "rebuilding_trust_260",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "written", "type": "written",
"text": "What should we avoid doing when relationship agreements feels fragile?", "text": "What should we avoid doing when relationship agreements feel fragile?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -7768,7 +7768,7 @@
"id": "rebuilding_trust_454", "id": "rebuilding_trust_454",
"category_id": "rebuilding_trust", "category_id": "rebuilding_trust",
"type": "single_choice", "type": "single_choice",
"text": "What makes accountability feel real?", "text": "Which answer fits best here: specific ownership or no excuses?",
"depth": 4, "depth": 4,
"access": "premium", "access": "premium",
"tags": [ "tags": [

View File

@ -1303,7 +1303,7 @@
"id": "sex_and_desire_076", "id": "sex_and_desire_076",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about different levels of desire?", "text": "What question do you wish I would ask about different levels of desire?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1388,7 +1388,7 @@
"id": "sex_and_desire_081", "id": "sex_and_desire_081",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about sexual communication?", "text": "What is one thing you want me to understand about sexual communication?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1473,7 +1473,7 @@
"id": "sex_and_desire_086", "id": "sex_and_desire_086",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about turn-ons and turn-offs?", "text": "What feels hardest to explain about turn-ons and turn-offs?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1558,7 +1558,7 @@
"id": "sex_and_desire_091", "id": "sex_and_desire_091",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about initiation preferences?", "text": "What would help me see initiation preferences with more care?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1643,7 +1643,7 @@
"id": "sex_and_desire_096", "id": "sex_and_desire_096",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about comfort with trying new things?", "text": "What do you want me to notice about comfort with trying new things?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1728,7 +1728,7 @@
"id": "sex_and_desire_101", "id": "sex_and_desire_101",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about sexual boundaries?", "text": "Where do you feel least understood around sexual boundaries?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1813,7 +1813,7 @@
"id": "sex_and_desire_106", "id": "sex_and_desire_106",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about desire during stress?", "text": "What part of desire during stress do you rarely get to say out loud?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1898,7 +1898,7 @@
"id": "sex_and_desire_111", "id": "sex_and_desire_111",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about body confidence during intimacy?", "text": "How can I better honor what body confidence during intimacy brings up for you?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -1983,7 +1983,7 @@
"id": "sex_and_desire_116", "id": "sex_and_desire_116",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about repair after rejection?", "text": "What question do you wish I would ask about repair after rejection?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2068,7 +2068,7 @@
"id": "sex_and_desire_121", "id": "sex_and_desire_121",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about sexual expectations?", "text": "What is one thing you want me to understand about sexual expectations?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2153,7 +2153,7 @@
"id": "sex_and_desire_126", "id": "sex_and_desire_126",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about frequency differences?", "text": "What feels hardest to explain about frequency differences?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2238,7 +2238,7 @@
"id": "sex_and_desire_131", "id": "sex_and_desire_131",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about emotional safety during intimacy?", "text": "What would help me see emotional safety during intimacy with more care?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2323,7 +2323,7 @@
"id": "sex_and_desire_136", "id": "sex_and_desire_136",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about pressure and consent?", "text": "What do you want me to notice about pressure and consent?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2408,7 +2408,7 @@
"id": "sex_and_desire_141", "id": "sex_and_desire_141",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about fantasy conversations?", "text": "Where do you feel least understood around fantasy conversations?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -2493,7 +2493,7 @@
"id": "sex_and_desire_146", "id": "sex_and_desire_146",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "written", "type": "written",
"text": "What do you wish I understood about protecting desire in long-term love?", "text": "What part of protecting desire in long-term love do you rarely get to say out loud?",
"depth": 5, "depth": 5,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -3474,306 +3474,6 @@
} }
] ]
}, },
{
"id": "sex_and_desire_181",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "For talking about desire respectfully, what would help most?",
"depth": 3,
"access": "premium",
"tags": [
"talking_about_desire_respectfully",
"support"
],
"options": [
{
"id": "gentle_words",
"text": "Gentle words"
},
{
"id": "clear_asking",
"text": "Clear asking"
},
{
"id": "playful_flirting",
"text": "Playful flirting"
},
{
"id": "quiet_closeness",
"text": "Quiet closeness"
}
]
},
{
"id": "sex_and_desire_182",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "How should we bring up feeling wanted?",
"depth": 3,
"access": "premium",
"tags": [
"feeling_wanted",
"communication"
],
"options": [
{
"id": "ask_directly",
"text": "Ask directly"
},
{
"id": "use_a_signal",
"text": "Use a signal"
},
{
"id": "talk_earlier",
"text": "Talk earlier"
},
{
"id": "check_in_later",
"text": "Check in later"
}
]
},
{
"id": "sex_and_desire_183",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "What should be centered when we discuss nonsexual closeness?",
"depth": 2,
"access": "premium",
"tags": [
"nonsexual_closeness",
"center"
],
"options": [
{
"id": "comfort",
"text": "Comfort"
},
{
"id": "curiosity",
"text": "Curiosity"
},
{
"id": "reassurance",
"text": "Reassurance"
},
{
"id": "no_pressure",
"text": "No pressure"
}
]
},
{
"id": "sex_and_desire_184",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "What would improve initiating intimacy kindly without adding pressure?",
"depth": 2,
"access": "premium",
"tags": [
"initiating_intimacy_kindly",
"improvement"
],
"options": [
{
"id": "more_romance",
"text": "More romance"
},
{
"id": "more_honesty",
"text": "More honesty"
},
{
"id": "more_patience",
"text": "More patience"
},
{
"id": "more_privacy",
"text": "More privacy"
}
]
},
{
"id": "sex_and_desire_185",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "What response matters most around responding to no with care?",
"depth": 3,
"access": "premium",
"tags": [
"responding_to_no_with_care",
"response"
],
"options": [
{
"id": "accept_no_kindly",
"text": "Accept no kindly"
},
{
"id": "ask_what_feels_good",
"text": "Ask what feels good"
},
{
"id": "slow_down",
"text": "Slow down"
},
{
"id": "talk_outside_the_moment",
"text": "Talk outside the moment"
}
]
},
{
"id": "sex_and_desire_186",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "What most supports desire around desire changing over time?",
"depth": 3,
"access": "premium",
"tags": [
"desire_changing_over_time",
"desire"
],
"options": [
{
"id": "emotional_closeness",
"text": "Emotional closeness"
},
{
"id": "rest",
"text": "Rest"
},
{
"id": "playfulness",
"text": "Playfulness"
},
{
"id": "feeling_desired",
"text": "Feeling desired"
}
]
},
{
"id": "sex_and_desire_187",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "For flirting in everyday life, what would help most?",
"depth": 3,
"access": "premium",
"tags": [
"flirting_in_everyday_life",
"support"
],
"options": [
{
"id": "gentle_words",
"text": "Gentle words"
},
{
"id": "clear_asking",
"text": "Clear asking"
},
{
"id": "playful_flirting",
"text": "Playful flirting"
},
{
"id": "quiet_closeness",
"text": "Quiet closeness"
}
]
},
{
"id": "sex_and_desire_188",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "How should we bring up feeling emotionally ready?",
"depth": 2,
"access": "premium",
"tags": [
"feeling_emotionally_ready",
"communication"
],
"options": [
{
"id": "ask_directly",
"text": "Ask directly"
},
{
"id": "use_a_signal",
"text": "Use a signal"
},
{
"id": "talk_earlier",
"text": "Talk earlier"
},
{
"id": "check_in_later",
"text": "Check in later"
}
]
},
{
"id": "sex_and_desire_189",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "What should be centered when we discuss privacy around intimacy?",
"depth": 3,
"access": "premium",
"tags": [
"privacy_around_intimacy",
"center"
],
"options": [
{
"id": "comfort",
"text": "Comfort"
},
{
"id": "curiosity",
"text": "Curiosity"
},
{
"id": "reassurance",
"text": "Reassurance"
},
{
"id": "no_pressure",
"text": "No pressure"
}
]
},
{
"id": "sex_and_desire_190",
"category_id": "sex_and_desire",
"type": "single_choice",
"text": "What would improve aftercare and reassurance without adding pressure?",
"depth": 3,
"access": "premium",
"tags": [
"aftercare_and_reassurance",
"improvement"
],
"options": [
{
"id": "more_romance",
"text": "More romance"
},
{
"id": "more_honesty",
"text": "More honesty"
},
{
"id": "more_patience",
"text": "More patience"
},
{
"id": "more_privacy",
"text": "More privacy"
}
]
},
{ {
"id": "sex_and_desire_191", "id": "sex_and_desire_191",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
@ -3914,7 +3614,7 @@
"id": "sex_and_desire_195", "id": "sex_and_desire_195",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "multi_choice", "type": "multi_choice",
"text": "Which things make sexual conversations feel safer?", "text": "Which answers fit best here: accept no kindly or ask what feels good?",
"depth": 3, "depth": 3,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4050,7 +3750,7 @@
"id": "sex_and_desire_199", "id": "sex_and_desire_199",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
"type": "multi_choice", "type": "multi_choice",
"text": "Which things make sexual conversations feel safer?", "text": "Which answers fit best here: comfort or curiosity?",
"depth": 3, "depth": 3,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4182,40 +3882,6 @@
"max_selections": 3 "max_selections": 3
} }
}, },
{
"id": "sex_and_desire_203",
"category_id": "sex_and_desire",
"type": "multi_choice",
"text": "Which things make sexual conversations feel safer?",
"depth": 4,
"access": "premium",
"tags": [
"reducing_pressure",
"safety"
],
"options": [
{
"id": "gentle_words",
"text": "Gentle words"
},
{
"id": "clear_asking",
"text": "Clear asking"
},
{
"id": "playful_flirting",
"text": "Playful flirting"
},
{
"id": "quiet_closeness",
"text": "Quiet closeness"
}
],
"answer_config": {
"min_selections": 1,
"max_selections": 3
}
},
{ {
"id": "sex_and_desire_204", "id": "sex_and_desire_204",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
@ -4318,40 +3984,6 @@
"max_selections": 3 "max_selections": 3
} }
}, },
{
"id": "sex_and_desire_207",
"category_id": "sex_and_desire",
"type": "multi_choice",
"text": "Which things make sexual conversations feel safer?",
"depth": 3,
"access": "premium",
"tags": [
"sexual_communication",
"safety"
],
"options": [
{
"id": "accept_no_kindly",
"text": "Accept no kindly"
},
{
"id": "ask_what_feels_good",
"text": "Ask what feels good"
},
{
"id": "slow_down",
"text": "Slow down"
},
{
"id": "talk_outside_the_moment",
"text": "Talk outside the moment"
}
],
"answer_config": {
"min_selections": 1,
"max_selections": 3
}
},
{ {
"id": "sex_and_desire_208", "id": "sex_and_desire_208",
"category_id": "sex_and_desire", "category_id": "sex_and_desire",
@ -5260,4 +4892,4 @@
] ]
} }
] ]
} }

View File

@ -79,7 +79,7 @@
"id": "stress_004", "id": "stress_004",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about work stress?", "text": "How can I better honor what work stress brings up for you?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -164,7 +164,7 @@
"id": "stress_009", "id": "stress_009",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about feeling overwhelmed?", "text": "What question do you wish I would ask about feeling overwhelmed?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -249,7 +249,7 @@
"id": "stress_014", "id": "stress_014",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about needing rest?", "text": "What is one thing you want me to understand about needing rest?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -334,7 +334,7 @@
"id": "stress_019", "id": "stress_019",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about asking for help?", "text": "What feels hardest to explain about asking for help?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -419,7 +419,7 @@
"id": "stress_024", "id": "stress_024",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about low energy days?", "text": "What would help me see low energy days with more care?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -504,7 +504,7 @@
"id": "stress_029", "id": "stress_029",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about mental load?", "text": "What do you want me to notice about mental load?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -589,7 +589,7 @@
"id": "stress_034", "id": "stress_034",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about unexpected problems?", "text": "Where do you feel least understood around unexpected problems?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -674,7 +674,7 @@
"id": "stress_039", "id": "stress_039",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about sleep and mood?", "text": "What part of sleep and mood do you rarely get to say out loud?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -759,7 +759,7 @@
"id": "stress_044", "id": "stress_044",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about busy weeks?", "text": "How can I better honor what busy weeks brings up for you?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -844,7 +844,7 @@
"id": "stress_049", "id": "stress_049",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about feeling supported?", "text": "What question do you wish I would ask about feeling supported?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -929,7 +929,7 @@
"id": "stress_054", "id": "stress_054",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about financial pressure?", "text": "What is one thing you want me to understand about financial pressure?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -1014,7 +1014,7 @@
"id": "stress_059", "id": "stress_059",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about family pressure?", "text": "What feels hardest to explain about family pressure?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -1099,7 +1099,7 @@
"id": "stress_064", "id": "stress_064",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about health worries?", "text": "What would help me see health worries with more care?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -1184,7 +1184,7 @@
"id": "stress_069", "id": "stress_069",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about burnout signs?", "text": "What do you want me to notice about burnout signs?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -1269,7 +1269,7 @@
"id": "stress_074", "id": "stress_074",
"category_id": "stress", "category_id": "stress",
"type": "written", "type": "written",
"text": "What do you wish I understood about resetting after stress?", "text": "Where do you feel least understood around resetting after stress?",
"depth": 3, "depth": 3,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -3474,306 +3474,6 @@
} }
] ]
}, },
{
"id": "stress_181",
"category_id": "stress",
"type": "single_choice",
"text": "When work stress shows up, what usually helps first?",
"depth": 3,
"access": "premium",
"tags": [
"work_stress",
"support"
],
"options": [
{
"id": "comfort",
"text": "Comfort"
},
{
"id": "practical_help",
"text": "Practical help"
},
{
"id": "quiet_space",
"text": "Quiet space"
},
{
"id": "encouragement",
"text": "Encouragement"
}
]
},
{
"id": "stress_182",
"category_id": "stress",
"type": "single_choice",
"text": "What kind of help feels best during feeling overwhelmed?",
"depth": 3,
"access": "premium",
"tags": [
"feeling_overwhelmed",
"help"
],
"options": [
{
"id": "a_hug",
"text": "A hug"
},
{
"id": "a_plan",
"text": "A plan"
},
{
"id": "a_break",
"text": "A break"
},
{
"id": "a_check_in",
"text": "A check-in"
}
]
},
{
"id": "stress_183",
"category_id": "stress",
"type": "single_choice",
"text": "How should we handle a serious talk when needing rest is high?",
"depth": 2,
"access": "premium",
"tags": [
"needing_rest",
"timing"
],
"options": [
{
"id": "talk_now",
"text": "Talk now"
},
{
"id": "talk_later",
"text": "Talk later"
},
{
"id": "write_it_down",
"text": "Write it down"
},
{
"id": "do_something_calming",
"text": "Do something calming"
}
]
},
{
"id": "stress_184",
"category_id": "stress",
"type": "single_choice",
"text": "What do you need me to do less when asking for help is present?",
"depth": 2,
"access": "premium",
"tags": [
"asking_for_help",
"less"
],
"options": [
{
"id": "listen",
"text": "Listen"
},
{
"id": "help_decide",
"text": "Help decide"
},
{
"id": "take_a_task",
"text": "Take a task"
},
{
"id": "give_reassurance",
"text": "Give reassurance"
}
]
},
{
"id": "stress_185",
"category_id": "stress",
"type": "single_choice",
"text": "What reset helps after low energy days?",
"depth": 3,
"access": "premium",
"tags": [
"low_energy_days",
"reset"
],
"options": [
{
"id": "rest",
"text": "Rest"
},
{
"id": "movement",
"text": "Movement"
},
{
"id": "food",
"text": "Food"
},
{
"id": "less_noise",
"text": "Less noise"
}
]
},
{
"id": "stress_186",
"category_id": "stress",
"type": "single_choice",
"text": "What should be our first move when mental load affects us?",
"depth": 3,
"access": "premium",
"tags": [
"mental_load",
"first_move"
],
"options": [
{
"id": "name_it_early",
"text": "Name it early"
},
{
"id": "pause_conflict",
"text": "Pause conflict"
},
{
"id": "lower_expectations",
"text": "Lower expectations"
},
{
"id": "ask_for_help",
"text": "Ask for help"
}
]
},
{
"id": "stress_187",
"category_id": "stress",
"type": "single_choice",
"text": "When unexpected problems shows up, what usually helps first?",
"depth": 3,
"access": "premium",
"tags": [
"unexpected_problems",
"support"
],
"options": [
{
"id": "comfort",
"text": "Comfort"
},
{
"id": "practical_help",
"text": "Practical help"
},
{
"id": "quiet_space",
"text": "Quiet space"
},
{
"id": "encouragement",
"text": "Encouragement"
}
]
},
{
"id": "stress_188",
"category_id": "stress",
"type": "single_choice",
"text": "What kind of help feels best during sleep and mood?",
"depth": 2,
"access": "premium",
"tags": [
"sleep_and_mood",
"help"
],
"options": [
{
"id": "a_hug",
"text": "A hug"
},
{
"id": "a_plan",
"text": "A plan"
},
{
"id": "a_break",
"text": "A break"
},
{
"id": "a_check_in",
"text": "A check-in"
}
]
},
{
"id": "stress_189",
"category_id": "stress",
"type": "single_choice",
"text": "How should we handle a serious talk when busy weeks is high?",
"depth": 3,
"access": "premium",
"tags": [
"busy_weeks",
"timing"
],
"options": [
{
"id": "talk_now",
"text": "Talk now"
},
{
"id": "talk_later",
"text": "Talk later"
},
{
"id": "write_it_down",
"text": "Write it down"
},
{
"id": "do_something_calming",
"text": "Do something calming"
}
]
},
{
"id": "stress_190",
"category_id": "stress",
"type": "single_choice",
"text": "What do you need me to do less when feeling supported is present?",
"depth": 3,
"access": "premium",
"tags": [
"feeling_supported",
"less"
],
"options": [
{
"id": "listen",
"text": "Listen"
},
{
"id": "help_decide",
"text": "Help decide"
},
{
"id": "take_a_task",
"text": "Take a task"
},
{
"id": "give_reassurance",
"text": "Give reassurance"
}
]
},
{ {
"id": "stress_191", "id": "stress_191",
"category_id": "stress", "category_id": "stress",

View File

@ -514,7 +514,7 @@
"id": "trust_031", "id": "trust_031",
"category_id": "trust", "category_id": "trust",
"type": "written", "type": "written",
"text": "What do you need from me when you feel jealous?", "text": "When you feel jealous, what reassurance helps most?",
"depth": 4, "depth": 4,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -530,7 +530,7 @@
"id": "trust_032", "id": "trust_032",
"category_id": "trust", "category_id": "trust",
"type": "written", "type": "written",
"text": "What do you need from me when I feel jealous?", "text": "When I feel jealous, what would help you feel less alone?",
"depth": 4, "depth": 4,
"access": "free", "access": "free",
"tags": [ "tags": [
@ -2846,7 +2846,7 @@
"id": "trust_164", "id": "trust_164",
"category_id": "trust", "category_id": "trust",
"type": "single_choice", "type": "single_choice",
"text": "What makes you feel chosen?", "text": "Which answer fits best here: quality time or public respect?",
"depth": 2, "depth": 2,
"access": "premium", "access": "premium",
"tags": [ "tags": [
@ -4431,25 +4431,6 @@
"scale_step": 1 "scale_step": 1
} }
}, },
{
"id": "trust_212",
"category_id": "trust",
"type": "scale",
"text": "How emotionally safe do you feel with me right now?",
"depth": 3,
"access": "premium",
"tags": [
"emotional_safety",
"security"
],
"answer_config": {
"min_scale": 1,
"max_scale": 5,
"min_label": "Not safe",
"max_label": "Very safe",
"scale_step": 1
}
},
{ {
"id": "trust_213", "id": "trust_213",
"category_id": "trust", "category_id": "trust",

View File

@ -3474,306 +3474,6 @@
} }
] ]
}, },
{
"id": "values_181",
"category_id": "values",
"type": "single_choice",
"text": "What would help us make decisions about respect in everyday choices?",
"depth": 3,
"access": "premium",
"tags": [
"respect_in_everyday_choices",
"decisions"
],
"options": [
{
"id": "talk_it_through",
"text": "Talk it through"
},
{
"id": "make_a_shared_rule",
"text": "Make a shared rule"
},
{
"id": "try_it_for_a_month",
"text": "Try it for a month"
},
{
"id": "pause_and_revisit",
"text": "Pause and revisit"
}
]
},
{
"id": "values_182",
"category_id": "values",
"type": "single_choice",
"text": "How aligned do you feel we are about honesty about needs?",
"depth": 3,
"access": "premium",
"tags": [
"honesty_about_needs",
"alignment"
],
"options": [
{
"id": "very_aligned",
"text": "Very aligned"
},
{
"id": "mostly_aligned",
"text": "Mostly aligned"
},
{
"id": "unsure",
"text": "Unsure"
},
{
"id": "different_but_workable",
"text": "Different but workable"
}
]
},
{
"id": "values_183",
"category_id": "values",
"type": "single_choice",
"text": "Which value matters most when we talk about how we spend time?",
"depth": 2,
"access": "premium",
"tags": [
"how_we_spend_time",
"priority"
],
"options": [
{
"id": "respect",
"text": "Respect"
},
{
"id": "honesty",
"text": "Honesty"
},
{
"id": "freedom",
"text": "Freedom"
},
{
"id": "security",
"text": "Security"
}
]
},
{
"id": "values_184",
"category_id": "values",
"type": "single_choice",
"text": "What should we protect when kindness under stress gets complicated?",
"depth": 2,
"access": "premium",
"tags": [
"kindness_under_stress",
"protection"
],
"options": [
{
"id": "family",
"text": "Family"
},
{
"id": "work",
"text": "Work"
},
{
"id": "health",
"text": "Health"
},
{
"id": "connection",
"text": "Connection"
}
]
},
{
"id": "values_185",
"category_id": "values",
"type": "single_choice",
"text": "What would make family priorities easier to discuss?",
"depth": 3,
"access": "premium",
"tags": [
"family_priorities",
"discussion"
],
"options": [
{
"id": "ask_more_questions",
"text": "Ask more questions"
},
{
"id": "share_examples",
"text": "Share examples"
},
{
"id": "name_the_tradeoff",
"text": "Name the tradeoff"
},
{
"id": "set_a_boundary",
"text": "Set a boundary"
}
]
},
{
"id": "values_186",
"category_id": "values",
"type": "single_choice",
"text": "What do you usually need first when personal growth feels uncertain?",
"depth": 3,
"access": "premium",
"tags": [
"personal_growth",
"needs"
],
"options": [
{
"id": "i_need_time",
"text": "I need time"
},
{
"id": "i_need_clarity",
"text": "I need clarity"
},
{
"id": "i_need_reassurance",
"text": "I need reassurance"
},
{
"id": "i_need_a_plan",
"text": "I need a plan"
}
]
},
{
"id": "values_187",
"category_id": "values",
"type": "single_choice",
"text": "What would help us make decisions about fairness in decisions?",
"depth": 3,
"access": "premium",
"tags": [
"fairness_in_decisions",
"decisions"
],
"options": [
{
"id": "talk_it_through",
"text": "Talk it through"
},
{
"id": "make_a_shared_rule",
"text": "Make a shared rule"
},
{
"id": "try_it_for_a_month",
"text": "Try it for a month"
},
{
"id": "pause_and_revisit",
"text": "Pause and revisit"
}
]
},
{
"id": "values_188",
"category_id": "values",
"type": "single_choice",
"text": "How aligned do you feel we are about how we show commitment?",
"depth": 2,
"access": "premium",
"tags": [
"how_we_show_commitment",
"alignment"
],
"options": [
{
"id": "very_aligned",
"text": "Very aligned"
},
{
"id": "mostly_aligned",
"text": "Mostly aligned"
},
{
"id": "unsure",
"text": "Unsure"
},
{
"id": "different_but_workable",
"text": "Different but workable"
}
]
},
{
"id": "values_189",
"category_id": "values",
"type": "single_choice",
"text": "Which value matters most when we talk about privacy and openness?",
"depth": 3,
"access": "premium",
"tags": [
"privacy_and_openness",
"priority"
],
"options": [
{
"id": "respect",
"text": "Respect"
},
{
"id": "honesty",
"text": "Honesty"
},
{
"id": "freedom",
"text": "Freedom"
},
{
"id": "security",
"text": "Security"
}
]
},
{
"id": "values_190",
"category_id": "values",
"type": "single_choice",
"text": "What should we protect when helping other people gets complicated?",
"depth": 3,
"access": "premium",
"tags": [
"helping_other_people",
"protection"
],
"options": [
{
"id": "family",
"text": "Family"
},
{
"id": "work",
"text": "Work"
},
{
"id": "health",
"text": "Health"
},
{
"id": "connection",
"text": "Connection"
}
]
},
{ {
"id": "values_191", "id": "values_191",
"category_id": "values", "category_id": "values",
@ -5260,4 +4960,4 @@
] ]
} }
] ]
} }

View File

@ -0,0 +1,141 @@
#!/usr/bin/env python3
"""
Validate question-bank variety before building the bundled database.
Checks:
* no exact duplicate visible question text
* heavily templated stems stay below a configured cap
Run from the repo root:
python3 seed/validate_question_variety.py
"""
from __future__ import annotations
import argparse
import json
import os
import re
import sqlite3
import sys
from collections import defaultdict
from dataclasses import dataclass
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
QUESTIONS_DIR = ROOT / "seed" / "questions"
DB_PATH = ROOT / "app" / "src" / "main" / "assets" / "database" / "app.db"
MAX_TEMPLATE_STEM_ROWS = 25
TEMPLATE_STEMS = (
"what do you wish i understood about",
"what do you need from me when",
)
@dataclass(frozen=True)
class QuestionRecord:
id: str
text: str
source: str
def normalize_text(text: str) -> str:
lowered = text.strip().lower()
lowered = re.sub(r"\s+", " ", lowered)
lowered = re.sub(r"[^\w\s']", "", lowered)
return lowered
def matching_stem(normalized_text: str) -> str | None:
for stem in TEMPLATE_STEMS:
if normalized_text.startswith(stem):
return stem
return None
def load_json_records(questions_dir: Path) -> list[QuestionRecord]:
records: list[QuestionRecord] = []
for path in sorted(questions_dir.glob("*.json")):
with path.open() as f:
data = json.load(f)
for q in data.get("questions", []):
text = q.get("text", "")
if text:
records.append(QuestionRecord(q["id"], text, str(path.relative_to(ROOT))))
return records
def load_db_records(db_path: Path) -> list[QuestionRecord]:
if not db_path.exists():
return []
con = sqlite3.connect(db_path)
try:
rows = con.execute(
"SELECT id, text FROM question WHERE status='active' AND text<>'' ORDER BY id"
).fetchall()
finally:
con.close()
return [QuestionRecord(qid, text, str(db_path.relative_to(ROOT))) for qid, text in rows]
def validate_records(records: list[QuestionRecord], label: str) -> list[str]:
errors: list[str] = []
by_text: dict[str, list[QuestionRecord]] = defaultdict(list)
by_stem: dict[str, list[QuestionRecord]] = defaultdict(list)
for record in records:
normalized = normalize_text(record.text)
by_text[normalized].append(record)
stem = matching_stem(normalized)
if stem:
by_stem[stem].append(record)
duplicates = {text: items for text, items in by_text.items() if len(items) > 1}
if duplicates:
extra_count = sum(len(items) - 1 for items in duplicates.values())
errors.append(f"{label}: {extra_count} duplicate visible question texts")
for _, items in sorted(duplicates.items(), key=lambda item: (-len(item[1]), item[0]))[:10]:
ids = ", ".join(record.id for record in items[:6])
if len(items) > 6:
ids += ", ..."
errors.append(f" {len(items)}x {items[0].text!r} ({ids})")
for stem, items in sorted(by_stem.items()):
if len(items) > MAX_TEMPLATE_STEM_ROWS:
errors.append(
f"{label}: stem {stem!r} appears {len(items)} times "
f"(max {MAX_TEMPLATE_STEM_ROWS})"
)
sample_ids = ", ".join(record.id for record in items[:8])
errors.append(f" sample ids: {sample_ids}")
return errors
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--json-only", action="store_true", help="Skip validating the asset DB")
args = parser.parse_args()
checks = [("JSON", load_json_records(QUESTIONS_DIR))]
if not args.json_only:
db_records = load_db_records(DB_PATH)
if db_records:
checks.append(("DB", db_records))
errors: list[str] = []
for label, records in checks:
errors.extend(validate_records(records, label))
if errors:
print("Question variety check failed:")
print("\n".join(errors))
return 1
print("Question variety check passed")
return 0
if __name__ == "__main__":
sys.exit(main())