Skip to content

fix: harden IBKR strategy switch contract - #199

Merged
Pigbibi merged 2 commits into
mainfrom
codex/ibkr-switch-contract-hardening-20260803
Aug 3, 2026
Merged

fix: harden IBKR strategy switch contract#199
Pigbibi merged 2 commits into
mainfrom
codex/ibkr-switch-contract-hardening-20260803

Conversation

@Pigbibi

@Pigbibi Pigbibi commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Summary

  • make all US live scheduler profiles IBKR-compatible Mon-Fri triggers while preserving strategy-owned cadence gates
  • map required feature snapshot + manifest artifacts during strategy switches and clear stale snapshot fields for non-snapshot strategies
  • fail closed for the HK dividend-quality snapshot strategy until a production artifact route is configured
  • run the pinned IBKR deployment planner before any GitHub variable write
  • refresh the strategy switch console assets and add regression coverage
  • refresh the derived internal dependency matrix to match current consumer main pins (required after external repos changed following the PR base)

Validation

  • python3 -m unittest discover -s python/tests (131 passed)
  • python3 python/scripts/build_config.py --check
  • python3 python/scripts/runtime_settings.py validate
  • current-main internal dependency matrix strict check (30 files, 0 issues)
  • actionlint
  • Node 22 worker and generated asset syntax checks
  • Python package build
  • no-write preview with current IBKR main planner:
    • PASS: TQQQ, SOXL, NASDAQ/S&P DCA, IBIT DCA, Global ETF Rotation, Russell Top50, HK ETF Tactical Rotation
    • EXPECTED_BLOCK: HK Dividend Quality snapshot (production snapshot route not configured)

Safety

  • no broker execution endpoint was called
  • candidate deployment plans are validated before variable mutation
  • planner output and repository variable values are not printed

Pigbibi and others added 2 commits August 3, 2026 13:41
Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Codex <noreply@openai.com>
@Pigbibi
Pigbibi merged commit 4a7dd64 into main Aug 3, 2026
6 checks passed
@Pigbibi
Pigbibi deleted the codex/ibkr-switch-contract-hardening-20260803 branch August 3, 2026 05:49

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e6df24c860

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment on lines +426 to +429
gh variable list \
--repo "${TARGET_REPOSITORY}" \
--json name,value \
> "${repository_variables_file}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Merge environment-scoped variables into the IBKR preflight

When an IBKR switch uses the supported variable_scope=environment path, the earlier inventory step reads CLOUD_RUN_SERVICE_TARGETS_JSON from that GitHub Environment, but this step fetches only repository variables. _candidate_environment therefore runs the planner without any unchanged environment-scoped settings, so it can reject a valid deployment or approve a state different from the one the sync workflow will receive. Fetch the selected environment's variables as well and merge them over repository variables before applying the candidate assignments.

Useful? React with 👍 / 👎.

Comment on lines +793 to +799
snapshot_path = snapshot_path.strip() if isinstance(snapshot_path, str) else ""
manifest_path = manifest_path.strip() if isinstance(manifest_path, str) else ""
if explicit and not feature_snapshot and (snapshot_path or manifest_path):
raise ValueError(
f"strategy {strategy_profile!r} does not accept feature snapshot artifacts"
)
if bool(snapshot_path) != bool(manifest_path):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Validate explicit snapshot overrides as GCS URIs

For a snapshot strategy, explicit values such as /tmp/snapshot.csv and /tmp/snapshot.csv.manifest.json pass this path because only presence is checked. This bypasses the new catalog contract in build_config.validate, which requires snapshot artifacts to be gs:// URIs, and non-IBKR platforms such as LongBridge have no planner preflight to catch the invalid route before it is written. Apply the same URI validation to explicit overrides.

Useful? React with 👍 / 👎.

Comment on lines +410 to +411
- name: Preflight IBKR deployment plan
if: env.PLATFORM == 'ibkr' && env.SERVICE_TARGETS_MODE != 'off'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Preflight IBKR switches in service-targets-off mode

When service_targets_mode=off is used against an IBKR repository that has no existing CLOUD_RUN_SERVICE_TARGETS_JSON, the earlier bypass guard permits the operation, but this condition skips the deployment planner entirely and apply=true proceeds directly to GitHub variable writes. This leaves the supported single-service/no-inventory path outside the new fail-closed contract and can publish live settings that the IBKR planner would reject; either synthesize a candidate inventory for this path or reject IBKR writes when no planner can run.

Useful? React with 👍 / 👎.

Comment thread platform-config.json
Comment on lines 709 to 711
"allowed_execution_modes": [
"live",
"paper",
"dry_run"

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Make the paper snapshot profile switchable from the console

The catalog exposes hk_low_vol_dividend_quality_snapshot as paper-capable, so the console permits that selection, but its generated switch inputs have no snapshot-path controls and therefore omit both artifact variables. Because the same profile is marked feature_snapshot.required=true without catalog paths, build_runtime_switch.py rejects every such console dispatch with requires feature snapshot path and manifest path. Supply a configured paper artifact, add console inputs for the pair, or stop advertising paper mode until the route exists.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant