From 1c784aa9df58cd940ad87792996ae468b2199b1a Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Fri, 13 Nov 2026 14:52:59 +0800 Subject: [PATCH] fix(monitor): report retired QMT target without running it Co-Authored-By: Codex --- .../workflows/runtime-target-lifecycle.yml | 33 +++++-------------- .../test_runtime_target_lifecycle_workflow.py | 10 +++--- 2 files changed, 12 insertions(+), 31 deletions(-) diff --git a/.github/workflows/runtime-target-lifecycle.yml b/.github/workflows/runtime-target-lifecycle.yml index df87222..06d5d5a 100644 --- a/.github/workflows/runtime-target-lifecycle.yml +++ b/.github/workflows/runtime-target-lifecycle.yml @@ -3,9 +3,7 @@ name: Runtime Target Lifecycle on: workflow_dispatch: schedule: - # QMT has no configured broker runtime. One weekday no-order validation is - # sufficient for this daily strategy family and avoids pretending it has a - # continuously running execution service. + # Publish the intentional retirement state without invoking a strategy. - cron: "17 22 * * 1-5" concurrency: @@ -22,9 +20,6 @@ jobs: timeout-minutes: 15 env: EXECUTION_EVIDENCE_SYNC_URL: ${{ vars.EXECUTION_EVIDENCE_SYNC_URL }} - QMT_DRY_RUN_ONLY: "true" - QMT_MARKET_HISTORY_PATH: data/fixtures/market_history.sample.csv - STRATEGY_PROFILE: cn_industry_etf_rotation steps: - name: Checkout repository uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 @@ -69,27 +64,15 @@ jobs: python -m pip install -e . python -m pip install --no-deps -e external/QuantPlatformKit -e external/CnEquityStrategies - - name: Validate disabled dry-run target + - name: Verify the QMT strategy rollout remains empty id: validation run: | - set -euo pipefail - python scripts/preflight_qmt_runtime.py - # Exit 2 from this smoke means the cycle itself completed but the - # deterministic risk gate kept target weights empty. That is an - # expected no-order outcome for a disabled target, not a runtime - # failure. Exit 1 still means the dry-run did not complete. - set +e - python scripts/smoke_cn_industry_etf_rotation_dry_run_e2e.py - smoke_status="$?" - set -e - if [ "$smoke_status" -eq 0 ]; then - exit 0 - fi - if [ "$smoke_status" -eq 2 ]; then - echo "Dry-run completed with target weights safely blocked by the risk gate." - exit 0 - fi - exit "$smoke_status" + python - <<'PYCODE' + from strategy_registry import get_supported_profiles_for_platform + if get_supported_profiles_for_platform("qmt"): + raise SystemExit("QMT retirement policy changed; review the lifecycle publisher") + print("QMT has no enabled strategy profiles") + PYCODE - name: Map validation to shared lifecycle checks if: ${{ always() }} diff --git a/tests/test_runtime_target_lifecycle_workflow.py b/tests/test_runtime_target_lifecycle_workflow.py index 369eaef..2b71fc6 100644 --- a/tests/test_runtime_target_lifecycle_workflow.py +++ b/tests/test_runtime_target_lifecycle_workflow.py @@ -7,13 +7,11 @@ def test_disabled_qmt_lifecycle_workflow_stays_no_order() -> None: workflow = (ROOT / ".github" / "workflows" / "runtime-target-lifecycle.yml").read_text(encoding="utf-8") - assert "python scripts/preflight_qmt_runtime.py" in workflow - assert "python scripts/smoke_cn_industry_etf_rotation_dry_run_e2e.py" in workflow - assert 'if [ "$smoke_status" -eq 2 ]; then' in workflow - assert "safely blocked by the risk gate" in workflow + assert 'if get_supported_profiles_for_platform("qmt"):' in workflow + assert "scripts/preflight_qmt_runtime.py" not in workflow + assert "dry_run_e2e.py" not in workflow assert "configured-state: disabled" in workflow assert "execution-mode: dry_run" in workflow assert "execution_heartbeat=not_applicable" in workflow assert "platform: qmt" in workflow - assert 'QMT_DRY_RUN_ONLY: "true"' in workflow - assert "QMT_DRY_RUN_ONLY=false" not in workflow + assert "STRATEGY_PROFILE:" not in workflow