Files
Keysat 6816d4a4f0 Realign stale thesis tests to the 7-member positioning group
ensure_positioning_framings adds 5 Architect framings to the core
positioning variant group alongside Option A/B, so the group holds 7
candidates and choose_variant retires 6. The two thesis tests still
asserted the pre-framings count of 2 — the tests were stale, not the
seed. Realign them, document the 2+5=7 seed structure in the thesis
guide, and refresh AGENTS.md Current state (13/13 tests green).
2026-06-12 18:44:14 -05:00

84 lines
3.6 KiB
Python

#!/usr/bin/env python3
"""Offline test for the v5 thesis seed (init_db auto-seed + idempotency).
Runs the real init_db against a throwaway DB (applies migration 0002 and the
auto-seed), then asserts the Workshop substrate: a core line, one line per segment,
the positioning variant group (Option A/B banner + the 5 Architect framings seeded
by ensure_positioning_framings), the pillars/proof, and the segments table — and
that re-seeding is a no-op.
Run: cd backend && python3 test_thesis_seed.py
"""
import os
import sqlite3
import sys
import tempfile
_tmp = tempfile.mkdtemp()
os.environ["CRM_DATA_DIR"] = _tmp
os.environ["CRM_DB_PATH"] = os.path.join(_tmp, "crm.db")
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import server # noqa: E402
import thesis_seed # noqa: E402
FAILS = []
def check(cond, msg):
print((" PASS " if cond else " FAIL ") + msg)
if not cond:
FAILS.append(msg)
def main():
server.init_db()
conn = sqlite3.connect(server.DB_PATH)
conn.row_factory = sqlite3.Row
lines = {r["line_key"]: dict(r) for r in conn.execute("SELECT * FROM thesis_lines WHERE deleted_at IS NULL")}
check("core" in lines and lines["core"]["is_core"] == 1, "core thesis line seeded (is_core)")
seg_lines = [k for k in lines if k.startswith("seg_")]
check(len(seg_lines) == 5, f"five per-segment lines seeded (got {len(seg_lines)}: {sorted(seg_lines)})")
check(len(lines) == 6, f"exactly 6 lines total (got {len(lines)})")
core_id = lines["core"]["id"]
nodes = [dict(r) for r in conn.execute("SELECT * FROM thesis_nodes WHERE line_id=?", (core_id,))]
types = [n["node_type"] for n in nodes]
check("throughline" in types, "core has a throughline node")
check("proof_point" in types, "core has a proof_point node")
variants = [n for n in nodes if n["variant_group"] == "positioning"]
banner = [n for n in variants if (n["title"] or "").startswith(("Option A", "Option B"))]
framings = [n for n in variants if "(Architect," in (n["title"] or "")]
check(len(banner) == 2, f"Option A/B banner present in positioning group (got {len(banner)})")
check(len(framings) == 5, f"five Architect positioning framings seeded into the group (got {len(framings)})")
check(len(variants) == 7, f"positioning variant group = Option A/B + 5 framings = 7 (got {len(variants)})")
pillars = [n for n in nodes if n["node_type"] == "claim" and n["title"] and n["title"][0] in "123"]
check(len(pillars) == 3, f"three pillar claims (got {len(pillars)})")
segs = {r["segment_key"] for r in conn.execute("SELECT segment_key FROM segments WHERE status='active'")}
check(segs == {"btc_native_hnwi", "institution", "family_office", "smaller_accredited", "ai_energy_operator"},
f"five active segments (got {sorted(segs)})")
# segment lines each carry a segment_cut angle
cut = conn.execute("""SELECT COUNT(*) FROM thesis_nodes n JOIN thesis_lines l ON l.id=n.line_id
WHERE n.node_type='segment_cut' AND l.line_key LIKE 'seg_%'""").fetchone()[0]
check(cut == 5, f"each segment line has a segment_cut angle (got {cut})")
# idempotency: re-seeding does nothing (thesis not empty)
thesis_seed.ensure_thesis_seed(conn)
conn.commit()
n2 = conn.execute("SELECT COUNT(*) FROM thesis_lines WHERE deleted_at IS NULL").fetchone()[0]
check(n2 == 6, f"re-seed is a no-op when thesis already exists (got {n2})")
conn.close()
print()
if FAILS:
print(f"FAILED ({len(FAILS)})")
sys.exit(1)
print("ALL PASS (v5 thesis seed)")
if __name__ == "__main__":
main()