Skip to content

Commit 3189242

Browse files
authored
Merge pull request #224 from QuantStrategyLab/codex/quant-p0-20260710
feat: harden lifecycle drift preflight
2 parents 4be94ec + c11b31d commit 3189242

29 files changed

Lines changed: 1773 additions & 81 deletions
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
name: Reusable Drift Check
2+
3+
on:
4+
workflow_call:
5+
inputs:
6+
strategy_domain:
7+
required: true
8+
type: string
9+
snapshot_repository:
10+
required: true
11+
type: string
12+
snapshot_checkout_path:
13+
required: true
14+
type: string
15+
python_version:
16+
required: false
17+
type: string
18+
default: "3.11"
19+
ai_gateway_service_url:
20+
required: false
21+
type: string
22+
default: ""
23+
secrets:
24+
codex_audit_service_url:
25+
required: false
26+
27+
permissions:
28+
contents: read
29+
issues: write
30+
id-token: write
31+
32+
jobs:
33+
drift:
34+
runs-on: ubuntu-latest
35+
timeout-minutes: 15
36+
env:
37+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
38+
STRATEGY_DOMAIN: ${{ inputs.strategy_domain }}
39+
QUANT_PROJECTS_ROOT: ${{ github.workspace }}/external
40+
LIFECYCLE_PERFORMANCE_BUCKET: ${{ vars.LIFECYCLE_PERFORMANCE_BUCKET || '' }}
41+
LIFECYCLE_LOCAL_ROOT: ${{ github.workspace }}/data/lifecycle_store
42+
43+
steps:
44+
- name: Resolve QuantPlatformKit ref
45+
id: quant-platform-kit-ref
46+
shell: bash
47+
run: |
48+
set -euo pipefail
49+
workflow_ref="${{ github.workflow_ref }}"
50+
ref="${workflow_ref##*@}"
51+
case "$ref" in
52+
refs/heads/*)
53+
ref="${ref#refs/heads/}"
54+
;;
55+
refs/tags/*)
56+
ref="${ref#refs/tags/}"
57+
;;
58+
esac
59+
if [ -z "$ref" ]; then
60+
ref="main"
61+
fi
62+
echo "ref=$ref" >> "$GITHUB_OUTPUT"
63+
64+
- name: Validate trusted caller
65+
shell: bash
66+
run: |
67+
set -euo pipefail
68+
caller_repo="${{ github.repository }}"
69+
snapshot_repo="${{ inputs.snapshot_repository }}"
70+
case "$caller_repo" in
71+
QuantStrategyLab/CnEquityStrategies|QuantStrategyLab/HkEquityStrategies|QuantStrategyLab/UsEquityStrategies|QuantStrategyLab/CryptoStrategies)
72+
;;
73+
*)
74+
echo "::error::Untrusted reusable workflow caller: $caller_repo"
75+
exit 1
76+
;;
77+
esac
78+
if [ "$snapshot_repo" != "$caller_repo" ]; then
79+
echo "::error::snapshot_repository must match caller repository: $snapshot_repo"
80+
exit 1
81+
fi
82+
83+
- name: Checkout
84+
uses: actions/checkout@v6
85+
86+
- name: Checkout snapshot pipeline repo
87+
uses: actions/checkout@v6
88+
with:
89+
repository: ${{ inputs.snapshot_repository }}
90+
ref: main
91+
path: ${{ inputs.snapshot_checkout_path }}
92+
93+
- name: Checkout QuantPlatformKit
94+
uses: actions/checkout@v6
95+
with:
96+
repository: QuantStrategyLab/QuantPlatformKit
97+
ref: ${{ steps.quant-platform-kit-ref.outputs.ref }}
98+
path: external/QuantPlatformKit
99+
100+
- name: Set up Python
101+
uses: actions/setup-python@v6
102+
with:
103+
python-version: ${{ inputs.python_version }}
104+
105+
- name: Install dependencies
106+
run: |
107+
set -euo pipefail
108+
python -m pip install --upgrade pip
109+
python -m pip install -e . pandas
110+
python -m pip install --no-deps -e external/QuantPlatformKit
111+
112+
- name: Build lifecycle performance snapshots
113+
run: quant-lifecycle monitor --domain ${{ inputs.strategy_domain }}
114+
115+
- name: Validate lifecycle prerequisites
116+
run: quant-lifecycle doctor --domain ${{ inputs.strategy_domain }} --require-snapshot --require-backtest --max-freshness-days 7
117+
118+
- name: Run drift detection
119+
run: quant-lifecycle drift --domain ${{ inputs.strategy_domain }} --no-alerts
120+
121+
- name: Sync drift alerts to GitHub Issues
122+
env:
123+
GH_TOKEN: ${{ github.token }}
124+
GITHUB_REPOSITORY: ${{ github.repository }}
125+
run: |
126+
python - <<'PY'
127+
from quant_platform_kit.strategy_lifecycle.codex_integration import create_issues_for_domain
128+
results = create_issues_for_domain("${{ inputs.strategy_domain }}")
129+
created = [item for item in results if item.get("issue_url")]
130+
print({"created_issues": len(created), "results": len(results)})
131+
PY
132+
133+
- name: Checkout AIAuditBridge
134+
uses: actions/checkout@v6
135+
with:
136+
repository: QuantStrategyLab/AIAuditBridge
137+
ref: 9ff297375acbc54afa910d828248812212b5d7f2
138+
path: external/AIAuditBridge
139+
140+
- name: Dual-review critical drift
141+
env:
142+
AIAUDIT_BRIDGE_ROOT: external/AIAuditBridge
143+
CODEX_AUDIT_SERVICE_URL: ${{ secrets.codex_audit_service_url }}
144+
AI_GATEWAY_SERVICE_URL: ${{ inputs.ai_gateway_service_url }}
145+
run: |
146+
script="external/AIAuditBridge/scripts/run_drift_dual_review.py"
147+
if [ ! -f "$script" ]; then
148+
echo "::notice::dual-review scripts unavailable; skipping until AIAuditBridge is merged"
149+
exit 0
150+
fi
151+
if [ -z "${CODEX_AUDIT_SERVICE_URL:-}" ]; then
152+
echo "::notice::CODEX_AUDIT_SERVICE_URL not configured; skipping dual-review dispatch"
153+
exit 0
154+
fi
155+
PYTHONPATH=external/AIAuditBridge python "$script" \
156+
--domain "${STRATEGY_DOMAIN}" --dispatch

QPK_PIN

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
56a03364d517fd0e2efb2c4d4add8a785fc5e857
1+
618b786d9d95c87ba5c4d08c088c8bcac7817644

constraints.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# pip-compatible constraints mirror for QSL internal Git SHA pins.
22
# Source of truth: qsl-pins.txt (mirrored by update-qpk-pin.yml on every push to QPK main).
33

4-
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@56a03364d517fd0e2efb2c4d4add8a785fc5e857
4+
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@618b786d9d95c87ba5c4d08c088c8bcac7817644
55
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@2f3361c88f5bd65c9d577c6a51b9df5537332866
66
hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@c94c218d693e037701376e45ae5a21a8046b3849
77
cn-equity-strategies @ git+https://github.com/QuantStrategyLab/CnEquityStrategies.git@5be403ddc099ce3ed0cbd65552a6ebb64bdc5fdd
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# reusable drift workflow rollout / 联调清单
2+
3+
适用范围:
4+
5+
- `QuantStrategyLab/QuantPlatformKit`
6+
- `QuantStrategyLab/UsEquityStrategies`
7+
- `QuantStrategyLab/HkEquityStrategies`
8+
- `QuantStrategyLab/CnEquityStrategies`
9+
- `QuantStrategyLab/CryptoStrategies`
10+
11+
## 1. 合并顺序
12+
13+
必须按下面顺序执行,否则下游仓库会引用到不存在的 reusable workflow:
14+
15+
1. 先合并 `QuantPlatformKit`
16+
- 新增 `.github/workflows/reusable-drift-check.yml`
17+
- 新增 `quant-lifecycle doctor`
18+
- `doctor` 已要求 `--require-snapshot --require-backtest --max-freshness-days 7`
19+
2. 再合并 4 个策略仓库
20+
- `UsEquityStrategies`
21+
- `HkEquityStrategies`
22+
- `CnEquityStrategies`
23+
- `CryptoStrategies`
24+
25+
## 2. 合并前本地校验
26+
27+
### QuantPlatformKit
28+
29+
```bash
30+
cd /Users/lisiyi/Projects/_worktrees/quant_p0/QuantPlatformKit
31+
PYTHONPATH=src python3 -m pytest -q \
32+
tests/test_reusable_drift_workflow.py \
33+
tests/test_lifecycle_cli.py \
34+
tests/test_lifecycle_doctor.py \
35+
tests/test_strategy_performance_export.py
36+
```
37+
38+
### 4 个策略仓库
39+
40+
```bash
41+
QPK=/Users/lisiyi/Projects/_worktrees/quant_p0/QuantPlatformKit/src
42+
for repo in UsEquityStrategies HkEquityStrategies CnEquityStrategies CryptoStrategies; do
43+
cd "/Users/lisiyi/Projects/_worktrees/quant_p0/$repo"
44+
PYTHONPATH="$QPK" python3 -m pytest -q tests/test_drift_workflow_config.py
45+
done
46+
```
47+
48+
## 3. 合并后线上联调步骤
49+
50+
以下步骤必须在 `QuantPlatformKit` 和对应策略仓库都进入 `main` 后执行。
51+
52+
### 3.1 手动触发 workflow
53+
54+
```bash
55+
gh workflow run drift-check.yml -R QuantStrategyLab/UsEquityStrategies
56+
gh workflow run drift-check.yml -R QuantStrategyLab/HkEquityStrategies
57+
gh workflow run drift-check.yml -R QuantStrategyLab/CnEquityStrategies
58+
gh workflow run drift-check.yml -R QuantStrategyLab/CryptoStrategies
59+
```
60+
61+
### 3.2 观察最近一次运行
62+
63+
```bash
64+
for repo in UsEquityStrategies HkEquityStrategies CnEquityStrategies CryptoStrategies; do
65+
echo "==== $repo ===="
66+
gh run list -R QuantStrategyLab/$repo -w drift-check.yml -L 3 \
67+
--json databaseId,status,conclusion,createdAt,updatedAt,headBranch,event,url
68+
done
69+
```
70+
71+
### 3.3 失败时重点看 doctor step
72+
73+
如果 workflow 变红,先看 `Validate lifecycle prerequisites`
74+
75+
- `No strategy return series discovered`
76+
- snapshot/pipeline 仓库没有生成可读 returns
77+
- `QUANT_PROJECTS_ROOT` 下路径不匹配
78+
- `missing lifecycle snapshot`
79+
- `quant-lifecycle monitor` 没有落到 `LIFECYCLE_LOCAL_ROOT` / bucket
80+
- `missing lifecycle backtest`
81+
- 当前域还没有持久化 baseline / walk-forward backtest
82+
- 这是本次收口最可能暴露出来的新红灯
83+
- `snapshot freshness ... exceeds max 7d`
84+
- 数据链路断更或产物过旧
85+
86+
## 4. 当前 main 基线(2026-07-10)
87+
88+
下面是切换到 reusable workflow 之前,`main` 上最近一次 `drift-check.yml` 运行:
89+
90+
- `UsEquityStrategies`
91+
- run: `29081276798`
92+
- created: `2026-07-10T08:54:29Z`
93+
- conclusion: `success`
94+
- link: <https://github.com/QuantStrategyLab/UsEquityStrategies/actions/runs/29081276798>
95+
- `HkEquityStrategies`
96+
- run: `29081274915`
97+
- created: `2026-07-10T08:54:27Z`
98+
- conclusion: `success`
99+
- link: <https://github.com/QuantStrategyLab/HkEquityStrategies/actions/runs/29081274915>
100+
- `CnEquityStrategies`
101+
- run: `29083727180`
102+
- created: `2026-07-10T09:38:36Z`
103+
- conclusion: `success`
104+
- link: <https://github.com/QuantStrategyLab/CnEquityStrategies/actions/runs/29083727180>
105+
- `CryptoStrategies`
106+
- run: `29083379166`
107+
- created: `2026-07-10T09:32:18Z`
108+
- conclusion: `success`
109+
- link: <https://github.com/QuantStrategyLab/CryptoStrategies/actions/runs/29083379166>
110+
111+
注意:这些都是旧 workflow 的结果,不能证明新的 `doctor --require-backtest` 已通过。
112+
113+
## 5. 通过标准
114+
115+
4 个仓库全部满足以下条件,才算这一批 rollout 完成:
116+
117+
1. `drift-check.yml``main` 上成功运行;
118+
2. workflow summary 不再是“0 strategies checked”假绿灯;
119+
3. `doctor` 没有报 `missing lifecycle backtest`
120+
4. `drift` step 至少验证到真实策略样本;
121+
5. GitHub Issues / AIAuditBridge dual-review 链路未回归。

qsl-pins.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# QSL internal Git SHA pins — source of truth.
22
# Auto-updated by update-qpk-pin.yml on every push to QPK main.
33

4-
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@56a03364d517fd0e2efb2c4d4add8a785fc5e857
4+
quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@618b786d9d95c87ba5c4d08c088c8bcac7817644
55
us-equity-strategies @ git+https://github.com/QuantStrategyLab/UsEquityStrategies.git@2f3361c88f5bd65c9d577c6a51b9df5537332866
66
hk-equity-strategies @ git+https://github.com/QuantStrategyLab/HkEquityStrategies.git@c94c218d693e037701376e45ae5a21a8046b3849
77
cn-equity-strategies @ git+https://github.com/QuantStrategyLab/CnEquityStrategies.git@5be403ddc099ce3ed0cbd65552a6ebb64bdc5fdd

0 commit comments

Comments
 (0)