196f1f6c65
Saves the 2026-06-05 Architect positioning pass as competing CANDIDATE options under the core line's positioning variant group, beside Option A/B: Convergence (47/60), Access (40), Asymmetry (36), Scarcity/chokepoints (35), Freedom-tech (28), each with its red-team weakness inline. One-time, additive, non-canonical (guardrail #4); idempotent via an interaction_log sentinel so a partner-deleted option is never resurrected. ensure_positioning_framings runs after the v5 seed. Test: test_positioning_framings.py (count/candidacy/idempotency/no-resurrection/log). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
78 lines
3.4 KiB
Python
78 lines
3.4 KiB
Python
#!/usr/bin/env python3
|
|
"""Test the one-time Architect positioning-framings seed (thesis_seed.ensure_positioning_framings).
|
|
|
|
Verifies: the 5 framings land as CANDIDATE options under the core line's positioning
|
|
variant group (beside Option A/B); the insert is idempotent; an interaction_log sentinel
|
|
prevents resurrection after a partner soft-deletes one; and per-framing + sentinel audit
|
|
rows are written. Synthetic schema only (guardrail #9). Run: cd backend && python3 test_positioning_framings.py
|
|
"""
|
|
import os
|
|
import sqlite3
|
|
import sys
|
|
import tempfile
|
|
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
import thesis_seed as ts # noqa: E402
|
|
|
|
SCHEMA = """
|
|
CREATE TABLE thesis_lines (id TEXT PRIMARY KEY, line_key TEXT, name TEXT, segment_key TEXT, is_core INT, description TEXT, created_at TEXT, updated_at TEXT, deleted_at TEXT);
|
|
CREATE TABLE thesis_nodes (id TEXT PRIMARY KEY, line_id TEXT, parent_id TEXT, node_type TEXT, ord REAL, title TEXT, body TEXT, status TEXT, variant_group TEXT, created_at TEXT, updated_at TEXT, deleted_at TEXT);
|
|
CREATE TABLE segments (id TEXT PRIMARY KEY, segment_key TEXT, name TEXT, definition TEXT, needs_to_hear TEXT, avoid TEXT, version_no INT, status TEXT, created_at TEXT, updated_at TEXT);
|
|
CREATE TABLE interaction_log (id TEXT PRIMARY KEY, ts TEXT, actor_type TEXT, actor_id TEXT, action TEXT, target_type TEXT, target_id TEXT, payload TEXT, source TEXT, created_at TEXT);
|
|
"""
|
|
|
|
FAILS = []
|
|
|
|
|
|
def check(cond, msg):
|
|
print((" PASS " if cond else " FAIL ") + msg)
|
|
if not cond:
|
|
FAILS.append(msg)
|
|
|
|
|
|
def positioning(conn):
|
|
return conn.execute(
|
|
"SELECT title, status FROM thesis_nodes WHERE variant_group='positioning' AND deleted_at IS NULL ORDER BY ord"
|
|
).fetchall()
|
|
|
|
|
|
def main():
|
|
db = os.path.join(tempfile.mkdtemp(), "t.db")
|
|
conn = sqlite3.connect(db)
|
|
conn.executescript(SCHEMA)
|
|
conn.commit()
|
|
|
|
ts.ensure_thesis_seed(conn) # core line + Option A/B + segments
|
|
ts.ensure_positioning_framings(conn) # + 5 Architect framings
|
|
|
|
opts = positioning(conn)
|
|
check(len(opts) == 7, f"7 positioning options after seed (A,B + 5 framings), got {len(opts)}")
|
|
check(all(s == "candidate" for _, s in opts), "every positioning option is candidate (nothing canonical)")
|
|
check(sum("Architect" in t for t, _ in opts) == 5, "exactly 5 Architect framings inserted")
|
|
|
|
ts.ensure_positioning_framings(conn) # idempotent
|
|
check(len(positioning(conn)) == 7, "second run adds nothing (idempotent)")
|
|
|
|
# a partner soft-deletes one framing; a restart must NOT resurrect it
|
|
conn.execute("UPDATE thesis_nodes SET deleted_at='x' WHERE title LIKE 'Option C%'")
|
|
conn.commit()
|
|
ts.ensure_positioning_framings(conn)
|
|
check(len(positioning(conn)) == 6, "soft-deleted framing is not resurrected on re-run (sentinel guard)")
|
|
|
|
sentinel = conn.execute("SELECT COUNT(*) FROM interaction_log WHERE action='thesis.positioning_framings_seeded'").fetchone()[0]
|
|
perframe = conn.execute("SELECT COUNT(*) FROM interaction_log WHERE action='thesis.framing_seeded'").fetchone()[0]
|
|
check(sentinel == 1, f"exactly one sentinel row (got {sentinel})")
|
|
check(perframe == 5, f"one audit row per framing (got {perframe})")
|
|
|
|
conn.close()
|
|
if FAILS:
|
|
print(f"\nFAILED ({len(FAILS)})")
|
|
for f in FAILS:
|
|
print(" - " + f)
|
|
sys.exit(1)
|
|
print("\nALL PASS (positioning framings seed)")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|