Skip to content

Commit 38aa210

Browse files
authored
Merge pull request #437 from QuantStrategyLab/fix/ibkr-reconciliation-artifact-input
fix: enroll redacted IBKR reconciliation artifacts directly
2 parents 49e2310 + 8b90cfe commit 38aa210

3 files changed

Lines changed: 23 additions & 0 deletions

File tree

docs/ibkr_reconciliation_baseline_enrollment.zh-CN.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,10 @@ Scheduler 任务,再由既有的最小权限 Scheduler 身份调用冻结服
9797
成功或失败时删除该一次性任务。它不调用 `/run`、不修改 GitHub 变量、不发布状态账本,也
9898
不发送任何订单。
9999

100+
工作流 artifact 的外层是 `ibkr_reconciliation_artifact.v1`,内部仅保留同一份
101+
`broker_reconciliation` 摘要;`build_reconciliation_baseline_candidate.py` 可直接消费它。
102+
这样基线审核不必下载包含其他运行诊断的完整私有报告。
103+
100104
同一目标至少应在相隔一分钟的两次手动运行中得到候选,才能交给
101105
`build_reconciliation_baseline_candidate.py`。工作流的成功只说明读取和收据格式正常;
102106
候选仍可能因为未配置预期摘要或账本差异而正确保持阻断。

scripts/build_reconciliation_baseline_candidate.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ def extract_reconciliation_evidence(payload: Mapping[str, Any]) -> BrokerReconci
3333
nested = diagnostics.get("broker_reconciliation")
3434
if isinstance(nested, Mapping):
3535
candidate = nested
36+
# The manual evidence workflow stores only this safe candidate beneath a
37+
# small artifact envelope. Accept that envelope too, so enrollment never
38+
# needs the broader private execution report as an input.
39+
reconciliation = payload.get("reconciliation")
40+
if isinstance(reconciliation, Mapping):
41+
candidate = reconciliation
3642
evidence = candidate.get("evidence") if isinstance(candidate, Mapping) else None
3743
if not isinstance(evidence, Mapping):
3844
raise ValueError("receipt does not contain broker_reconciliation evidence")

tests/test_reconciliation_baseline_candidate_script.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,19 @@ def test_accepts_persisted_runtime_report_shape() -> None:
8585
assert evidence.platform_id == "ibkr"
8686

8787

88+
def test_accepts_redacted_workflow_artifact_shape() -> None:
89+
start = datetime(2026, 8, 30, 8, 0, tzinfo=timezone.utc)
90+
payload = {
91+
"schema_version": "ibkr_reconciliation_artifact.v1",
92+
"strategy_profile": "soxl_soxx_trend_income",
93+
"reconciliation": _payload(observed_at=start),
94+
}
95+
96+
evidence = extract_reconciliation_evidence(payload)
97+
98+
assert evidence.platform_id == "ibkr"
99+
100+
88101
def test_missing_redacted_evidence_is_rejected() -> None:
89102
with pytest.raises(ValueError, match="does not contain"):
90103
extract_reconciliation_evidence({"diagnostics": {}})

0 commit comments

Comments
 (0)