"""Orchestrator tests — Profile 1 surfacing and explain-context roundtrip.""" from io import StringIO from pathlib import Path from unittest.mock import patch import pytest from rich.console import Console from cya.memory import KIND_REFLECTION, remember_reflection from cya.memory.reflections import format_reflection_surfacing from cya.orchestrator import handle_request @pytest.fixture def isolated_memory(monkeypatch, tmp_path): mem_dir = tmp_path / "memory" mem_dir.mkdir() def _fake_mem_path(scope: str = "cwd") -> Path: return mem_dir / f"{scope}.json" monkeypatch.setattr("cya.memory._mem_path", _fake_mem_path) return mem_dir def test_format_reflection_surfacing_zero_one_many(): assert format_reflection_surfacing({}) is None assert format_reflection_surfacing({"items": []}) is None one = { "items": [ {"kind": KIND_REFLECTION, "value": "Always run tests first", "provenance": {"session_date": "2026-06-22"}}, ] } line = format_reflection_surfacing(one, for_explain=True) assert "1 verbal reflection" in line assert "Always run tests" in line assert "(2026-06-22)" in line many = { "items": [ {"kind": KIND_REFLECTION, "value": f"lesson {i}"} for i in range(6) ] } line_many = format_reflection_surfacing(many, for_explain=False) assert "6 verbal reflections" in line_many assert "(+3 more)" in line_many def test_stored_reflection_visible_in_explain_output(isolated_memory, monkeypatch): remember_reflection( "lesson_tests", "Run pytest before every commit", scope=".", provenance={"session_date": "2026-06-22", "scope": ".", "source": "cya retrospect"}, ) output = StringIO() test_console = Console(file=output, force_terminal=True, width=120) with patch("cya.orchestrator.console", test_console): with patch("cya.orchestrator.collect") as mock_collect: mock_collect.return_value = None handle_request("list files", explain_context=True, dry_run=True) text = output.getvalue() assert "Reflections:" in text or "verbal reflection" in text.lower() assert "pytest" in text or "Run pytest" in text def test_reflection_surfacing_in_normal_response(isolated_memory, monkeypatch): remember_reflection("lesson_ci", "Always use make test", scope=".") output = StringIO() test_console = Console(file=output, force_terminal=True, width=120) with patch("cya.orchestrator.console", test_console): with patch("cya.orchestrator.collect") as mock_collect: with patch("cya.orchestrator.get_user_confirmation", return_value=True): mock_collect.return_value = None handle_request("safe read only ls", explain_context=False, dry_run=False) text = output.getvalue() assert "verbal reflection" in text.lower() or "influenced this" in text