from __future__ import annotations import argparse import json from pathlib import Path import yaml from reuse_surface.reports import ( cohort_filters_from_args, collect_gap_report, collect_reuse_events, collect_reuse_report, collect_reused_by_suggestions, format_cohort_json, format_cohort_markdown, format_gap_markdown, format_reuse_report_json, format_reuse_report_markdown, select_cohort, ) SAMPLE_INDEX = { "capabilities": [ { "id": "capability.planning.only", "vector": "D5 / A0 / C2 / R1", "domain": "helix_forge", "consumption_modes": ["planning"], }, { "id": "capability.implementation.ready", "vector": "D5 / A4 / C3 / R3", "domain": "helix_forge", "consumption_modes": ["cli", "service API"], }, { "id": "capability.other.domain", "vector": "D4 / A3 / C2 / R2", "domain": "other", "consumption_modes": ["cli"], }, ] } def test_planning_min_filter(): filters = cohort_filters_from_args( argparse.Namespace( planning_min="D5", implementation_min=None, discovery_min=None, availability_min=None, availability_max=None, domain=None, ) ) matches = select_cohort(filters, SAMPLE_INDEX) assert [item["id"] for item in matches] == ["capability.planning.only"] def test_implementation_min_filter(): filters = cohort_filters_from_args( argparse.Namespace( planning_min=None, implementation_min="A4", discovery_min=None, availability_min=None, availability_max=None, domain=None, ) ) matches = select_cohort(filters, SAMPLE_INDEX) assert [item["id"] for item in matches] == ["capability.implementation.ready"] def test_domain_filter(): filters = {"discovery_min": None, "availability_min": None, "availability_max": None, "domain": "helix_forge"} matches = select_cohort(filters, SAMPLE_INDEX) assert len(matches) == 2 def test_format_cohort_markdown_includes_filters(): filters = {"discovery_min": "D5", "availability_min": None, "availability_max": "A1", "domain": None} text = format_cohort_markdown([SAMPLE_INDEX["capabilities"][0]], filters) assert "planning-min" not in text assert "discovery_min" in text assert "capability.planning.only" in text def test_format_cohort_json_payload(): filters = {"discovery_min": "D5", "availability_min": None, "availability_max": "A1", "domain": None} payload = json.loads( format_cohort_json([SAMPLE_INDEX["capabilities"][0]], filters) ) assert payload["count"] == 1 assert payload["filters"]["discovery_min"] == "D5" def test_collect_gap_report_from_roster(): root = Path(__file__).resolve().parent.parent roster = root / "registry/federation/local-repo-roster.yaml" report = collect_gap_report(roster) assert report["summary"]["total"] == 62 assert len(report["publish_fail"]) == 0 assert report["unclassified_count"] + report["explicit_none_count"] == report["empty_scaffold_count"] assert "/" in report["coverage_ratio"] def test_collect_gap_report_splits_unclassified_and_explicit_none(tmp_path): roster_path = tmp_path / "roster.yaml" roster_path.write_text( """ summary: total: 3 repos: - slug: has-repo status: established capability_count: 1 capability_status: has - slug: none-repo status: established capability_count: 0 capability_status: none - slug: pending-repo status: established capability_count: 0 capability_status: pending """ ) report = collect_gap_report(roster_path, index={"capabilities": []}) assert report["unclassified"] == ["pending-repo"] assert report["explicit_none"] == ["none-repo"] assert report["empty_scaffold_count"] == 2 assert report["coverage_ratio"] == "2/3" def test_format_gap_markdown_lists_publish_fail(): report = { "roster_path": "/tmp/roster.yaml", "summary": {"total": 60, "established": 60, "publish_pass": 48}, "publish_fail": [{"slug": "inter-hub", "publish_note": "missing repo"}], "empty_scaffold_count": 1, "empty_scaffolds": ["ops-bridge"], "unclassified_count": 1, "unclassified": ["ops-bridge"], "explicit_none_count": 0, "explicit_none": [], "coverage_ratio": "59/60", "seeded_repos": [], "dedup_pending_local_owners": [], "local_capability_count": 2, } text = format_gap_markdown(report) assert "inter-hub" in text assert "ops-bridge" in text def test_cmd_report_gaps_json(monkeypatch): from reuse_surface.cli import main exit_code = main(["report", "gaps", "--format", "json"]) assert exit_code == 0 def test_cmd_report_gaps_check_capability_requests_unreachable(monkeypatch): from reuse_surface.cli import main monkeypatch.setattr( "reuse_surface.cli.list_open_capability_requests", lambda: None ) exit_code = main(["report", "gaps", "--check-capability-requests"]) assert exit_code == 0 def test_cmd_report_gaps_check_capability_requests_json(monkeypatch): from reuse_surface.cli import main monkeypatch.setattr( "reuse_surface.cli.list_open_capability_requests", lambda: [{"id": "r1", "title": "Need X", "requesting_domain_slug": "infotech"}], ) exit_code = main( ["report", "gaps", "--check-capability-requests", "--format", "json"] ) assert exit_code == 0 def test_cmd_report_cohorts_markdown(monkeypatch): from reuse_surface.cli import main monkeypatch.setattr( "reuse_surface.reports.load_index", lambda: SAMPLE_INDEX, ) exit_code = main(["report", "cohorts", "--planning-min", "D5"]) assert exit_code == 0 # --- T05: reuse telemetry aggregation --- SAMPLE_REUSE_EVENTS = [ { "ts": "2026-07-01T00:00:00Z", "consumer_repo": "repo-a", "capability_id": "capability.infotech.issue-tracking", "verdict": "reuse", "outcome": "reused", "source": "plan-check", }, { "ts": "2026-07-02T00:00:00Z", "consumer_repo": "repo-b", "capability_id": "capability.infotech.issue-tracking", "verdict": "reuse", "outcome": "reused", "source": "manual", }, { "ts": "2026-07-03T00:00:00Z", "consumer_repo": "repo-a", "capability_id": "capability.audit.event-retain", "verdict": "extend", "outcome": "extended", "source": "plan-check", }, ] def test_collect_reuse_report_aggregates_per_capability(): report = collect_reuse_report(SAMPLE_REUSE_EVENTS) assert report["total_events"] == 3 by_id = {row["capability_id"]: row for row in report["capabilities"]} assert by_id["capability.infotech.issue-tracking"]["consumer_count"] == 2 assert by_id["capability.infotech.issue-tracking"]["consumer_repos"] == ["repo-a", "repo-b"] assert by_id["capability.infotech.issue-tracking"]["outcomes"] == {"reused": 2} assert by_id["capability.infotech.issue-tracking"]["last_used"] == "2026-07-02T00:00:00Z" assert by_id["capability.audit.event-retain"]["consumer_count"] == 1 def test_collect_reuse_report_filters_by_capability_id(): report = collect_reuse_report(SAMPLE_REUSE_EVENTS, capability_id="capability.audit.event-retain") assert len(report["capabilities"]) == 1 assert report["capabilities"][0]["capability_id"] == "capability.audit.event-retain" def test_collect_reuse_report_ignores_events_without_capability_id(): events = SAMPLE_REUSE_EVENTS + [ {"ts": "2026-07-04T00:00:00Z", "consumer_repo": "repo-c", "capability_id": None, "verdict": "new", "outcome": "new", "source": "manual"} ] report = collect_reuse_report(events) assert report["total_events"] == 4 assert len(report["capabilities"]) == 2 def test_format_reuse_report_markdown_empty(): output = format_reuse_report_markdown({"capabilities": [], "total_events": 0}) assert "No reuse events recorded yet" in output def test_format_reuse_report_markdown_nonempty(): report = collect_reuse_report(SAMPLE_REUSE_EVENTS) output = format_reuse_report_markdown(report) assert "capability.infotech.issue-tracking" in output assert "3" in output def test_format_reuse_report_json_roundtrips(): report = collect_reuse_report(SAMPLE_REUSE_EVENTS) payload = json.loads(format_reuse_report_json(report)) assert payload["total_events"] == 3 def test_collect_reuse_events_merges_hub_and_local(tmp_path, monkeypatch): monkeypatch.setattr( "reuse_surface.hub_client.hub_list_reuse_events", lambda capability_id=None, base_url=None: (200, {"events": [SAMPLE_REUSE_EVENTS[0]]}), ) telemetry_dir = tmp_path / "registry" / "telemetry" telemetry_dir.mkdir(parents=True) (telemetry_dir / "plan-check-events.jsonl").write_text( json.dumps(SAMPLE_REUSE_EVENTS[1], sort_keys=True) + "\n", encoding="utf-8" ) events = collect_reuse_events(repo_root=tmp_path) assert len(events) == 2 def test_collect_reuse_events_dedupes_identical_facts(tmp_path, monkeypatch): monkeypatch.setattr( "reuse_surface.hub_client.hub_list_reuse_events", lambda capability_id=None, base_url=None: (200, {"events": [SAMPLE_REUSE_EVENTS[0]]}), ) telemetry_dir = tmp_path / "registry" / "telemetry" telemetry_dir.mkdir(parents=True) (telemetry_dir / "plan-check-events.jsonl").write_text( json.dumps(SAMPLE_REUSE_EVENTS[0], sort_keys=True) + "\n", encoding="utf-8" ) events = collect_reuse_events(repo_root=tmp_path) assert len(events) == 1 def test_collect_reuse_events_degrades_gracefully_when_hub_unreachable(tmp_path, monkeypatch): monkeypatch.delenv("REUSE_SURFACE_URL", raising=False) events = collect_reuse_events(repo_root=tmp_path) assert events == [] def _write_entry_with_relations(tmp_path: Path, cap_id: str, reused_by: list[str]) -> str: rel = "registry/capabilities/capability-demo-sample.md" front_matter = { "id": cap_id, "name": "Sample", "summary": "Sample", "owner": "demo", "status": "draft", "domain": "helix_forge", "tags": ["demo"], "maturity": { "discovery": {"current": "D3", "target": "D5", "confidence": "low"}, "availability": {"current": "A3", "target": "A4", "confidence": "low"}, }, "external_evidence": { "completeness": {"level": "C2", "confidence": "low"}, "reliability": {"level": "R2", "confidence": "low"}, }, "discovery": {"intent": "demo", "includes": [], "excludes": []}, "availability": { "current_level": "A3", "target_level": "A4", "current_artifacts": [], "consumption_modes": ["informational"], }, "relations": {"depends_on": [], "supports": [], "related_to": [], "reused_by": reused_by}, "evidence": {"documentation": [], "tests": []}, "consumer_guidance": { "recommended_for": [], "not_recommended_for": [], "known_limitations": [], }, } path = tmp_path / rel path.parent.mkdir(parents=True, exist_ok=True) path.write_text("---\n" + yaml.safe_dump(front_matter, sort_keys=False) + "---\n", encoding="utf-8") return rel def test_collect_reused_by_suggestions_skips_already_listed_consumers(tmp_path): rel = _write_entry_with_relations(tmp_path, "capability.infotech.issue-tracking", reused_by=["repo-a"]) index_path = tmp_path / "registry" / "indexes" / "capabilities.yaml" index_path.parent.mkdir(parents=True, exist_ok=True) index_path.write_text( yaml.safe_dump({ "version": 1, "domain": "helix_forge", "updated": "2026-07-01", "capabilities": [{"id": "capability.infotech.issue-tracking", "path": rel, "vector": "D3/A3/C2/R2"}], }), encoding="utf-8", ) report = collect_reuse_report(SAMPLE_REUSE_EVENTS) suggestions = collect_reused_by_suggestions(report, repo_root=tmp_path) # repo-a already listed -> only repo-b should be suggested assert len(suggestions) == 1 assert suggestions[0]["value"] == {"type": "reused_by", "target": "repo-b"} assert suggestions[0]["kind"] == "relation_add" def test_collect_reused_by_suggestions_skips_capabilities_not_owned_locally(tmp_path): # empty local index -- no capabilities owned here at all index_path = tmp_path / "registry" / "indexes" / "capabilities.yaml" index_path.parent.mkdir(parents=True, exist_ok=True) index_path.write_text( yaml.safe_dump({"version": 1, "domain": "helix_forge", "updated": "2026-07-01", "capabilities": []}), encoding="utf-8", ) report = collect_reuse_report(SAMPLE_REUSE_EVENTS) suggestions = collect_reused_by_suggestions(report, repo_root=tmp_path) assert suggestions == [] def test_collect_reused_by_suggestions_no_index_returns_empty(tmp_path): report = collect_reuse_report(SAMPLE_REUSE_EVENTS) suggestions = collect_reused_by_suggestions(report, repo_root=tmp_path) assert suggestions == [] def test_cmd_report_reuse_markdown(monkeypatch): from reuse_surface.cli import main monkeypatch.setattr("reuse_surface.cli.collect_reuse_events", lambda hub_url=None: SAMPLE_REUSE_EVENTS) exit_code = main(["report", "reuse"]) assert exit_code == 0 def test_cmd_report_reuse_json(monkeypatch, capsys): from reuse_surface.cli import main monkeypatch.setattr("reuse_surface.cli.collect_reuse_events", lambda hub_url=None: SAMPLE_REUSE_EVENTS) exit_code = main(["report", "reuse", "--format", "json"]) assert exit_code == 0 payload = json.loads(capsys.readouterr().out) assert payload["total_events"] == 3 def test_cmd_report_reuse_apply_without_suggest_relations_errors(monkeypatch): from reuse_surface.cli import main monkeypatch.setattr("reuse_surface.cli.collect_reuse_events", lambda hub_url=None: []) exit_code = main(["report", "reuse", "--apply"]) assert exit_code == 1 def test_cmd_report_reuse_suggest_relations(monkeypatch, capsys): from reuse_surface.cli import main monkeypatch.setattr("reuse_surface.cli.collect_reuse_events", lambda hub_url=None: SAMPLE_REUSE_EVENTS) monkeypatch.setattr( "reuse_surface.cli.collect_reused_by_suggestions", lambda report: [{"capability_id": "capability.infotech.issue-tracking", "kind": "relation_add", "detail": "observed reuse by repo-a", "value": {"type": "reused_by", "target": "repo-a"}}], ) exit_code = main(["report", "reuse", "--suggest-relations"]) assert exit_code == 0 out = capsys.readouterr().out assert "repo-a" in out def test_cmd_report_reuse_apply_calls_apply_patches(monkeypatch): from reuse_surface.cli import main monkeypatch.setattr("reuse_surface.cli.collect_reuse_events", lambda hub_url=None: SAMPLE_REUSE_EVENTS) suggestion = {"capability_id": "capability.infotech.issue-tracking", "kind": "relation_add", "detail": "x", "value": {"type": "reused_by", "target": "repo-a"}} monkeypatch.setattr("reuse_surface.cli.collect_reused_by_suggestions", lambda report: [suggestion]) applied_calls = [] monkeypatch.setattr( "reuse_surface.patches.apply_patches", lambda repo_root, patches: applied_calls.append(patches) or ["applied one"], ) exit_code = main(["report", "reuse", "--suggest-relations", "--apply"]) assert exit_code == 0 assert applied_calls == [[suggestion]]