code-mower 0.5.0b5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (185) hide show
  1. code_mower/__init__.py +3 -0
  2. code_mower/adapters/__init__.py +39 -0
  3. code_mower/adapters/_base.py +148 -0
  4. code_mower/adapters/cursor_bugbot.py +97 -0
  5. code_mower/adapters/gitar.py +111 -0
  6. code_mower/adapters/greptile.py +191 -0
  7. code_mower/adapters/qodo.py +140 -0
  8. code_mower/antigravity_cli_audit_pr.py +241 -0
  9. code_mower/audit_handoff_log.py +345 -0
  10. code_mower/audit_labeler_lib.py +311 -0
  11. code_mower/audit_progress.py +203 -0
  12. code_mower/blind_review_artifacts.py +562 -0
  13. code_mower/blind_review_coordinator.py +276 -0
  14. code_mower/bootstrap.py +524 -0
  15. code_mower/builder_experiment.py +539 -0
  16. code_mower/calibration/__init__.py +181 -0
  17. code_mower/calibration/arms.py +267 -0
  18. code_mower/calibration/auto_discovery.py +348 -0
  19. code_mower/calibration/commands.py +192 -0
  20. code_mower/calibration/context_inputs.py +199 -0
  21. code_mower/calibration/corpus.py +91 -0
  22. code_mower/calibration/evidence.py +20 -0
  23. code_mower/calibration/evidence_report.py +360 -0
  24. code_mower/calibration/identity.py +27 -0
  25. code_mower/calibration/metrics.py +18 -0
  26. code_mower/calibration/overlap.py +103 -0
  27. code_mower/calibration/planning.py +309 -0
  28. code_mower/calibration/policy.py +207 -0
  29. code_mower/calibration/results.py +315 -0
  30. code_mower/calibration/run_results.py +147 -0
  31. code_mower/calibration/run_status.py +64 -0
  32. code_mower/calibration/runner.py +360 -0
  33. code_mower/calibration/truth.py +188 -0
  34. code_mower/calibration/value_report.py +142 -0
  35. code_mower/checks.py +402 -0
  36. code_mower/claude_audit_pr.py +1126 -0
  37. code_mower/claude_cli_bounce.py +303 -0
  38. code_mower/claude_cli_environment.py +73 -0
  39. code_mower/clear_stale.py +374 -0
  40. code_mower/cli.py +537 -0
  41. code_mower/cloud.py +674 -0
  42. code_mower/cloud_client/__init__.py +173 -0
  43. code_mower/cloud_client/bundle.py +155 -0
  44. code_mower/cloud_client/doctor.py +206 -0
  45. code_mower/cloud_client/dogfood.py +78 -0
  46. code_mower/cloud_client/endpoints.py +114 -0
  47. code_mower/cloud_client/errors.py +7 -0
  48. code_mower/cloud_client/events.py +278 -0
  49. code_mower/cloud_client/export.py +272 -0
  50. code_mower/cloud_client/git_metadata.py +46 -0
  51. code_mower/cloud_client/manifest.py +39 -0
  52. code_mower/cloud_client/operations.py +448 -0
  53. code_mower/cloud_client/reports.py +45 -0
  54. code_mower/cloud_client/setup.py +205 -0
  55. code_mower/cloud_client/upload.py +97 -0
  56. code_mower/code_mower_calibration.py +598 -0
  57. code_mower/code_mower_context_packs.py +591 -0
  58. code_mower/code_mower_merge.py +227 -0
  59. code_mower/code_mower_telemetry.py +561 -0
  60. code_mower/coderabbit_cli_audit_pr.py +526 -0
  61. code_mower/codex_audit_env_preflight.py +220 -0
  62. code_mower/codex_audit_pr.py +1738 -0
  63. code_mower/codex_audit_schema_smoke.py +160 -0
  64. code_mower/codex_audit_verdict.schema.json +44 -0
  65. code_mower/config.py +655 -0
  66. code_mower/doctor.py +161 -0
  67. code_mower/doctor_checks/__init__.py +104 -0
  68. code_mower/doctor_checks/cloud.py +129 -0
  69. code_mower/doctor_checks/common.py +215 -0
  70. code_mower/doctor_checks/github.py +128 -0
  71. code_mower/doctor_checks/github_actions.py +11 -0
  72. code_mower/doctor_checks/github_actions_cost.py +99 -0
  73. code_mower/doctor_checks/github_actions_cost_summary.py +111 -0
  74. code_mower/doctor_checks/github_actions_failure_annotations.py +27 -0
  75. code_mower/doctor_checks/github_actions_failure_models.py +47 -0
  76. code_mower/doctor_checks/github_actions_failure_scan.py +200 -0
  77. code_mower/doctor_checks/github_actions_failure_selection.py +63 -0
  78. code_mower/doctor_checks/github_actions_failures.py +103 -0
  79. code_mower/doctor_checks/github_actions_permissions.py +55 -0
  80. code_mower/doctor_checks/github_api.py +79 -0
  81. code_mower/doctor_checks/github_branch.py +56 -0
  82. code_mower/doctor_checks/github_config.py +25 -0
  83. code_mower/doctor_checks/github_provider.py +61 -0
  84. code_mower/doctor_checks/github_repo.py +120 -0
  85. code_mower/doctor_checks/groups.py +36 -0
  86. code_mower/doctor_checks/models.py +96 -0
  87. code_mower/doctor_checks/output.py +86 -0
  88. code_mower/doctor_checks/presets.py +64 -0
  89. code_mower/doctor_checks/privacy.py +20 -0
  90. code_mower/doctor_checks/provider_api_model.py +138 -0
  91. code_mower/doctor_checks/provider_api_model_openai.py +29 -0
  92. code_mower/doctor_checks/provider_api_model_profiles.py +137 -0
  93. code_mower/doctor_checks/provider_env.py +113 -0
  94. code_mower/doctor_checks/provider_env_required.py +56 -0
  95. code_mower/doctor_checks/provider_env_tokens.py +100 -0
  96. code_mower/doctor_checks/provider_local_cli.py +162 -0
  97. code_mower/doctor_checks/provider_local_cli_commands.py +47 -0
  98. code_mower/doctor_checks/provider_local_cli_probe_config.py +70 -0
  99. code_mower/doctor_checks/provider_probe.py +20 -0
  100. code_mower/doctor_checks/provider_probe_auth.py +52 -0
  101. code_mower/doctor_checks/provider_probe_evaluation.py +109 -0
  102. code_mower/doctor_checks/provider_probe_json.py +45 -0
  103. code_mower/doctor_checks/provider_probe_remediation.py +39 -0
  104. code_mower/doctor_checks/providers.py +159 -0
  105. code_mower/doctor_checks/registry.py +69 -0
  106. code_mower/doctor_checks/runner.py +188 -0
  107. code_mower/doctor_checks/runtime.py +89 -0
  108. code_mower/doctor_checks/runtime_github_auth.py +148 -0
  109. code_mower/gemini_cli_audit_pr.py +897 -0
  110. code_mower/hermes_cli_audit_pr.py +436 -0
  111. code_mower/init.py +888 -0
  112. code_mower/lane_configs/__init__.py +37 -0
  113. code_mower/lane_configs/aider.py +32 -0
  114. code_mower/lane_configs/antigravity_cli.py +35 -0
  115. code_mower/lane_configs/claude.py +35 -0
  116. code_mower/lane_configs/codex.py +32 -0
  117. code_mower/lane_configs/devin.py +33 -0
  118. code_mower/lane_configs/gemini_cli.py +35 -0
  119. code_mower/lane_configs/hermes_cli.py +35 -0
  120. code_mower/lane_configs/local_llm.py +31 -0
  121. code_mower/local_llm_audit_pr.py +1364 -0
  122. code_mower/local_llm_bakeoff.py +458 -0
  123. code_mower/local_llm_calibration.py +441 -0
  124. code_mower/local_llm_profiles.py +66 -0
  125. code_mower/migration.py +508 -0
  126. code_mower/migration_install.py +292 -0
  127. code_mower/migration_mirror.py +392 -0
  128. code_mower/migration_readiness.py +237 -0
  129. code_mower/migration_rehearsal.py +718 -0
  130. code_mower/next_steps.py +441 -0
  131. code_mower/package.py +673 -0
  132. code_mower/package_content.py +444 -0
  133. code_mower/package_manifest.py +452 -0
  134. code_mower/package_paths.py +53 -0
  135. code_mower/package_rendering.py +90 -0
  136. code_mower/package_static.py +585 -0
  137. code_mower/prompts.py +267 -0
  138. code_mower/provider_registry.py +469 -0
  139. code_mower/provider_runners/__init__.py +60 -0
  140. code_mower/provider_runners/comments.py +31 -0
  141. code_mower/provider_runners/git.py +46 -0
  142. code_mower/provider_runners/github_auth.py +61 -0
  143. code_mower/provider_runners/github_pr.py +120 -0
  144. code_mower/provider_runners/process.py +58 -0
  145. code_mower/provider_runners/repo_paths.py +23 -0
  146. code_mower/provider_runners/text_schema.py +41 -0
  147. code_mower/provider_runners/verdict_artifacts.py +103 -0
  148. code_mower/provider_runners/workspace.py +57 -0
  149. code_mower/release_readiness.py +549 -0
  150. code_mower/reviewer_metrics.py +389 -0
  151. code_mower/saas_reviewer_labeler.py +809 -0
  152. code_mower/secrets.py +89 -0
  153. code_mower/templates/builder-experiment.example.json +55 -0
  154. code_mower/templates/calibration-corpus.example.json +129 -0
  155. code_mower/templates/calibration-corpus.json +129 -0
  156. code_mower/templates/code-mower.example.yml +423 -0
  157. code_mower/templates/context-packs.example.json +150 -0
  158. code_mower/templates/lane_prompts/base-audit.md +22 -0
  159. code_mower/templates/lane_prompts/calibration-policy.md +21 -0
  160. code_mower/templates/lane_prompts/context-driven-quality.md +21 -0
  161. code_mower/templates/lane_prompts/docs-design.md +12 -0
  162. code_mower/templates/lane_prompts/generic-programming.md +21 -0
  163. code_mower/templates/lane_prompts/operability.md +22 -0
  164. code_mower/templates/lane_prompts/package-runtime.md +12 -0
  165. code_mower/templates/lane_prompts/security-threat-model.md +22 -0
  166. code_mower/templates/product-support/code_mower +216 -0
  167. code_mower/templates/product-support/code_mower_standalone_pin.env +7 -0
  168. code_mower/templates/product-support/code_mower_standalone_shadow.sh +151 -0
  169. code_mower/templates/product-support/run_claude_audit_pr.sh +32 -0
  170. code_mower/templates/product-support/run_codex_audit_pr.sh +32 -0
  171. code_mower/templates/product-support/safe_gh_comment.py +96 -0
  172. code_mower/templates/providers.yml +454 -0
  173. code_mower/templates/reviewer-spend.example.json +28 -0
  174. code_mower/templates/reviewer-value-report.example.md +20 -0
  175. code_mower/templates/workflows/private-standalone-shadow.yml.j2 +106 -0
  176. code_mower/templates/workflows/review-clear-stale.yml.j2 +83 -0
  177. code_mower/trailer_comment_labeler.py +207 -0
  178. code_mower/versioning.py +32 -0
  179. code_mower-0.5.0b5.dist-info/METADATA +302 -0
  180. code_mower-0.5.0b5.dist-info/RECORD +185 -0
  181. code_mower-0.5.0b5.dist-info/WHEEL +5 -0
  182. code_mower-0.5.0b5.dist-info/entry_points.txt +2 -0
  183. code_mower-0.5.0b5.dist-info/licenses/LICENSE +202 -0
  184. code_mower-0.5.0b5.dist-info/licenses/NOTICE +10 -0
  185. code_mower-0.5.0b5.dist-info/top_level.txt +1 -0
