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
2 changes: 1 addition & 1 deletion README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ python3 -m unittest discover -s python/tests -v
推荐流程:

1. 第一次运行保持 `apply=false`,只看 preview。
2. 确认 `repository`、`environment`、`strategy_profile`、`service_name`、`execution_mode` 和插件挂载正确
2. 确认 `repository`、`environment`、`strategy_profile`、`service_name`、`execution_mode`,以及由 `strategy_profile` 派生的 `scheduler` / 插件挂载正确
3. 再运行 `apply=true`,并填写 `confirm_apply=APPLY`,写入目标仓库变量。
4. 如果要让平台仓同步 Cloud Run 环境,额外设置 `trigger_platform_sync=true`,并填写 `confirm_apply=APPLY_AND_SYNC`。

Expand Down
2 changes: 2 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

QuantRuntimeSettings is a **config-driven** runtime settings package that serves as the central control plane for QuantStrategyLab deployments. It defines versioned strategy-to-platform assignments and hosts a Cloudflare Workers-based strategy switch console.

The generated `RUNTIME_TARGET_JSON` payload is the canonical desired-state contract for a switch. `scheduler` and plugin mount outputs are derived from `strategy_profile`, while `execution_mode` is part of the target and validated against strategy-profile policy.

The repository has a **three-tier architecture** built around a single source of truth:

```
Expand Down
19 changes: 19 additions & 0 deletions python/tests/test_runtime_settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -710,6 +710,7 @@ def test_build_switch_target_defaults_longbridge_sg_tqqq(self):
"tqqq_growth_income/plugins/market_regime_control/latest_signal.json",
)
self.assertEqual(plugin_payload["strategy_plugins"][0]["expected_schema_version"], "market_regime_control.v1")
self.assertEqual(runtime_settings.validate_target(target), [])

def test_build_switch_target_uses_fork_repository_overrides(self):
parser = build_runtime_switch.build_parser()
Expand Down Expand Up @@ -1405,6 +1406,24 @@ def test_runtime_target_scheduler_rejects_invalid_cron_shape(self):
runtime_settings.validate_target(target),
)

def test_runtime_target_scheduler_rejects_extra_fields(self):
_, target = self.load_target("examples/targets/longbridge/hk_combo.example.json")
target["runtime_target"]["scheduler"]["offset_minutes"] = 10

self.assertIn(
"runtime_target.scheduler.offset_minutes is unsupported",
runtime_settings.validate_target(target),
)

def test_runtime_target_scheduler_requires_timezone(self):
_, target = self.load_target("examples/targets/longbridge/hk_combo.example.json")
target["runtime_target"]["scheduler"].pop("timezone")

self.assertIn(
"runtime_target.scheduler.timezone must be a non-empty string",
runtime_settings.validate_target(target),
)

def test_build_switch_target_rejects_secret_extra_variable(self):
parser = build_runtime_switch.build_parser()
args = parser.parse_args(
Expand Down
18 changes: 18 additions & 0 deletions schemas/runtime-target.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,24 @@
"type": "string",
"enum": ["live", "paper", "dry_run"]
},
"scheduler": {
"type": "object",
"additionalProperties": false,
"properties": {
Comment on lines +80 to +83

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 Require complete scheduler payloads in schema

When a target is validated only through schemas/runtime-target.schema.json, a present runtime_target.scheduler can omit timezone, main_time, probe_time, or precheck_time and still pass because this new object has no required list. The Python validator rejects the same payload (validate_runtime_target requires a non-empty timezone and all three time fields), so schema-based consumers can accept targets that later fail runtime_settings.py validate or platform parsing; add the scheduler fields to required to keep the shared schema consistent with the runtime contract.

Useful? React with 👍 / 👎.

"timezone": {
"type": "string"
},
"main_time": {
"type": "string"
},
"probe_time": {
"type": "string"
},
"precheck_time": {
"type": "string"
}
Comment on lines +87 to +95

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 Reject malformed scheduler times in the schema

For schema-only validation paths, these new scheduler time fields accept any string, so values such as "45" or "not a cron" pass the shared schema even though runtime_settings.validate_target rejects anything that is not exactly 2 time fields or 5 cron fields. Since schemas/ is documented as shared between Python and JS consumers, this can let an invalid schedule through a schema-based switch preview/apply flow and fail only later in the Python/platform validator; constrain these fields with the same shape that the runtime validator enforces.

Useful? React with 👍 / 👎.

}
},
"execution_windows": {
"type": "object",
"additionalProperties": false,
Expand Down
Loading