From 44de9e980ff89886cd642c9f5b874d36e0e0b028 Mon Sep 17 00:00:00 2001 From: Saagar Date: Sat, 4 Jul 2026 07:11:22 -0700 Subject: [PATCH] fix: match path-qualified catalog entries by repo basename --- src/cli.py | 37 +++++++++++++++++++++ src/portfolio_catalog.py | 15 +++++++++ tests/test_cli_hardening.py | 57 +++++++++++++++++++++++++++++++++ tests/test_portfolio_catalog.py | 48 +++++++++++++++++++++++++++ 4 files changed, 157 insertions(+) diff --git a/src/cli.py b/src/cli.py index 171d97f..e5e45a3 100644 --- a/src/cli.py +++ b/src/cli.py @@ -2218,6 +2218,15 @@ def _enrich_control_center_snapshot_from_report( snapshot: dict, args, ) -> dict: + from src.portfolio_catalog import ( + DEFAULT_CATALOG_PATH, + build_catalog_line, + catalog_entry_for_repo, + evaluate_intent_alignment, + load_portfolio_catalog, + ) + from src.report_enrichment import build_operator_focus + report = _report_from_dict( { **report_data, @@ -2225,6 +2234,34 @@ def _enrich_control_center_snapshot_from_report( "operator_queue": snapshot.get("operator_queue", []), } ) + catalog_path = getattr(args, "catalog", None) or DEFAULT_CATALOG_PATH + catalog_data = load_portfolio_catalog(Path(catalog_path)) + queue_by_repo = { + str(item.get("repo") or item.get("repo_name") or "").strip(): item + for item in report.operator_queue + if str(item.get("repo") or item.get("repo_name") or "").strip() + } + for audit in report.audits: + if (audit.portfolio_catalog or {}).get("has_explicit_entry"): + continue + base_entry = catalog_entry_for_repo(audit.metadata.to_dict(), catalog_data) + if not base_entry.get("has_explicit_entry"): + continue + operator_focus = build_operator_focus(queue_by_repo.get(audit.metadata.name, {})) + intent_alignment, intent_alignment_reason = evaluate_intent_alignment( + base_entry, + completeness_tier=audit.completeness_tier, + archived=audit.metadata.archived, + operator_focus=operator_focus, + ) + audit.portfolio_catalog = { + **base_entry, + "catalog_line": build_catalog_line(base_entry), + "intent_alignment": intent_alignment, + "intent_alignment_reason": intent_alignment_reason, + "intent_alignment_line": f"{intent_alignment}: {intent_alignment_reason}", + "operator_focus": operator_focus, + } if any(audit.portfolio_catalog for audit in report.audits): audit_lookup = {audit.metadata.name: audit.portfolio_catalog for audit in report.audits} for item in report.operator_queue: diff --git a/src/portfolio_catalog.py b/src/portfolio_catalog.py index 2318599..d183a92 100644 --- a/src/portfolio_catalog.py +++ b/src/portfolio_catalog.py @@ -367,6 +367,21 @@ def catalog_entry_for_repo( "matched_by": "bare-name", } + basename_matches = [ + entry + for key, entry in repos.items() + if "/" in key and key.rsplit("/", 1)[-1] == normalized_repo_name + ] + if normalized_repo_name and len(basename_matches) == 1: + return { + **basename_matches[0], + "repo": repo_name, + "repo_full_name": full_name, + "catalog_default_maturity_program": default_program, + "catalog_default_target_maturity": default_target, + "matched_by": "path-basename", + } + return { "repo": repo_name, "repo_full_name": full_name, diff --git a/tests/test_cli_hardening.py b/tests/test_cli_hardening.py index 2b05d59..a4c0257 100644 --- a/tests/test_cli_hardening.py +++ b/tests/test_cli_hardening.py @@ -544,6 +544,63 @@ def test_control_center_snapshot_rehydrates_portfolio_context( assert item["scorecard"]["status"] == "on-track" +def test_control_center_snapshot_repairs_missing_path_basename_catalog_context( + tmp_path, + sample_metadata, +) -> None: + catalog_path = tmp_path / "portfolio-catalog.yaml" + catalog_path.write_text( + """ +repos: + _machine/test-repo: + owner: d + lifecycle_state: active + criticality: high + review_cadence: weekly + intended_disposition: maintain + maturity_program: maintain + target_maturity: operating + category: infrastructure +""" + ) + audit = RepoAudit( + metadata=sample_metadata, + analyzer_results=[AnalyzerResult("testing", 0.7, 1.0, [], {})], + overall_score=0.7, + completeness_tier="functional", + flags=[], + lenses={"ship_readiness": {"score": 0.7}}, + security_posture={"score": 0.8}, + portfolio_catalog={ + "has_explicit_entry": False, + "catalog_line": "No portfolio catalog contract is recorded yet.", + "intent_alignment": "missing-contract", + }, + ) + report = AuditReport.from_audits("testuser", [audit], [], 1) + report.operator_queue = [ + { + "repo": "test-repo", + "lane": "urgent", + "title": "Review test-repo", + "portfolio_catalog": dict(audit.portfolio_catalog), + } + ] + snapshot = {"operator_summary": {}, "operator_queue": [dict(report.operator_queue[0])]} + + updated = cli._enrich_control_center_snapshot_from_report( + report.to_dict(), + snapshot, + _make_args(catalog=catalog_path), + ) + + item = updated["operator_queue"][0] + assert item["portfolio_catalog"]["catalog_key"] == "_machine/test-repo" + assert item["portfolio_catalog"]["matched_by"] == "path-basename" + assert item["portfolio_catalog"]["has_explicit_entry"] is True + assert item["intent_alignment"] != "missing-contract" + + def test_main_doctor_writes_artifact_and_exits_cleanly(monkeypatch, tmp_path, capsys): args = _make_args(doctor=True, output_dir=str(tmp_path)) artifact_path = tmp_path / "diagnostics-testuser-2026-03-29.json" diff --git a/tests/test_portfolio_catalog.py b/tests/test_portfolio_catalog.py index 2d0cf53..eea34ec 100644 --- a/tests/test_portfolio_catalog.py +++ b/tests/test_portfolio_catalog.py @@ -195,6 +195,54 @@ def test_catalog_entry_matches_path_before_full_name_and_bare_name(): assert entry["matched_by"] == "path" +def test_catalog_entry_matches_unambiguous_path_basename(): + catalog = { + "repos": { + "_machine/machine-control-tower": { + "owner": "d", + "catalog_key": "_machine/machine-control-tower", + "matched_by": "full-name", + "has_explicit_entry": True, + }, + } + } + + entry = catalog_entry_for_repo( + {"name": "machine-control-tower", "full_name": "user/machine-control-tower"}, + catalog, + ) + + assert entry["owner"] == "d" + assert entry["matched_by"] == "path-basename" + + +def test_catalog_entry_does_not_guess_ambiguous_path_basename(): + catalog = { + "repos": { + "alpha/shared": { + "owner": "alpha", + "catalog_key": "alpha/shared", + "matched_by": "full-name", + "has_explicit_entry": True, + }, + "beta/shared": { + "owner": "beta", + "catalog_key": "beta/shared", + "matched_by": "full-name", + "has_explicit_entry": True, + }, + } + } + + entry = catalog_entry_for_repo( + {"name": "shared", "full_name": "user/shared"}, + catalog, + ) + + assert entry["has_explicit_entry"] is False + assert entry["matched_by"] == "" + + def test_group_entry_matches_path_prefix(): catalog = { "groups": {