Skip to content

Commit 4b441ec

Browse files
Pigbibicodex
andcommitted
fix: allow private present package staging
Co-Authored-By: Codex <noreply@openai.com>
1 parent 0c33aff commit 4b441ec

2 files changed

Lines changed: 110 additions & 8 deletions

File tree

src/quant_strategy_plugins/tqqq_market_regime_control_present.py

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,23 @@ def _git(*args: str) -> str:
161161
return subprocess.check_output(["git", *args], text=True, stderr=subprocess.DEVNULL).strip()
162162

163163

164-
def _verify_source_identity(expected_qsp_commit_sha: str) -> None:
164+
def _only_private_stage_is_dirty(root: Path, status: str, private_stage: Path) -> bool:
165+
try:
166+
relative_stage = private_stage.resolve().relative_to(root).as_posix()
167+
except ValueError:
168+
return False
169+
if not private_stage.name.startswith(".tqqq-market-regime-control-present-"):
170+
return False
171+
for record in filter(None, status.split("\0")):
172+
if len(record) < 4 or record[:2] != "??":
173+
return False
174+
path = record[3:]
175+
if path != relative_stage and not path.startswith(f"{relative_stage}/"):
176+
return False
177+
return bool(status)
178+
179+
180+
def _verify_source_identity(expected_qsp_commit_sha: str, *, private_stage: Path | None = None) -> None:
165181
if not _is_commit_sha(expected_qsp_commit_sha):
166182
_fail("T2B2_PRODUCER_IDENTITY_INVALID", 2)
167183
try:
@@ -172,7 +188,8 @@ def _verify_source_identity(expected_qsp_commit_sha: str) -> None:
172188
relative_module = module_path.relative_to(root)
173189
if _git("ls-files", "--error-unmatch", str(relative_module)) != str(relative_module):
174190
_fail("T2B2_PRODUCER_IDENTITY_INVALID", 2)
175-
if _git("status", "--porcelain"):
191+
status = _git("status", "--porcelain=v1", "-z", "--untracked-files=all")
192+
if status and (private_stage is None or not _only_private_stage_is_dirty(root, status, private_stage)):
176193
_fail("T2B2_PRODUCER_IDENTITY_INVALID", 2)
177194
if _git("rev-parse", "HEAD") != expected_qsp_commit_sha:
178195
_fail("T2B2_PRODUCER_IDENTITY_INVALID", 2)
@@ -464,7 +481,7 @@ def capture_tqqq_market_regime_control_present(
464481
staged_package.write_bytes(package_bytes)
465482
_readback_package(staged_package, expected_qsp_commit_sha=expected_qsp_commit_sha)
466483
_readback_package(staged_package, expected_qsp_commit_sha=expected_qsp_commit_sha)
467-
_verify_source_identity(expected_qsp_commit_sha)
484+
_verify_source_identity(expected_qsp_commit_sha, private_stage=stage)
468485
shutil.rmtree(stage / "producer-output")
469486
if (stage / "producer-output").exists():
470487
_fail("T2B2_PRODUCER_PUBLISH_FAILED", 4)

tests/test_tqqq_market_regime_control_present.py

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import base64
44
import hashlib
55
import json
6+
import shutil
67
import subprocess
78
from pathlib import Path
89

@@ -67,9 +68,13 @@ def _config(tmp_path: Path) -> Path:
6768
return config_path
6869

6970

70-
def _capture(tmp_path: Path, monkeypatch: pytest.MonkeyPatch):
71-
source_checks: list[str] = []
72-
monkeypatch.setattr(present_module, "_verify_source_identity", lambda expected: source_checks.append(expected))
71+
def _capture(tmp_path: Path, monkeypatch: pytest.MonkeyPatch, *, output_dir: Path | None = None):
72+
source_checks: list[Path | None] = []
73+
monkeypatch.setattr(
74+
present_module,
75+
"_verify_source_identity",
76+
lambda _expected, private_stage=None: source_checks.append(private_stage),
77+
)
7378
calls: list[dict[str, object]] = []
7479

7580
def run_once(config: dict[str, object], mode: str):
@@ -79,7 +84,7 @@ def run_once(config: dict[str, object], mode: str):
7984
monkeypatch.setattr(present_module, "run_market_regime_control_plugin", run_once)
8085
package = present_module.capture_tqqq_market_regime_control_present(
8186
config_path=_config(tmp_path),
82-
output_dir=tmp_path / "packages",
87+
output_dir=output_dir or tmp_path / "packages",
8388
expected_qsp_commit_sha=EXPECTED_COMMIT,
8489
as_of=AS_OF,
8590
session_id=f"XNAS:{AS_OF}",
@@ -95,7 +100,8 @@ def test_capture_publishes_one_canonical_package_after_one_current_producer_call
95100
payload_bytes = base64.b64decode(decoded["payload"]["bytes_b64"], validate=True)
96101

97102
assert len(calls) == 1
98-
assert source_checks == [EXPECTED_COMMIT, EXPECTED_COMMIT]
103+
assert source_checks[0] is None
104+
assert source_checks[1] is not None
99105
assert package.path.parent == tmp_path / "packages"
100106
assert package.path.name == f"tqqq-market-regime-control-present-{AS_OF}-{package.sha256}.json"
101107
assert package.sha256 == hashlib.sha256(package_bytes).hexdigest()
@@ -113,6 +119,20 @@ def test_capture_publishes_one_canonical_package_after_one_current_producer_call
113119
assert list((tmp_path / "packages").iterdir()) == [package.path]
114120

115121

122+
def test_capture_allows_unignored_in_repository_output_and_removes_private_stage(tmp_path, monkeypatch) -> None:
123+
output_dir = Path.cwd() / f"tqqq-present-output-{tmp_path.name}"
124+
try:
125+
package, _, source_checks = _capture(tmp_path, monkeypatch, output_dir=output_dir)
126+
127+
assert package.path.parent == output_dir
128+
assert source_checks[0] is None
129+
assert source_checks[1] is not None
130+
assert source_checks[1].parent == output_dir
131+
assert not list(output_dir.glob(".tqqq-market-regime-control-present-*"))
132+
finally:
133+
shutil.rmtree(output_dir, ignore_errors=True)
134+
135+
116136
def test_capture_rejects_staged_input_mutation_without_a_final_package(tmp_path, monkeypatch) -> None:
117137
monkeypatch.setattr(present_module, "_verify_source_identity", lambda _expected: None)
118138

@@ -166,6 +186,71 @@ def test_source_identity_rejects_a_wrong_expected_commit(monkeypatch) -> None:
166186
present_module._verify_source_identity("0" * 40)
167187

168188

189+
def _source_identity_git(monkeypatch, status: str) -> tuple[Path, list[tuple[str, ...]]]:
190+
root = Path.cwd().resolve()
191+
relative_module = Path(present_module.__file__).resolve().relative_to(root)
192+
calls: list[tuple[str, ...]] = []
193+
194+
def fake_git(*args: str) -> str:
195+
calls.append(args)
196+
if args == ("rev-parse", "--show-toplevel"):
197+
return str(root)
198+
if args == ("ls-files", "--error-unmatch", str(relative_module)):
199+
return str(relative_module)
200+
if args and args[0] == "status":
201+
return status
202+
if args == ("rev-parse", "HEAD"):
203+
return EXPECTED_COMMIT
204+
raise AssertionError(args)
205+
206+
monkeypatch.setattr(present_module, "_git", fake_git)
207+
return root, calls
208+
209+
210+
def test_second_source_identity_check_allows_only_its_private_stage(monkeypatch) -> None:
211+
root = Path.cwd().resolve()
212+
private_stage = root / "unignored-output" / ".tqqq-market-regime-control-present-test"
213+
relative_stage = private_stage.relative_to(root).as_posix()
214+
_, calls = _source_identity_git(monkeypatch, f"?? {relative_stage}/\0")
215+
216+
present_module._verify_source_identity(EXPECTED_COMMIT, private_stage=private_stage)
217+
218+
assert ("status", "--porcelain=v1", "-z", "--untracked-files=all") in calls
219+
220+
with pytest.raises(present_module.PresentPackageError, match="T2B2_PRODUCER_IDENTITY_INVALID"):
221+
present_module._verify_source_identity(EXPECTED_COMMIT)
222+
223+
224+
@pytest.mark.parametrize("status", [" M src/unrelated.py\0", "?? unrelated.txt\0"])
225+
def test_second_source_identity_check_rejects_unrelated_tracked_or_untracked_dirt(monkeypatch, status: str) -> None:
226+
root = Path.cwd().resolve()
227+
private_stage = root / "unignored-output" / ".tqqq-market-regime-control-present-test"
228+
_source_identity_git(monkeypatch, f"?? {private_stage.relative_to(root).as_posix()}/\0{status}")
229+
230+
with pytest.raises(present_module.PresentPackageError, match="T2B2_PRODUCER_IDENTITY_INVALID"):
231+
present_module._verify_source_identity(EXPECTED_COMMIT, private_stage=private_stage)
232+
233+
234+
def test_identity_failure_does_not_create_a_final_package(tmp_path, monkeypatch) -> None:
235+
monkeypatch.setattr(
236+
present_module,
237+
"_verify_source_identity",
238+
lambda *_args, **_kwargs: (_ for _ in ()).throw(present_module.PresentPackageError("T2B2_PRODUCER_IDENTITY_INVALID", 2)),
239+
)
240+
destination = tmp_path / "packages"
241+
242+
with pytest.raises(present_module.PresentPackageError, match="T2B2_PRODUCER_IDENTITY_INVALID"):
243+
present_module.capture_tqqq_market_regime_control_present(
244+
config_path=_config(tmp_path),
245+
output_dir=destination,
246+
expected_qsp_commit_sha=EXPECTED_COMMIT,
247+
as_of=AS_OF,
248+
session_id=f"XNAS:{AS_OF}",
249+
)
250+
251+
assert not destination.exists()
252+
253+
169254
def test_strict_readback_rejects_an_unknown_package_field(tmp_path, monkeypatch) -> None:
170255
package, _, _ = _capture(tmp_path, monkeypatch)
171256
decoded = json.loads(package.path.read_bytes())

0 commit comments

Comments
 (0)