@@ -0,0 +1,598 @@
1
+ #!/usr/bin/env python3
2
+ """Plan and report Code Mower reviewer calibration pilots."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import json
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import Sequence
11
+
12
+ if __package__ in {None, ""}:
13
+ module_dir = Path(__file__).resolve().parent
14
+ sys.path.insert(0, str(module_dir.parent))
15
+ if module_dir.name == "code_mower": # pragma: no cover - extracted direct CLI.
16
+ from code_mower import code_mower_telemetry
17
+ from code_mower.calibration import (
18
+ RUN_STATUS_AUDIT_INPUT_INSUFFICIENT,
19
+ RUN_STATUS_BLOCKED,
20
+ RUN_STATUS_CATEGORY_ALIASES,
21
+ RUN_STATUS_INFRA_ERROR,
22
+ RUN_STATUS_PASS,
23
+ RUN_STATUS_UNKNOWN,
24
+ TRUTH_EXPECTATION_ALIASES,
25
+ TRUTH_EXPECTATION_KNOWN_BLOCKED,
26
+ TRUTH_EXPECTATION_KNOWN_CLEAN,
27
+ TRUTH_EXPECTATION_UNKNOWN,
28
+ AUDIT_INPUT_INSUFFICIENT_PATTERNS,
29
+ CALIBRATION_RUN_RESULTS_MODE,
30
+ CALIBRATION_RUN_RESULTS_SCHEMA,
31
+ build_pilot_plan,
32
+ command_lane_id as _command_lane_id,
33
+ command_metadata_for_run as _command_metadata_for_run,
34
+ context_pack_file_for_command as _context_pack_file_for_command,
35
+ default_arms,
36
+ build_overlap_report,
37
+ build_lane_policy_report,
38
+ build_reviewer_evidence_report,
39
+ build_value_report,
40
+ audit_input_insufficient_result as _audit_input_insufficient_result,
41
+ coderabbit_blocking_findings as _coderabbit_blocking_findings,
42
+ corpus_with_run_results,
43
+ expected_finding_matches as _expected_finding_matches,
44
+ infra_run_record as _infra_run_record,
45
+ load_corpus,
46
+ load_json_object as _load_json,
47
+ load_run_results as _load_run_results,
48
+ local_llm_profiles_from_command as _local_llm_profiles_from_command,
49
+ local_llm_findings as _local_llm_findings,
50
+ materialize_command as _materialize_command,
51
+ normalize_disposition as _normalize_disposition,
52
+ normalize_run_status_category as _normalize_run_status_category,
53
+ normalize_truth as _normalize_truth,
54
+ normalize_truth_expectation as _normalize_truth_expectation,
55
+ parse_int as _int,
56
+ parse_repo_path_map,
57
+ resolve_path_for_cwd as _resolve_path_for_cwd,
58
+ reviewer_id_from_command as _reviewer_id_from_command,
59
+ run_records_from_summary as _run_records_from_summary,
60
+ render_evidence_text,
61
+ render_overlap_text,
62
+ render_plan_text,
63
+ render_policy_text,
64
+ render_value_report_text,
65
+ safe_slug as _safe_slug,
66
+ summary_path_for_command as _summary_path_for_command,
67
+ text_from_timeout_stream as _text_from_timeout_stream,
68
+ truth_for_item as _truth_for_item,
69
+ default_code_mower_command as _default_code_mower_command,
70
+ load_summary as _load_summary,
71
+ result_command_dir as _result_command_dir,
72
+ run_calibration_commands,
73
+ utc_now_iso as _utc_now_iso,
74
+ write_json as _write_json,
75
+ )
76
+ from code_mower.calibration.auto_discovery import (
77
+ build_auto_discovered_corpus,
78
+ fetch_merged_prs_for_auto_discovery,
79
+ load_auto_discovery_input,
80
+ )
81
+ else:
82
+ from tools import code_mower_telemetry
83
+ from tools.calibration import (
84
+ RUN_STATUS_AUDIT_INPUT_INSUFFICIENT,
85
+ RUN_STATUS_BLOCKED,
86
+ RUN_STATUS_CATEGORY_ALIASES,
87
+ RUN_STATUS_INFRA_ERROR,
88
+ RUN_STATUS_PASS,
89
+ RUN_STATUS_UNKNOWN,
90
+ TRUTH_EXPECTATION_ALIASES,
91
+ TRUTH_EXPECTATION_KNOWN_BLOCKED,
92
+ TRUTH_EXPECTATION_KNOWN_CLEAN,
93
+ TRUTH_EXPECTATION_UNKNOWN,
94
+ AUDIT_INPUT_INSUFFICIENT_PATTERNS,
95
+ CALIBRATION_RUN_RESULTS_MODE,
96
+ CALIBRATION_RUN_RESULTS_SCHEMA,
97
+ build_pilot_plan,
98
+ command_lane_id as _command_lane_id,
99
+ command_metadata_for_run as _command_metadata_for_run,
100
+ context_pack_file_for_command as _context_pack_file_for_command,
101
+ default_arms,
102
+ build_overlap_report,
103
+ build_lane_policy_report,
104
+ build_reviewer_evidence_report,
105
+ build_value_report,
106
+ audit_input_insufficient_result as _audit_input_insufficient_result,
107
+ coderabbit_blocking_findings as _coderabbit_blocking_findings,
108
+ corpus_with_run_results,
109
+ expected_finding_matches as _expected_finding_matches,
110
+ infra_run_record as _infra_run_record,
111
+ load_corpus,
112
+ load_json_object as _load_json,
113
+ load_run_results as _load_run_results,
114
+ local_llm_profiles_from_command as _local_llm_profiles_from_command,
115
+ local_llm_findings as _local_llm_findings,
116
+ materialize_command as _materialize_command,
117
+ normalize_disposition as _normalize_disposition,
118
+ normalize_run_status_category as _normalize_run_status_category,
119
+ normalize_truth as _normalize_truth,
120
+ normalize_truth_expectation as _normalize_truth_expectation,
121
+ parse_int as _int,
122
+ parse_repo_path_map,
123
+ resolve_path_for_cwd as _resolve_path_for_cwd,
124
+ reviewer_id_from_command as _reviewer_id_from_command,
125
+ run_records_from_summary as _run_records_from_summary,
126
+ render_evidence_text,
127
+ render_overlap_text,
128
+ render_plan_text,
129
+ render_policy_text,
130
+ render_value_report_text,
131
+ safe_slug as _safe_slug,
132
+ summary_path_for_command as _summary_path_for_command,
133
+ text_from_timeout_stream as _text_from_timeout_stream,
134
+ truth_for_item as _truth_for_item,
135
+ default_code_mower_command as _default_code_mower_command,
136
+ load_summary as _load_summary,
137
+ result_command_dir as _result_command_dir,
138
+ run_calibration_commands,
139
+ utc_now_iso as _utc_now_iso,
140
+ write_json as _write_json,
141
+ )
142
+ from tools.calibration.auto_discovery import (
143
+ build_auto_discovered_corpus,
144
+ fetch_merged_prs_for_auto_discovery,
145
+ load_auto_discovery_input,
146
+ )
147
+ elif __package__ == "tools":
148
+ from tools import code_mower_telemetry
149
+ from tools.calibration import (
150
+ RUN_STATUS_AUDIT_INPUT_INSUFFICIENT,
151
+ RUN_STATUS_BLOCKED,
152
+ RUN_STATUS_CATEGORY_ALIASES,
153
+ RUN_STATUS_INFRA_ERROR,
154
+ RUN_STATUS_PASS,
155
+ RUN_STATUS_UNKNOWN,
156
+ TRUTH_EXPECTATION_ALIASES,
157
+ TRUTH_EXPECTATION_KNOWN_BLOCKED,
158
+ TRUTH_EXPECTATION_KNOWN_CLEAN,
159
+ TRUTH_EXPECTATION_UNKNOWN,
160
+ AUDIT_INPUT_INSUFFICIENT_PATTERNS,
161
+ CALIBRATION_RUN_RESULTS_MODE,
162
+ CALIBRATION_RUN_RESULTS_SCHEMA,
163
+ build_pilot_plan,
164
+ command_lane_id as _command_lane_id,
165
+ command_metadata_for_run as _command_metadata_for_run,
166
+ context_pack_file_for_command as _context_pack_file_for_command,
167
+ default_arms,
168
+ build_overlap_report,
169
+ build_lane_policy_report,
170
+ build_reviewer_evidence_report,
171
+ build_value_report,
172
+ audit_input_insufficient_result as _audit_input_insufficient_result,
173
+ coderabbit_blocking_findings as _coderabbit_blocking_findings,
174
+ corpus_with_run_results,
175
+ expected_finding_matches as _expected_finding_matches,
176
+ infra_run_record as _infra_run_record,
177
+ load_corpus,
178
+ load_json_object as _load_json,
179
+ load_run_results as _load_run_results,
180
+ local_llm_profiles_from_command as _local_llm_profiles_from_command,
181
+ local_llm_findings as _local_llm_findings,
182
+ materialize_command as _materialize_command,
183
+ normalize_disposition as _normalize_disposition,
184
+ normalize_run_status_category as _normalize_run_status_category,
185
+ normalize_truth as _normalize_truth,
186
+ normalize_truth_expectation as _normalize_truth_expectation,
187
+ parse_int as _int,
188
+ parse_repo_path_map,
189
+ resolve_path_for_cwd as _resolve_path_for_cwd,
190
+ reviewer_id_from_command as _reviewer_id_from_command,
191
+ run_records_from_summary as _run_records_from_summary,
192
+ render_evidence_text,
193
+ render_overlap_text,
194
+ render_plan_text,
195
+ render_policy_text,
196
+ render_value_report_text,
197
+ safe_slug as _safe_slug,
198
+ summary_path_for_command as _summary_path_for_command,
199
+ text_from_timeout_stream as _text_from_timeout_stream,
200
+ truth_for_item as _truth_for_item,
201
+ default_code_mower_command as _default_code_mower_command,
202
+ load_summary as _load_summary,
203
+ result_command_dir as _result_command_dir,
204
+ run_calibration_commands,
205
+ utc_now_iso as _utc_now_iso,
206
+ write_json as _write_json,
207
+ )
208
+ from tools.calibration.auto_discovery import (
209
+ build_auto_discovered_corpus,
210
+ fetch_merged_prs_for_auto_discovery,
211
+ load_auto_discovery_input,
212
+ )
213
+ else: # pragma: no cover - exercised after package extraction.
214
+ from . import code_mower_telemetry
215
+ from .calibration import (
216
+ RUN_STATUS_AUDIT_INPUT_INSUFFICIENT,
217
+ RUN_STATUS_BLOCKED,
218
+ RUN_STATUS_CATEGORY_ALIASES,
219
+ RUN_STATUS_INFRA_ERROR,
220
+ RUN_STATUS_PASS,
221
+ RUN_STATUS_UNKNOWN,
222
+ TRUTH_EXPECTATION_ALIASES,
223
+ TRUTH_EXPECTATION_KNOWN_BLOCKED,
224
+ TRUTH_EXPECTATION_KNOWN_CLEAN,
225
+ TRUTH_EXPECTATION_UNKNOWN,
226
+ AUDIT_INPUT_INSUFFICIENT_PATTERNS,
227
+ CALIBRATION_RUN_RESULTS_MODE,
228
+ CALIBRATION_RUN_RESULTS_SCHEMA,
229
+ build_pilot_plan,
230
+ command_lane_id as _command_lane_id,
231
+ command_metadata_for_run as _command_metadata_for_run,
232
+ context_pack_file_for_command as _context_pack_file_for_command,
233
+ default_arms,
234
+ build_overlap_report,
235
+ build_lane_policy_report,
236
+ build_reviewer_evidence_report,
237
+ build_value_report,
238
+ audit_input_insufficient_result as _audit_input_insufficient_result,
239
+ coderabbit_blocking_findings as _coderabbit_blocking_findings,
240
+ corpus_with_run_results,
241
+ expected_finding_matches as _expected_finding_matches,
242
+ infra_run_record as _infra_run_record,
243
+ load_corpus,
244
+ load_json_object as _load_json,
245
+ load_run_results as _load_run_results,
246
+ local_llm_profiles_from_command as _local_llm_profiles_from_command,
247
+ local_llm_findings as _local_llm_findings,
248
+ materialize_command as _materialize_command,
249
+ normalize_disposition as _normalize_disposition,
250
+ normalize_run_status_category as _normalize_run_status_category,
251
+ normalize_truth as _normalize_truth,
252
+ normalize_truth_expectation as _normalize_truth_expectation,
253
+ parse_int as _int,
254
+ parse_repo_path_map,
255
+ resolve_path_for_cwd as _resolve_path_for_cwd,
256
+ reviewer_id_from_command as _reviewer_id_from_command,
257
+ run_records_from_summary as _run_records_from_summary,
258
+ render_evidence_text,
259
+ render_overlap_text,
260
+ render_plan_text,
261
+ render_policy_text,
262
+ render_value_report_text,
263
+ safe_slug as _safe_slug,
264
+ summary_path_for_command as _summary_path_for_command,
265
+ text_from_timeout_stream as _text_from_timeout_stream,
266
+ truth_for_item as _truth_for_item,
267
+ default_code_mower_command as _default_code_mower_command,
268
+ load_summary as _load_summary,
269
+ result_command_dir as _result_command_dir,
270
+ run_calibration_commands,
271
+ utc_now_iso as _utc_now_iso,
272
+ write_json as _write_json,
273
+ )
274
+ from .calibration.auto_discovery import (
275
+ build_auto_discovered_corpus,
276
+ fetch_merged_prs_for_auto_discovery,
277
+ load_auto_discovery_input,
278
+ )
279
+
280
+ _LEGACY_CORPUS_EXPORTS = (load_corpus, _int)
281
+ _LEGACY_RUN_STATUS_EXPORTS = (
282
+ RUN_STATUS_AUDIT_INPUT_INSUFFICIENT,
283
+ RUN_STATUS_BLOCKED,
284
+ RUN_STATUS_CATEGORY_ALIASES,
285
+ RUN_STATUS_INFRA_ERROR,
286
+ RUN_STATUS_PASS,
287
+ RUN_STATUS_UNKNOWN,
288
+ _normalize_run_status_category,
289
+ )
290
+ _LEGACY_EVIDENCE_EXPORTS = (_normalize_disposition,)
291
+ _LEGACY_PLANNING_EXPORTS = (default_arms, build_pilot_plan)
292
+ _LEGACY_TRUTH_EXPORTS = (
293
+ TRUTH_EXPECTATION_ALIASES,
294
+ TRUTH_EXPECTATION_KNOWN_BLOCKED,
295
+ TRUTH_EXPECTATION_KNOWN_CLEAN,
296
+ TRUTH_EXPECTATION_UNKNOWN,
297
+ _expected_finding_matches,
298
+ _normalize_truth,
299
+ _normalize_truth_expectation,
300
+ _truth_for_item,
301
+ )
302
+ _LEGACY_RESULT_EXPORTS = (
303
+ AUDIT_INPUT_INSUFFICIENT_PATTERNS,
304
+ _audit_input_insufficient_result,
305
+ _coderabbit_blocking_findings,
306
+ corpus_with_run_results,
307
+ _infra_run_record,
308
+ _local_llm_findings,
309
+ _run_records_from_summary,
310
+ )
311
+ _LEGACY_RUNNER_EXPORTS = (
312
+ CALIBRATION_RUN_RESULTS_MODE,
313
+ CALIBRATION_RUN_RESULTS_SCHEMA,
314
+ _command_lane_id,
315
+ _command_metadata_for_run,
316
+ _context_pack_file_for_command,
317
+ _local_llm_profiles_from_command,
318
+ _materialize_command,
319
+ _resolve_path_for_cwd,
320
+ _reviewer_id_from_command,
321
+ _safe_slug,
322
+ _summary_path_for_command,
323
+ _text_from_timeout_stream,
324
+ _default_code_mower_command,
325
+ _load_summary,
326
+ _result_command_dir,
327
+ run_calibration_commands,
328
+ _utc_now_iso,
329
+ )
330
+
331
+
332
+
333
+ def main(argv: Sequence[str] | None = None) -> int:
334
+ parser = argparse.ArgumentParser(description=__doc__)
335
+ subparsers = parser.add_subparsers(dest="command", required=True)
336
+ plan_parser = subparsers.add_parser("plan")
337
+ plan_parser.add_argument("corpus", type=Path)
338
+ plan_parser.add_argument("--replicates", type=int, default=1)
339
+ plan_parser.add_argument("--output-dir", type=Path, default=Path(".code-mower/calibration"))
340
+ plan_parser.add_argument("--jobs", type=int, default=1)
341
+ plan_parser.add_argument("--json", action="store_true")
342
+
343
+ overlap_parser = subparsers.add_parser("overlap")
344
+ overlap_parser.add_argument("calibration_reports", nargs="+", type=Path)
345
+ overlap_parser.add_argument("--json", action="store_true")
346
+
347
+ evidence_parser = subparsers.add_parser("evidence")
348
+ evidence_parser.add_argument("corpus", type=Path)
349
+ evidence_parser.add_argument("--json", action="store_true")
350
+
351
+ auto_discover_parser = subparsers.add_parser("auto-discover")
352
+ auto_discover_parser.add_argument("--repo", required=True, help="GitHub owner/repo slug.")
353
+ auto_discover_parser.add_argument(
354
+ "--last-n",
355
+ type=int,
356
+ default=20,
357
+ help="Number of recent merged PRs to inspect when querying GitHub.",
358
+ )
359
+ auto_discover_parser.add_argument(
360
+ "--input",
361
+ type=Path,
362
+ default=None,
363
+ help="Optional saved `gh pr list --json ...` payload to convert offline.",
364
+ )
365
+ auto_discover_parser.add_argument(
366
+ "--output",
367
+ type=Path,
368
+ default=None,
369
+ help="Optional path for the draft calibration corpus JSON.",
370
+ )
371
+ auto_discover_parser.add_argument("--json", action="store_true")
372
+
373
+ run_parser = subparsers.add_parser("run")
374
+ run_parser.add_argument("corpus", type=Path)
375
+ run_parser.add_argument("--replicates", type=int, default=1)
376
+ run_parser.add_argument("--output-dir", type=Path, default=Path(".code-mower/calibration"))
377
+ run_parser.add_argument(
378
+ "--results-dir",
379
+ type=Path,
380
+ default=Path(".code-mower/calibration-results"),
381
+ )
382
+ run_parser.add_argument(
383
+ "--lanes",
384
+ default="",
385
+ help=(
386
+ "Comma-separated command lanes to execute, e.g. "
387
+ "antigravity-cli,gemini-cli,coderabbit-cli,local-llm."
388
+ ),
389
+ )
390
+ run_parser.add_argument(
391
+ "--arms",
392
+ default="",
393
+ help=(
394
+ "Comma-separated calibration arm IDs to execute. Spend-heavy fan-out "
395
+ "arms require explicit selection."
396
+ ),
397
+ )
398
+ run_parser.add_argument("--jobs", type=int, default=1)
399
+ run_parser.add_argument(
400
+ "--code-mower-command",
401
+ nargs="+",
402
+ default=None,
403
+ help="Command used to replace the generated `code-mower` executable.",
404
+ )
405
+ run_parser.add_argument(
406
+ "--repo-path-map",
407
+ action="append",
408
+ default=[],
409
+ help=(
410
+ "Map OWNER/REPO, OWNER/REPO#PR, OWNER/REPO@HEAD, or "
411
+ "OWNER/REPO#PR@HEAD to a clean local PR worktree for CLI reviewers."
412
+ ),
413
+ )
414
+ run_parser.add_argument(
415
+ "--context-pack-manifest",
416
+ type=Path,
417
+ default=None,
418
+ help=(
419
+ "Optional context-pack manifest. Corpus items with context_packs "
420
+ "materialize matching packs from their local PR checkout and pass "
421
+ "the bounded text to supported local CLI reviewers."
422
+ ),
423
+ )
424
+ run_parser.add_argument(
425
+ "--context-pack-output-dir",
426
+ type=Path,
427
+ default=Path(".code-mower/calibration-context-packs"),
428
+ help="Directory for materialized calibration context-pack artifacts.",
429
+ )
430
+ run_parser.add_argument(
431
+ "--require-context-pack-files",
432
+ action="store_true",
433
+ help="Fail if a selected context-pack file is missing.",
434
+ )
435
+ run_parser.add_argument("--allow-historical-head", action="store_true")
436
+ run_parser.add_argument("--dry-run", action="store_true")
437
+ run_parser.add_argument("--limit", type=int, default=None)
438
+ run_parser.add_argument("--timeout", type=int, default=1800)
439
+ run_parser.add_argument("--json", action="store_true")
440
+
441
+ policy_parser = subparsers.add_parser("policy")
442
+ policy_parser.add_argument("metrics_report", type=Path)
443
+ policy_parser.add_argument("--json", action="store_true")
444
+
445
+ value_parser = subparsers.add_parser("value-report")
446
+ value_parser.add_argument("corpus", type=Path)
447
+ value_parser.add_argument("--spend", type=Path, default=None)
448
+ value_parser.add_argument(
449
+ "--events",
450
+ nargs="+",
451
+ type=Path,
452
+ default=[],
453
+ help="Optional Code Mower audit event JSONL logs to fold into reviewer metrics.",
454
+ )
455
+ value_parser.add_argument(
456
+ "--runs",
457
+ nargs="+",
458
+ type=Path,
459
+ default=[],
460
+ help="Optional calibration run-results JSON files to fold into reviewer metrics.",
461
+ )
462
+ value_parser.add_argument("--output", type=Path, default=None)
463
+ value_parser.add_argument("--json", action="store_true")
464
+ args = parser.parse_args(argv)
465
+
466
+ try:
467
+ if args.command == "plan":
468
+ payload = build_pilot_plan(
469
+ load_corpus(args.corpus),
470
+ replicates=args.replicates,
471
+ output_dir=args.output_dir,
472
+ jobs=args.jobs,
473
+ )
474
+ if args.json:
475
+ print(json.dumps(payload, indent=2, sort_keys=True))
476
+ else:
477
+ print(render_plan_text(payload), end="")
478
+ return 0
479
+ if args.command == "overlap":
480
+ payload = build_overlap_report(_load_json(path) for path in args.calibration_reports)
481
+ if args.json:
482
+ print(json.dumps(payload, indent=2, sort_keys=True))
483
+ else:
484
+ print(render_overlap_text(payload), end="")
485
+ return 0
486
+ if args.command == "evidence":
487
+ payload = build_reviewer_evidence_report(load_corpus(args.corpus))
488
+ if args.json:
489
+ print(json.dumps(payload, indent=2, sort_keys=True))
490
+ else:
491
+ print(render_evidence_text(payload), end="")
492
+ return 0
493
+ if args.command == "auto-discover":
494
+ raw_prs = (
495
+ load_auto_discovery_input(args.input)
496
+ if args.input is not None
497
+ else fetch_merged_prs_for_auto_discovery(
498
+ repo=args.repo,
499
+ last_n=args.last_n,
500
+ )
501
+ )
502
+ payload = build_auto_discovered_corpus(
503
+ repo=args.repo,
504
+ pull_requests=raw_prs,
505
+ last_n=args.last_n,
506
+ )
507
+ if args.output is not None:
508
+ _write_json(args.output, payload)
509
+ if args.json:
510
+ print(json.dumps(payload, indent=2, sort_keys=True))
511
+ else:
512
+ print(
513
+ "Code Mower auto-discovered draft corpus\n"
514
+ f"repo: {payload['discovery']['repo']}\n"
515
+ f"items: {len(payload.get('corpus', []) or [])}\n"
516
+ f"caveat: {payload['discovery']['caveat']}\n",
517
+ end="",
518
+ )
519
+ return 0
520
+ if args.command == "run":
521
+ lanes = tuple(
522
+ lane.strip()
523
+ for lane in str(args.lanes or "").split(",")
524
+ if lane.strip()
525
+ )
526
+ arms = tuple(
527
+ arm.strip()
528
+ for arm in str(args.arms or "").split(",")
529
+ if arm.strip()
530
+ )
531
+ payload = run_calibration_commands(
532
+ load_corpus(args.corpus),
533
+ replicates=args.replicates,
534
+ output_dir=args.output_dir,
535
+ results_dir=args.results_dir,
536
+ lanes=lanes,
537
+ arms=arms,
538
+ jobs=args.jobs,
539
+ code_mower_command=args.code_mower_command,
540
+ repo_path_map=parse_repo_path_map(args.repo_path_map),
541
+ context_pack_manifest=_load_json(args.context_pack_manifest)
542
+ if args.context_pack_manifest is not None
543
+ else None,
544
+ context_pack_output_dir=args.context_pack_output_dir,
545
+ require_context_pack_files=args.require_context_pack_files,
546
+ allow_historical_head=args.allow_historical_head,
547
+ dry_run=args.dry_run,
548
+ limit=args.limit,
549
+ timeout_seconds=args.timeout,
550
+ cwd=Path.cwd(),
551
+ )
552
+ if args.json:
553
+ print(json.dumps(payload, indent=2, sort_keys=True))
554
+ else:
555
+ print(
556
+ "Code Mower calibration run\n"
557
+ f"commands: {payload.get('command_count', 0)}\n"
558
+ f"reviewer runs: {len(payload.get('reviewer_runs', []) or [])}\n"
559
+ f"results: {payload.get('results_dir')}\n",
560
+ end="",
561
+ )
562
+ return 0
563
+ if args.command == "policy":
564
+ payload = build_lane_policy_report(_load_json(args.metrics_report))
565
+ if args.json:
566
+ print(json.dumps(payload, indent=2, sort_keys=True))
567
+ else:
568
+ print(render_policy_text(payload), end="")
569
+ return 0
570
+ if args.command == "value-report":
571
+ event_summaries = [
572
+ code_mower_telemetry.summarize_events(
573
+ code_mower_telemetry.load_jsonl_events(path)
574
+ )
575
+ for path in args.events
576
+ ]
577
+ payload = build_value_report(
578
+ load_corpus(args.corpus),
579
+ spend=_load_json(args.spend) if args.spend is not None else None,
580
+ event_summaries=event_summaries,
581
+ run_results=_load_run_results(args.runs),
582
+ )
583
+ if args.output is not None:
584
+ args.output.parent.mkdir(parents=True, exist_ok=True)
585
+ args.output.write_text(render_value_report_text(payload), encoding="utf-8")
586
+ if args.json:
587
+ print(json.dumps(payload, indent=2, sort_keys=True))
588
+ else:
589
+ print(render_value_report_text(payload), end="")
590
+ return 0
591
+ except ValueError as exc:
592
+ print(f"error: {exc}", file=sys.stderr)
593
+ return 1
594
+ raise AssertionError(f"unhandled calibration command: {args.command}")
595
+
596
+
597
+ if __name__ == "__main__":
598
+ raise SystemExit(main())