1616 list_contracts ,
1717 show_artifact ,
1818)
19+ from governance_ledger .replay import (
20+ replay_admissibility ,
21+ replay_governance_compilation ,
22+ verify_authority_lineage ,
23+ )
1924from governance_ledger .summary import (
2025 build_pr_summary ,
2126 format_publish_summary ,
@@ -69,6 +74,31 @@ def main(argv: Sequence[str] | None = None) -> int:
6974 show_parser .add_argument ("path" )
7075 show_parser .add_argument ("--json" , action = "store_true" )
7176
77+ replay_authority_parser = subparsers .add_parser (
78+ "replay-authority" ,
79+ help = "replay governance source into compilation report and authority contract" ,
80+ )
81+ replay_authority_parser .add_argument ("--source" , required = True )
82+ replay_authority_parser .add_argument ("--report" )
83+ replay_authority_parser .add_argument ("--contract" )
84+ replay_authority_parser .add_argument ("--json" , action = "store_true" )
85+
86+ replay_execution_parser = subparsers .add_parser (
87+ "replay-execution" ,
88+ help = "replay deterministic admissibility from authority contract and execution state" ,
89+ )
90+ replay_execution_parser .add_argument ("--contract" , required = True )
91+ replay_execution_parser .add_argument ("--execution-state" , required = True )
92+ replay_execution_parser .add_argument ("--json" , action = "store_true" )
93+
94+ verify_lineage_parser = subparsers .add_parser (
95+ "verify-lineage" ,
96+ help = "verify authority provenance lineage against an optional compilation report" ,
97+ )
98+ verify_lineage_parser .add_argument ("--contract" , required = True )
99+ verify_lineage_parser .add_argument ("--report" )
100+ verify_lineage_parser .add_argument ("--json" , action = "store_true" )
101+
72102 args = parser .parse_args (argv )
73103
74104 if args .command == "run" :
@@ -115,11 +145,29 @@ def main(argv: Sequence[str] | None = None) -> int:
115145 result = check_validation_directory (args .generated_dir )
116146 elif args .command == "list" :
117147 result = list_contracts (args .contracts_dir )
148+ elif args .command == "replay-authority" :
149+ result = replay_governance_compilation (
150+ source_text = Path (args .source ).read_text (encoding = "utf-8" ),
151+ expected_report = _read_json_arg (args .report ),
152+ expected_contract = _read_json_arg (args .contract ),
153+ )
154+ elif args .command == "replay-execution" :
155+ result = replay_admissibility (
156+ authority_contract = _read_json_arg (args .contract ),
157+ execution_state = _read_json_arg (args .execution_state ),
158+ )
159+ elif args .command == "verify-lineage" :
160+ result = verify_authority_lineage (
161+ authority_contract = _read_json_arg (args .contract ),
162+ compilation_report = _read_json_arg (args .report ),
163+ )
118164 else :
119165 result = show_artifact (args .path )
120166
121167 if getattr (args , "json" , False ):
122168 print (json .dumps (result , indent = 2 , sort_keys = True ))
169+ if args .command in {"replay-authority" , "replay-execution" , "verify-lineage" }:
170+ return 0 if _replay_ok (result ) else 1
123171 elif args .command == "run" :
124172 print (format_run_summary (result ))
125173 elif args .command == "publish" :
@@ -131,6 +179,9 @@ def main(argv: Sequence[str] | None = None) -> int:
131179 print (format_contract_list (result ))
132180 elif args .command == "show" :
133181 print (format_artifact (args .path , result ))
182+ elif args .command in {"replay-authority" , "replay-execution" , "verify-lineage" }:
183+ print (_format_replay_summary (result ))
184+ return 0 if _replay_ok (result ) else 1
134185 else :
135186 print (
136187 "\n " .join (
@@ -148,5 +199,37 @@ def main(argv: Sequence[str] | None = None) -> int:
148199 return 0
149200
150201
202+ def _read_json_arg (path : str | None ) -> dict | None :
203+ if path is None :
204+ return None
205+ return json .loads (Path (path ).read_text (encoding = "utf-8" ))
206+
207+
208+ def _replay_ok (result : dict ) -> bool :
209+ if "replay_verified" in result :
210+ return bool (result ["replay_verified" ])
211+ if "lineage_verified" in result :
212+ return bool (result ["lineage_verified" ])
213+ return not result .get ("diagnostics" )
214+
215+
216+ def _format_replay_summary (result : dict ) -> str :
217+ status = "VERIFIED" if _replay_ok (result ) else "FAILED"
218+ lines = [
219+ "[Governance Replay]" ,
220+ "" ,
221+ f"Status: { status } " ,
222+ ]
223+ if result .get ("authority_ref" ):
224+ lines .append (f"Authority: { result ['authority_ref' ]} " )
225+ if result .get ("contract_hash" ):
226+ lines .append (f"Contract hash: { result ['contract_hash' ]} " )
227+ diagnostics = result .get ("diagnostics" ) or []
228+ if diagnostics :
229+ lines .extend (["" , "Diagnostics:" ])
230+ lines .extend (f" { item ['text' ]} " for item in diagnostics )
231+ return "\n " .join (lines )
232+
233+
151234if __name__ == "__main__" :
152235 raise SystemExit (main ())
0 commit comments