Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
90 changes: 90 additions & 0 deletions .github/workflows/collect-reconciliation-evidence.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
name: Collect IBKR Reconciliation Evidence

on:
workflow_dispatch:
inputs:
target:
description: "Frozen live target to read; this workflow has no order path."
required: true
default: all
type: choice
options:
- all
- soxl_soxx_trend_income
- tqqq_growth_income
- global_etf_rotation
- russell_top50_leader_rotation

permissions:
contents: read
id-token: write

env:
GCP_PROJECT_ID: interactivebrokersquant
GCP_REGION: us-central1
GCP_WORKLOAD_IDENTITY_PROVIDER: projects/303168642265/locations/global/workloadIdentityPools/github-actions/providers/github-main
GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT: ibkr-platform-deploy@interactivebrokersquant.iam.gserviceaccount.com

concurrency:
group: ibkr-reconciliation-evidence-${{ inputs.target }}
cancel-in-progress: false

jobs:
collect:
name: Read ${{ matrix.profile }} baseline evidence
if: ${{ inputs.target == 'all' || inputs.target == matrix.profile }}
runs-on: ubuntu-latest
timeout-minutes: 10
strategy:
fail-fast: false
matrix:
include:
- profile: soxl_soxx_trend_income
service: interactive-brokers-quant-live-u15998061-service
- profile: tqqq_growth_income
service: interactive-brokers-quant-live-u16608560-service
- profile: global_etf_rotation
service: interactive-brokers-quant-live-u18308207-service
- profile: russell_top50_leader_rotation
service: interactive-brokers-quant-live-u18336562-service
steps:
- name: Authenticate to Google Cloud
uses: google-github-actions/auth@v3
with:
workload_identity_provider: ${{ env.GCP_WORKLOAD_IDENTITY_PROVIDER }}
service_account: ${{ env.GCP_WORKLOAD_IDENTITY_SERVICE_ACCOUNT }}

- name: Set up gcloud
uses: google-github-actions/setup-gcloud@v3

- name: Collect no-order reconciliation candidate
env:
SERVICE: ${{ matrix.service }}
PROFILE: ${{ matrix.profile }}
run: |
set -euo pipefail
service_url="$(gcloud run services describe "$SERVICE" --project "$GCP_PROJECT_ID" --region "$GCP_REGION" --format='value(status.url)')"
test -n "$service_url"
identity_token="$(gcloud auth print-identity-token --audiences="$service_url")"
mkdir -p reports
curl --fail --silent --show-error --max-time 90 \
--request POST \
--header "Authorization: Bearer ${identity_token}" \
--output "reports/${PROFILE}.json" \
"${service_url}/reconcile"
jq -e --arg profile "$PROFILE" '
.schema_version == "ibkr_reconciliation_candidate.v1"
and .evidence.platform_id == "ibkr"
and .evidence.strategy_profile == $profile
and (.recovery_blockers | type == "array")
' "reports/${PROFILE}.json" >/dev/null
jq -r '[.permits_active_lkg, .expected_digests_configured, (.recovery_blockers | length)] | @tsv' \
"reports/${PROFILE}.json" | awk -F '\t' '{print "candidate_collected permits_active_lkg=" $1 ", expected_digests_configured=" $2 ", blockers=" $3}'

- name: Retain redacted candidate
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7
with:
name: ibkr-reconciliation-${{ matrix.profile }}-${{ github.run_id }}
path: reports/${{ matrix.profile }}.json
if-no-files-found: error
retention-days: 30
11 changes: 11 additions & 0 deletions docs/ibkr_reconciliation_baseline_enrollment.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,14 @@ URI、部署 Cloud Run、连接券商或提交订单。实际启用仍需要单
令牌被试图发送到普通管理站路径。每一种情况都必须抛出拒绝或返回没有
`transition_plan` 的结果;测试同时断言 `state_write_attempted=false`。这让后续接入
最小权限 CAS 时能持续证明“异常只能保持冻结,不能意外恢复实盘”。

## 收集两份候选收据

`Collect IBKR Reconciliation Evidence` 是显式手动工作流。它仅以部署身份调用每个
冻结 Cloud Run 服务的 `POST /reconcile`,并在 30 天内保留脱敏
`ibkr_reconciliation_candidate.v1` artifact。它不调用 `/run`、不修改 GitHub 变量、
不发布状态账本,也不发送任何订单。

同一目标至少应在相隔一分钟的两次手动运行中得到候选,才能交给
`build_reconciliation_baseline_candidate.py`。工作流的成功只说明读取和收据格式正常;
候选仍可能因为未配置预期摘要或账本差异而正确保持阻断。