From aadfccf32d17a3f6d2e84e40e407077de96748bd Mon Sep 17 00:00:00 2001 From: Ben Stull Date: Fri, 5 Jun 2026 03:41:35 -0700 Subject: [PATCH] feat(simulator): deterministic synthetic fixture catalog Per docs/superpowers/plans/2026-06-04-experience-simulator.md Task 3. Co-Authored-By: Claude Opus 4.8 (1M context) --- simulator/fixtures.py | 59 ++++++++++++++++++++++++++++++++++++++++++ tests/test_fixtures.py | 40 ++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) create mode 100644 simulator/fixtures.py create mode 100644 tests/test_fixtures.py diff --git a/simulator/fixtures.py b/simulator/fixtures.py new file mode 100644 index 0000000..1d83344 --- /dev/null +++ b/simulator/fixtures.py @@ -0,0 +1,59 @@ +"""Deterministic synthetic catalog so the selection model can be felt everywhere. + +The real catalog (catalog/library.jsonl) is empty; this generates one record per +cell of the 5x5 brain x 5x5 mood coordinate space (625 records), with a seeded +mix of content modes and review statuses and no real media attached. +""" + +from __future__ import annotations + +import random + +from hef.catalog import Record + +MODES = ("audio", "video", "av") +ARCHIVES = ("internet_archive", "musopen", "librivox", "nasa", "freesound") + +_LEFT_WORDS = ("Treatise", "Lecture", "Field Notes", "Reading", "Documentary") +_RIGHT_WORDS = ("Reverie", "Nocturne", "Bloom", "Drift", "Aurora") + + +def _title(left: int, right: int, dark: int, light: int, mode: str) -> str: + a = _LEFT_WORDS[left] if left >= right else _RIGHT_WORDS[right] + return f"{a} ({mode}) L{left}R{right}D{dark}Li{light}" + + +def generate_fixture_catalog(seed: int = 1729) -> list[Record]: + """One valid Record per coordinate cell (625 total), deterministic for a seed.""" + rng = random.Random(seed) + records: list[Record] = [] + n = 0 + for left in range(5): + for right in range(5): + for dark in range(5): + for light in range(5): + mode = rng.choice(MODES) + status = rng.choice(("proposed", "approved")) + is_video = mode in ("video", "av") + records.append( + Record( + id=f"fx-{n:04d}", + title=_title(left, right, dark, light, mode), + source_url=f"https://example.test/fx/{n:04d}", + source_archive=rng.choice(ARCHIVES), + license="public_domain", + mode=mode, + left=left, + right=right, + dark=dark, + light=light, + duration_s=rng.choice((300, 480, 600, 720, 900)), + file_path="", + review_status=status, + resolution="1920x1080" if is_video else "", + rationale=f"fixture at ({left},{right},{dark},{light})", + reviewed_at="2026-06-04T00:00:00Z" if status == "approved" else None, + ) + ) + n += 1 + return records diff --git a/tests/test_fixtures.py b/tests/test_fixtures.py new file mode 100644 index 0000000..8e0d8cd --- /dev/null +++ b/tests/test_fixtures.py @@ -0,0 +1,40 @@ +from hef.catalog import validate_catalog +from hef.selection import CONTENT_MODES +from simulator.fixtures import generate_fixture_catalog + + +def test_fixture_catalog_is_valid(): + records = generate_fixture_catalog() + validate_catalog(records) # raises on any invalid record or duplicate id + + +def test_fixture_catalog_spans_the_coordinate_space(): + records = generate_fixture_catalog() + coords = {(r.left, r.right, r.dark, r.light) for r in records} + # all 625 cells of the 5x5 brain x 5x5 mood space are present + assert len(coords) == 625 + + +def test_fixture_catalog_has_every_content_mode(): + records = generate_fixture_catalog() + present = {r.mode for r in records} + assert CONTENT_MODES <= present + + +def test_fixture_catalog_mixes_review_statuses(): + records = generate_fixture_catalog() + statuses = {r.review_status for r in records} + assert statuses == {"proposed", "approved"} + + +def test_fixture_catalog_references_no_real_media(): + records = generate_fixture_catalog() + assert all(r.file_path == "" for r in records) + + +def test_fixture_catalog_is_deterministic(): + a = generate_fixture_catalog(seed=42) + b = generate_fixture_catalog(seed=42) + assert [r.id for r in a] == [r.id for r in b] + assert [r.mode for r in a] == [r.mode for r in b] + assert [r.review_status for r in a] == [r.review_status for r in b]