From fbeb4f78491c5c08c3b52df132f47f7b78c20f4f Mon Sep 17 00:00:00 2001 From: saagpatel Date: Wed, 5 Aug 2026 03:35:19 -0700 Subject: [PATCH] fix(decisions): make queue CLI cwd-independent --- src/portfolio_decision_queue.py | 8 +++++ tests/test_portfolio_decision_queue.py | 47 ++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/portfolio_decision_queue.py b/src/portfolio_decision_queue.py index 554a9ac..1334fec 100644 --- a/src/portfolio_decision_queue.py +++ b/src/portfolio_decision_queue.py @@ -13,10 +13,18 @@ import argparse import hashlib import json +import sys from datetime import datetime, timedelta, timezone from pathlib import Path from typing import Any +# Keep the documented absolute-path entrypoint portable. When Python executes +# this file directly it puts ``src/`` on sys.path, which otherwise makes the +# package-qualified ``src.security_admission`` import impossible outside the +# repository root. Module and test imports already have the repository root. +if __package__ in {None, ""}: + sys.path.insert(0, str(Path(__file__).resolve().parents[1])) + from src.security_admission import derive_security_admission CONTRACT_VERSION = "decision_queue_v2" diff --git a/tests/test_portfolio_decision_queue.py b/tests/test_portfolio_decision_queue.py index 20d62d3..ab62ccc 100644 --- a/tests/test_portfolio_decision_queue.py +++ b/tests/test_portfolio_decision_queue.py @@ -2,6 +2,8 @@ import copy import json +import subprocess +import sys from pathlib import Path import pytest @@ -469,3 +471,48 @@ def test_cli_json_and_markdown_are_deterministic( markdown = capsys.readouterr().out assert "## Portfolio Decision Digest — 2026-08-05" in markdown assert "**MCPAudit** [security follow-up]" in markdown + + +def test_absolute_cli_entrypoint_runs_from_arbitrary_cwd(tmp_path: Path) -> None: + truth_path = tmp_path / "portfolio-truth.json" + truth_path.write_text( + json.dumps( + _truth( + [ + _project( + "MCPAudit", + attention_state="decision-needed", + security_risk=True, + code_scanning_high=1, + ) + ] + ) + ), + encoding="utf-8", + ) + script = Path(__file__).resolve().parents[1] / "src" / "portfolio_decision_queue.py" + unrelated_cwd = tmp_path / "unrelated-cwd" + unrelated_cwd.mkdir() + + run = subprocess.run( + [ + sys.executable, + "-B", + str(script), + "--truth", + str(truth_path), + "--format", + "json", + ], + cwd=unrelated_cwd, + check=False, + capture_output=True, + text=True, + ) + + assert run.returncode == 0, run.stderr + digest = json.loads(run.stdout) + assert digest["contract_version"] == DIGEST_CONTRACT_VERSION + assert digest["decision_queue"][0]["evidence_reference"]["provider"] == ( + "github_security_combined" + )