diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 5c8e589..3f9a4ba 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -70,6 +70,7 @@ - [x] `generate_v2_formal_report()` 已带 `generated_at` 时间戳。 - [x] `freeze_checklist()` 已列出正式冻结验收所需状态。 - [x] 冻结清单包含 review_url/reviewed_by 占位。 +- [x] `governance` CLI 可输出治理清单。 - [x] formal 报告输出中已附带 freeze_checklist。 - [ ] 完成外部评审/日期戳后的正式冻结验收流程。 - [x] `formal` CLI 可输出正式验收前 JSON 报告。 @@ -94,4 +95,4 @@ 当前测试:`PYTHONPATH=src python3 -m unittest discover -s tests -v` -当前通过:116 tests OK(本阶段核心开发完成,外部冻结验收待治理流程)。 +当前通过:117 tests OK(本阶段核心开发完成,外部冻结验收待治理流程)。 diff --git a/CHANGELOG.md b/CHANGELOG.md index 9e18a54..4267809 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -70,7 +70,8 @@ - `generate_v2_formal_report()` 输出中附带 freeze_checklist; - `generate_v2_overview()` 输出 as_of; - Web 工作台显示外部评审完成状态; -- `freeze_checklist()` 增加 review_url/reviewed_by 占位字段。 +- `freeze_checklist()` 增加 review_url/reviewed_by 占位字段; +- `governance` CLI:输出正式冻结验收治理清单。 ## [0.1.0-rc1] - 2026-09-02 diff --git a/src/goratio/cli.py b/src/goratio/cli.py index acd210b..3ab9488 100644 --- a/src/goratio/cli.py +++ b/src/goratio/cli.py @@ -29,7 +29,11 @@ from .dataset import DataQualityError, prepare_market_data from .doctor import run_doctor from .episode_study import run_episode_evidence_bundle -from .formal_v2 import generate_v2_formal_report, generate_v2_overview +from .formal_v2 import ( + freeze_checklist, + generate_v2_formal_report, + generate_v2_overview, +) from .evidence_gates import run_v2_evidence_bundle from .episodes import ( build_forward_episodes, @@ -192,6 +196,9 @@ def build_parser() -> argparse.ArgumentParser: help="每笔 episode 附加的换月价差成本(基点)", ) + governance = commands.add_parser("governance", help="输出正式冻结验收治理清单") + governance.add_argument("--json", action="store_true", dest="as_json") + overview = commands.add_parser("overview", help="输出 v2 研究总览") overview.add_argument("--period", choices=("3y", "5y", "10y"), default="10y") overview.add_argument("--source", choices=("cn_public", "yahoo_futures"), default="cn_public") @@ -729,6 +736,16 @@ def make_web_payload(): f"协议:{PROTOCOL_V2_SPEC['id']};当前状态不可用:{snapshot['reason']}\n" ) return 0 + if args.command == "governance": + report = freeze_checklist() + if args.as_json: + stdout.write(json.dumps(report, ensure_ascii=False, indent=2, sort_keys=True) + "\n") + else: + stdout.write( + f"协议:{report['protocol_id']};外部评审:{report['external_review']};" + f"日期戳签名:{report['date_stamp_signed']}\n" + ) + return 0 if args.command == "update" and args.import_csv: raw = import_standard_csv( args.import_csv, diff --git a/tests/test_cli.py b/tests/test_cli.py index 9098bd5..9366e71 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -461,5 +461,18 @@ def test_overview_command_returns_v2_overview(self) -> None: self.assertEqual(payload["protocol"], "goratio-2a-v1") self.assertEqual(payload["overview"]["overall_status"], "insufficient_data") + def test_governance_command_returns_freeze_checklist(self) -> None: + output = io.StringIO() + exit_code = main( + ["governance", "--json"], + stdout=output, + stderr=io.StringIO(), + ) + + payload = json.loads(output.getvalue()) + self.assertEqual(exit_code, 0) + self.assertEqual(payload["protocol_id"], "goratio-2a-v1") + self.assertFalse(payload["external_review"]) + if __name__ == "__main__": unittest.main() \ No newline at end of file