"""Scoping + proposals + active registry tests (WP-0007 T04).""" import os import sys sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) from session_memory.curate.schema import Resolution, Scope, SolutionPattern # noqa: E402 from session_memory.distribute.proposals import ( # noqa: E402 ActiveRegistry, Target, applies, propose, ) def _pattern(pid="sp-x", repos=None, flavors=None, status="approved", ready=True): return SolutionPattern( id=pid, name="Read before edit", version="1.0.0", polarity="problem", problem="edit before read", resolutions=[Resolution(summary="read first")], scope=Scope(repos=repos or [], flavors=flavors or []), status=status, distribution_ready=ready, ) def test_applies_respects_scope(): p = _pattern(repos=["agentic-resources"], flavors=["claude"]) assert applies(p, Target("agentic-resources", flavor="claude")) assert not applies(p, Target("other-repo", flavor="claude")) assert not applies(p, Target("agentic-resources", flavor="codex")) def test_empty_scope_is_unrestricted(): assert applies(_pattern(), Target("any", flavor="grok")) def test_propose_writes_scoped_proposal_files(tmp_path): out = str(tmp_path / "proposals") reg = ActiveRegistry(str(tmp_path / "active.json")) p = _pattern(flavors=["claude"]) res = propose([p], [Target("agentic-resources", flavor="claude"), Target("agentic-resources", flavor="codex")], out, reg) # only claude target is in scope assert len(res.proposals) == 1 path = os.path.join(out, "agentic-resources", "CLAUDE.md") assert os.path.exists(path) assert "BEGIN helix-forge pattern:sp-x" in open(path).read() def test_not_distributable_skipped(tmp_path): reg = ActiveRegistry(str(tmp_path / "active.json")) prov = _pattern(status="provisional", ready=False) res = propose([prov], [Target("r", flavor="claude")], str(tmp_path / "p"), reg) assert res.proposals == [] assert "sp-x" in res.skipped_not_distributable def test_proposals_idempotent_on_rerun(tmp_path): out = str(tmp_path / "proposals") reg_path = str(tmp_path / "active.json") p = _pattern() propose([p], [Target("r", flavor="claude")], out, ActiveRegistry(reg_path)) propose([p], [Target("r", flavor="claude")], out, ActiveRegistry(reg_path)) content = open(os.path.join(out, "r", "CLAUDE.md")).read() assert content.count("BEGIN helix-forge pattern:sp-x") == 1 # no duplication def test_active_registry_records_environment(tmp_path): reg_path = str(tmp_path / "active.json") reg = ActiveRegistry(reg_path) propose([_pattern()], [Target("r", domain="helix_forge", flavor="claude")], str(tmp_path / "p"), reg) reg2 = ActiveRegistry(reg_path) # reload from disk entries = reg2.entries() assert len(entries) == 1 assert entries[0]["pattern_id"] == "sp-x" assert entries[0]["repo"] == "r" assert entries[0]["flavor"] == "claude" assert entries[0]["status"] == "proposed"