From e9fd133db93db09147c41f19d9cb892f5fc0a74e Mon Sep 17 00:00:00 2001 From: Pigbibi <20649888+Pigbibi@users.noreply.github.com> Date: Fri, 3 Jul 2026 17:34:08 +0800 Subject: [PATCH] Add QSL bundle 2026.07.1 and checker transition tests Co-Authored-By: Codex --- compat/bundles/2026.07.1.toml | 12 +++ docs/qsl_compat_upgrade.md | 39 +++++---- python/tests/test_qsl_compat_checker.py | 104 ++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 14 deletions(-) create mode 100644 compat/bundles/2026.07.1.toml create mode 100644 python/tests/test_qsl_compat_checker.py diff --git a/compat/bundles/2026.07.1.toml b/compat/bundles/2026.07.1.toml new file mode 100644 index 0000000..35853a2 --- /dev/null +++ b/compat/bundles/2026.07.1.toml @@ -0,0 +1,12 @@ +name = "2026.07.1" +description = "Phase-2 QSL compatibility bundle (strict transition warning convergence)" +created_at = "2026-07-03" + +[repos] +QuantPlatformKit = "7032cde4547e7ec59af15df8935d142461a77051" +UsEquityStrategies = "9f0e5e2deca8a9c16d711eb4772f08a7901da101" +HkEquityStrategies = "00dd0e5b62a6fa65bd9262e15c083468e8b8c191" +CnEquityStrategies = "c6d680d6d2690fe6ff77872355719751c021f9a0" +CryptoStrategies = "c0203b66746efb63e79f4d4bc9a65758c342817e" +QuantStrategyPlugins = "1f3a27b8fd83d71b583f4f5160a748e95fbefaa1" +MarketSignalSources = "bda8ab10b80a646e4b579ef4c0d5dfe90776e908" diff --git a/docs/qsl_compat_upgrade.md b/docs/qsl_compat_upgrade.md index 324122b..a1135fd 100644 --- a/docs/qsl_compat_upgrade.md +++ b/docs/qsl_compat_upgrade.md @@ -1,11 +1,11 @@ -# QSL Compatibility & Upgrade Checklist (Central Manifest Phase-1) +# QSL Compatibility & Upgrade Checklist (Central Manifest) -This repository carries the first version of the QSL central compatibility manifest. +This repository defines the QSL central compatibility manifest and its upgrade policy. ## 文件结构 - `compat/bundles/*.toml` - - 每个 bundle 用 Calendar Version 命名(当前:`2026.07.0`)。 + - 每个 bundle 用 Calendar Version 命名(当前:`2026.07.1`)。 - 记录 QSL 管控的固定内部仓库提交。 - `compat/repo-tiers.toml` - 记录仓库层级(`core/strategy-lib/pipeline/runtime/ops`)与升级 ring 规则。 @@ -26,8 +26,8 @@ This repository carries the first version of the QSL central compatibility manif ```toml [qsl] -bundle = "2026.07.0" # 选择要对齐的 central bundle -compat = "2026.07.0" # 兼容检查入口(与 bundle 相同) +bundle = "2026.07.1" # 选择要对齐的 central bundle +compat = "2026.07.1" # 兼容检查入口(与 bundle 相同) tier = "ops/tooling" upgrade_ring = "ring_e" allow_legacy = false # 需要临时兼容时可先放开 @@ -43,15 +43,26 @@ python scripts/check_qsl_compat.py --repo-root . --non-strict python scripts/render_qsl_dependency_graph.py --repo-root . --format md ``` -说明:默认脚本会输出错误并以非零退出码返回;`--non-strict` 仅用于本地快速预览。 +说明: +- 默认脚本执行严格模式:`forbidden short/invalid`、`bundle pin mismatch`、`@main` 均为 issue(非零退出)。 +- 阶段过渡仓可设置 `enforce_bundle = false`(建议限时): + - `forbidden short/invalid` 与 `bundle pin mismatch` 降级为 warning。 + - `forbidden ref 'main'` 始终为 issue,不降级。 +- `--non-strict` 仅用于本地快速预览,不作为发布门禁依据。 ## 当前中心兼容基线 -- Bundle: `2026.07.0` -- QPK: `0063af3b4a974650ea58a7d3f26dd1b94f65d3e8` -- UsEquityStrategies: `46887bc3f5454d5b59623b1f5efb7c65912c6b8b` -- HkEquityStrategies: `61993bf261aeccf64b5a75428b9405f4e1d1d682` -- CnEquityStrategies: `ffbdf7303179ba6e7f9d3e28c21202f77e04762c` -- CryptoStrategies: `8039ddddde7634ad3615496c9b79d2918996938c` -- QuantStrategyPlugins: `6c10aef8989f52d82571e676092b14d315401989` -- MarketSignalSources: `ea8771b6b65f356e7edc4a2b08cd621186726646` +- Bundle: `2026.07.1` +- QPK: `7032cde4547e7ec59af15df8935d142461a77051` +- UsEquityStrategies: `9f0e5e2deca8a9c16d711eb4772f08a7901da101` +- HkEquityStrategies: `00dd0e5b62a6fa65bd9262e15c083468e8b8c191` +- CnEquityStrategies: `c6d680d6d2690fe6ff77872355719751c021f9a0` +- CryptoStrategies: `c0203b66746efb63e79f4d4bc9a65758c342817e` +- QuantStrategyPlugins: `1f3a27b8fd83d71b583f4f5160a748e95fbefaa1` +- MarketSignalSources: `bda8ab10b80a646e4b579ef4c0d5dfe90776e908` + +## Phase-2 Transition Warning 收敛路径 + +1. 发现 phase-1 之后的 drift/main 问题先通过 `--non-strict` 定位;提交修复前确保日志可回放。 +2. 过渡仓可短期开启 `enforce_bundle = false`,仅将 drift / short SHA 降级为 warning。 +3. 版本发布前将仓库切回 `enforce_bundle = true`,并清零 transition warning。 diff --git a/python/tests/test_qsl_compat_checker.py b/python/tests/test_qsl_compat_checker.py new file mode 100644 index 0000000..ebf2ece --- /dev/null +++ b/python/tests/test_qsl_compat_checker.py @@ -0,0 +1,104 @@ +from __future__ import annotations + +import importlib.util +import sys +import tempfile +import unittest +from pathlib import Path + +ROOT = Path(__file__).resolve().parents[2] +MODULE_PATH = ROOT / "scripts" / "check_qsl_compat.py" +MODULE_SPEC = importlib.util.spec_from_file_location("check_qsl_compat", MODULE_PATH) +check_qsl_compat = importlib.util.module_from_spec(MODULE_SPEC) +assert MODULE_SPEC.loader is not None +sys.modules[MODULE_SPEC.name] = check_qsl_compat +MODULE_SPEC.loader.exec_module(check_qsl_compat) + + +class QSLCompatCheckerTest(unittest.TestCase): + def _make_repo_root(self, qsl_toml: str, pyproject: str) -> Path: + root = Path(tempfile.mkdtemp()) + (root / "qsl.toml").write_text(qsl_toml, encoding="utf-8") + (root / "pyproject.toml").write_text(pyproject, encoding="utf-8") + return root + + def _write_bundle(self, compat_root: Path, bundle_name: str, repos: dict[str, str]) -> None: + bundle_path = compat_root / "compat" / "bundles" / f"{bundle_name}.toml" + bundle_path.parent.mkdir(parents=True, exist_ok=True) + block = [f'name = "{bundle_name}"', "[repos]"] + for repo, ref in repos.items(): + block.append(f'{repo} = "{ref}"') + bundle_path.write_text("\n".join(block) + "\n", encoding="utf-8") + + def test_root_compat_bundle_and_ring_schema(self): + with tempfile.TemporaryDirectory() as workspace: + compat_root = Path(workspace) + self._write_bundle( + compat_root, + "2026.07.1", + {"QuantPlatformKit": "7032cde4547e7ec59af15df8935d142461a77051"}, + ) + repo_root = self._make_repo_root( + qsl_toml=( + "tier = \"ops/tooling\"\n" + "ring = \"ring_e\"\n" + "[compat]\n" + 'bundle = "2026.07.1"\n' + ), + pyproject=( + "dependencies = [\n" + ' "quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@7032cde4547e7ec59af15df8935d142461a77051"\n' + "]\n" + ), + ) + + ok, issues, warnings, notes = check_qsl_compat._check(repo_root=repo_root, compat_root=compat_root) + + self.assertTrue(ok) + self.assertEqual(issues, []) + self.assertEqual(warnings, []) + self.assertIn("bundle=2026.07.1", notes) + self.assertIn("upgrade_ring=ring_e", notes) + + def test_not_enforced_bundle_reports_warning_for_short_sha_and_mismatch_but_main_stays_issue(self): + with tempfile.TemporaryDirectory() as workspace: + compat_root = Path(workspace) + self._write_bundle( + compat_root, + "2026.07.1", + { + "QuantPlatformKit": "7032cde4547e7ec59af15df8935d142461a77051", + "UsEquityStrategies": "9f0e5e2deca8a9c16d711eb4772f08a7901da101", + }, + ) + repo_root = self._make_repo_root( + qsl_toml=( + "tier = \"ops/tooling\"\n" + "ring = \"ring_e\"\n" + "[compat]\n" + 'bundle = "2026.07.1"\n' + "enforce_bundle = false\n" + ), + pyproject=( + "dependencies = [\n" + ' "quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@abc123"\n' + ' "quant-platform-kit @ git+https://github.com/QuantStrategyLab/QuantPlatformKit.git@' + 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"\n' + ' "us-equity-strategies @ https://github.com/QuantStrategyLab/UsEquityStrategies.git?rev=main"\n' + "]\n" + ), + ) + + ok, issues, warnings, notes = check_qsl_compat._check(repo_root=repo_root, compat_root=compat_root) + + self.assertFalse(ok) + self.assertEqual(len(issues), 1) + self.assertIn("forbidden ref 'main'", issues[0]) + self.assertEqual(len(warnings), 2) + self.assertTrue(any("forbidden short/invalid ref 'abc123'" in warning for warning in warnings)) + self.assertTrue(any("bundle pin mismatch for QuantPlatformKit" in warning for warning in warnings)) + self.assertEqual(notes[0], "qsl=" + str(repo_root / "qsl.toml")) + + +if __name__ == "__main__": + unittest.main()