code-mower 1.2.1__tar.gz → 1.3.0__tar.gz

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 (457) hide show
  1. {code_mower-1.2.1 → code_mower-1.3.0}/PKG-INFO +18 -7
  2. {code_mower-1.2.1 → code_mower-1.3.0}/README.md +12 -6
  3. {code_mower-1.2.1 → code_mower-1.3.0}/pyproject.toml +2 -1
  4. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/__init__.py +1 -1
  5. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/audit_labeler_lib.py +29 -0
  6. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/claude_audit_pr.py +44 -5
  7. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/codex_audit_pr.py +70 -15
  8. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/config.py +13 -211
  9. code_mower-1.3.0/src/code_mower/context_audit.py +117 -0
  10. code_mower-1.3.0/src/code_mower/context_command.py +135 -0
  11. code_mower-1.3.0/src/code_mower/context_connections.py +274 -0
  12. code_mower-1.3.0/src/code_mower/context_contract.py +452 -0
  13. code_mower-1.3.0/src/code_mower/context_delivery.py +184 -0
  14. code_mower-1.3.0/src/code_mower/context_packets.py +215 -0
  15. code_mower-1.3.0/src/code_mower/context_readiness.py +105 -0
  16. code_mower-1.3.0/src/code_mower/context_review.py +133 -0
  17. code_mower-1.3.0/src/code_mower/context_store.py +214 -0
  18. code_mower-1.3.0/src/code_mower/coworker_mcp.py +379 -0
  19. code_mower-1.3.0/src/code_mower/coworker_retrieval.py +103 -0
  20. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor.py +4 -0
  21. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/groups.py +1 -1
  22. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/runner.py +10 -0
  23. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/file_locks.py +27 -22
  24. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/init.py +56 -2
  25. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/jira_cloud.py +2 -1
  26. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/jira_mutations.py +9 -1
  27. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/jira_pr_sync.py +12 -3
  28. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_status.py +35 -2
  29. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/migration.py +2 -0
  30. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/package_content.py +3 -0
  31. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/package_manifest.py +19 -0
  32. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/verdict_artifacts.py +2 -0
  33. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/session.py +23 -4
  34. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/code-mower.example.yml +3 -0
  35. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/builder-provenance.yml.j2 +1 -1
  36. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/code-mower-gate.yml.j2 +15 -2
  37. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/tracker_contract.py +1 -1
  38. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/tracker_queue.py +1 -1
  39. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/work_orders.py +44 -7
  40. code_mower-1.3.0/src/code_mower/yaml_subset.py +220 -0
  41. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower.egg-info/PKG-INFO +18 -7
  42. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower.egg-info/SOURCES.txt +22 -0
  43. code_mower-1.3.0/src/code_mower.egg-info/requires.txt +13 -0
  44. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/builder-provenance.yml.j2 +1 -1
  45. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/code-mower-gate.yml.j2 +15 -2
  46. code_mower-1.3.0/tests/test_context_audit.py +192 -0
  47. code_mower-1.3.0/tests/test_context_command.py +185 -0
  48. code_mower-1.3.0/tests/test_context_connections.py +274 -0
  49. code_mower-1.3.0/tests/test_context_contract.py +415 -0
  50. code_mower-1.3.0/tests/test_context_delivery.py +125 -0
  51. code_mower-1.3.0/tests/test_context_packets.py +188 -0
  52. code_mower-1.3.0/tests/test_context_readiness.py +223 -0
  53. code_mower-1.3.0/tests/test_context_review.py +106 -0
  54. code_mower-1.3.0/tests/test_coworker_mcp.py +152 -0
  55. code_mower-1.3.0/tests/test_coworker_retrieval.py +157 -0
  56. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_fork_pr_guard.py +22 -4
  57. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_jira_adoption.py +2 -1
  58. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_jira_cloud.py +7 -3
  59. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_jira_pr_sync.py +49 -1
  60. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_lane_status.py +89 -0
  61. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_participant_sessions.py +21 -0
  62. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_release_hygiene.py +73 -47
  63. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_tracker_contract.py +6 -0
  64. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_tracker_queue.py +2 -2
  65. code_mower-1.2.1/src/code_mower.egg-info/requires.txt +0 -7
  66. {code_mower-1.2.1 → code_mower-1.3.0}/CODE_OF_CONDUCT.md +0 -0
  67. {code_mower-1.2.1 → code_mower-1.3.0}/LICENSE +0 -0
  68. {code_mower-1.2.1 → code_mower-1.3.0}/MANIFEST.in +0 -0
  69. {code_mower-1.2.1 → code_mower-1.3.0}/NOTICE +0 -0
  70. {code_mower-1.2.1 → code_mower-1.3.0}/SUPPORT.md +0 -0
  71. {code_mower-1.2.1 → code_mower-1.3.0}/requirements/requirements.txt +0 -0
  72. {code_mower-1.2.1 → code_mower-1.3.0}/setup.cfg +0 -0
  73. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/adapters/__init__.py +0 -0
  74. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/adapters/_base.py +0 -0
  75. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/adapters/cursor_bugbot.py +0 -0
  76. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/adapters/gitar.py +0 -0
  77. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/adapters/greptile.py +0 -0
  78. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/adapters/qodo.py +0 -0
  79. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
  80. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/antigravity_sdk_probe.py +0 -0
  81. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/audit_handoff_log.py +0 -0
  82. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/audit_limits.py +0 -0
  83. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/audit_progress.py +0 -0
  84. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/blind_review_artifacts.py +0 -0
  85. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/blind_review_coordinator.py +0 -0
  86. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/board.py +0 -0
  87. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/board_store.py +0 -0
  88. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/bootstrap.py +0 -0
  89. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/builder_experiment.py +0 -0
  90. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/builder_runs.py +0 -0
  91. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/__init__.py +0 -0
  92. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/arms.py +0 -0
  93. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/auto_discovery.py +0 -0
  94. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/commands.py +0 -0
  95. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/context_inputs.py +0 -0
  96. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/corpus.py +0 -0
  97. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/effect_report.py +0 -0
  98. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/evidence.py +0 -0
  99. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/evidence_report.py +0 -0
  100. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/identity.py +0 -0
  101. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/metrics.py +0 -0
  102. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/overlap.py +0 -0
  103. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/planning.py +0 -0
  104. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/policy.py +0 -0
  105. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/results.py +0 -0
  106. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/run_results.py +0 -0
  107. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/run_status.py +0 -0
  108. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/runner.py +0 -0
  109. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/truth.py +0 -0
  110. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/calibration/value_report.py +0 -0
  111. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/campaign_adapters.py +0 -0
  112. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/campaign_discovery.py +0 -0
  113. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/checks.py +0 -0
  114. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/claude_cli_bounce.py +0 -0
  115. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/claude_cli_environment.py +0 -0
  116. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/clear_stale.py +0 -0
  117. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cli.py +0 -0
  118. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud.py +0 -0
  119. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/__init__.py +0 -0
  120. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/adoption_runs.py +0 -0
  121. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/bundle.py +0 -0
  122. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/doctor.py +0 -0
  123. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/dogfood.py +0 -0
  124. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/endpoints.py +0 -0
  125. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/errors.py +0 -0
  126. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/events.py +0 -0
  127. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/export.py +0 -0
  128. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/finding_outcomes.py +0 -0
  129. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/git_metadata.py +0 -0
  130. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/manifest.py +0 -0
  131. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/operations.py +0 -0
  132. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/pr_outcomes.py +0 -0
  133. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/productivity.py +0 -0
  134. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/productivity_windows.py +0 -0
  135. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/reports.py +0 -0
  136. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/setup.py +0 -0
  137. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/tokens.py +0 -0
  138. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/upload.py +0 -0
  139. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/cloud_client/work_types.py +0 -0
  140. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/code_mower_calibration.py +0 -0
  141. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/code_mower_context_packs.py +0 -0
  142. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/code_mower_merge.py +0 -0
  143. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/code_mower_telemetry.py +0 -0
  144. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
  145. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/codex_audit_env_preflight.py +0 -0
  146. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/codex_audit_schema_smoke.py +0 -0
  147. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/codex_audit_verdict.schema.json +0 -0
  148. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/controller.py +0 -0
  149. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/decisions.py +0 -0
  150. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/devin_api.py +0 -0
  151. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/devin_cli_audit_pr.py +0 -0
  152. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/__init__.py +0 -0
  153. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/adoption.py +0 -0
  154. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/audit_limits.py +0 -0
  155. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/campaign_auth.py +0 -0
  156. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/cloud.py +0 -0
  157. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/common.py +0 -0
  158. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github.py +0 -0
  159. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_actions.py +0 -0
  160. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
  161. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
  162. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
  163. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
  164. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
  165. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
  166. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
  167. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
  168. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_api.py +0 -0
  169. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_branch.py +0 -0
  170. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_config.py +0 -0
  171. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_human_token.py +0 -0
  172. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_provider.py +0 -0
  173. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_repo.py +0 -0
  174. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/github_trusted_authors.py +0 -0
  175. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/jira.py +0 -0
  176. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/models.py +0 -0
  177. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/output.py +0 -0
  178. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/presets.py +0 -0
  179. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/privacy.py +0 -0
  180. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
  181. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
  182. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
  183. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_env.py +0 -0
  184. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
  185. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
  186. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_local_audit_setup.py +0 -0
  187. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
  188. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
  189. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
  190. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_probe.py +0 -0
  191. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
  192. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
  193. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
  194. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
  195. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/provider_review_hygiene.py +0 -0
  196. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/providers.py +0 -0
  197. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/registry.py +0 -0
  198. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/runtime.py +0 -0
  199. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
  200. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/self_hosted_runner.py +0 -0
  201. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/doctor_checks/supervised_pilot.py +0 -0
  202. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/gate_health.py +0 -0
  203. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/gemini_cli_audit_pr.py +0 -0
  204. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/git_identity.py +0 -0
  205. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/grok_build_audit_pr.py +0 -0
  206. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/hermes_cli_audit_pr.py +0 -0
  207. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/__init__.py +0 -0
  208. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/aider.py +0 -0
  209. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
  210. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/claude.py +0 -0
  211. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/codex.py +0 -0
  212. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/devin.py +0 -0
  213. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/devin_cli.py +0 -0
  214. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/gemini_cli.py +0 -0
  215. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/grok_build.py +0 -0
  216. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/hermes_cli.py +0 -0
  217. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/local_llm.py +0 -0
  218. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_configs/muse_cli.py +0 -0
  219. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/lane_delivery.py +0 -0
  220. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/local_llm_audit_pr.py +0 -0
  221. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/local_llm_bakeoff.py +0 -0
  222. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/local_llm_calibration.py +0 -0
  223. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/local_llm_profiles.py +0 -0
  224. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/migration_install.py +0 -0
  225. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/migration_mirror.py +0 -0
  226. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/migration_readiness.py +0 -0
  227. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/migration_rehearsal.py +0 -0
  228. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/muse_cli_audit_pr.py +0 -0
  229. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/next_steps.py +0 -0
  230. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/package.py +0 -0
  231. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/package_paths.py +0 -0
  232. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/package_rendering.py +0 -0
  233. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/package_static.py +0 -0
  234. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/participants.py +0 -0
  235. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/plan_context.py +0 -0
  236. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/productivity_report.py +0 -0
  237. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/prompts.py +0 -0
  238. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_credentials.py +0 -0
  239. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_registry.py +0 -0
  240. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/__init__.py +0 -0
  241. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/comments.py +0 -0
  242. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/exit_codes.py +0 -0
  243. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/git.py +0 -0
  244. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/github_auth.py +0 -0
  245. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/github_pr.py +0 -0
  246. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/pr_worktree.py +0 -0
  247. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/process.py +0 -0
  248. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/repo_paths.py +0 -0
  249. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/text_schema.py +0 -0
  250. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/provider_runners/workspace.py +0 -0
  251. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/providers/__init__.py +0 -0
  252. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/providers/local_cli.py +0 -0
  253. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/providers/provenance.py +0 -0
  254. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/release_campaigns.py +0 -0
  255. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/release_qualify.py +0 -0
  256. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/release_readiness.py +0 -0
  257. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/reviewer_metrics.py +0 -0
  258. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/reviewer_spend.py +0 -0
  259. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/saas_reviewer_labeler.py +0 -0
  260. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/secrets.py +0 -0
  261. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/session_lease.py +0 -0
  262. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/builder-experiment.example.json +0 -0
  263. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/calibration-corpus.example.json +0 -0
  264. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/calibration-corpus.json +0 -0
  265. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/context-packs.example.json +0 -0
  266. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
  267. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
  268. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
  269. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
  270. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
  271. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lane_prompts/operability.md +0 -0
  272. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
  273. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lane_prompts/plan-conformance.md +0 -0
  274. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
  275. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lanes/README.md +0 -0
  276. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lanes/claude.md +0 -0
  277. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lanes/codex.md +0 -0
  278. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lanes/cursor.md +0 -0
  279. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lanes/devin.md +0 -0
  280. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lanes/generic.md +0 -0
  281. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/lanes/run_mac_lane.sh +0 -0
  282. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/product-support/code_mower +0 -0
  283. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
  284. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
  285. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
  286. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
  287. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/product-support/run_devin_cli_audit_pr.sh +0 -0
  288. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
  289. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/product-support/status_report.py +0 -0
  290. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/providers.yml +0 -0
  291. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/reviewer-spend.example.json +0 -0
  292. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
  293. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  294. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
  295. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
  296. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
  297. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/dispatch-lanes.yml.j2 +0 -0
  298. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
  299. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/lane-mac-runner.yml.j2 +0 -0
  300. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
  301. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/needs-owner-notify.yml.j2 +0 -0
  302. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  303. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
  304. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
  305. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
  306. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
  307. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/templates/workflows/weekly-status.yml.j2 +0 -0
  308. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/trailer_comment_labeler.py +0 -0
  309. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/versioning.py +0 -0
  310. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower/workflow_actionlint.py +0 -0
  311. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower.egg-info/dependency_links.txt +0 -0
  312. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower.egg-info/entry_points.txt +0 -0
  313. {code_mower-1.2.1 → code_mower-1.3.0}/src/code_mower.egg-info/top_level.txt +0 -0
  314. {code_mower-1.2.1 → code_mower-1.3.0}/templates/builder-experiment.example.json +0 -0
  315. {code_mower-1.2.1 → code_mower-1.3.0}/templates/calibration-corpus.example.json +0 -0
  316. {code_mower-1.2.1 → code_mower-1.3.0}/templates/calibration-corpus.json +0 -0
  317. {code_mower-1.2.1 → code_mower-1.3.0}/templates/code-mower.yml.j2 +0 -0
  318. {code_mower-1.2.1 → code_mower-1.3.0}/templates/context-packs.example.json +0 -0
  319. {code_mower-1.2.1 → code_mower-1.3.0}/templates/cursor/BUGBOT.md +0 -0
  320. {code_mower-1.2.1 → code_mower-1.3.0}/templates/lanes/README.md +0 -0
  321. {code_mower-1.2.1 → code_mower-1.3.0}/templates/lanes/claude.md +0 -0
  322. {code_mower-1.2.1 → code_mower-1.3.0}/templates/lanes/codex.md +0 -0
  323. {code_mower-1.2.1 → code_mower-1.3.0}/templates/lanes/cursor.md +0 -0
  324. {code_mower-1.2.1 → code_mower-1.3.0}/templates/lanes/devin.md +0 -0
  325. {code_mower-1.2.1 → code_mower-1.3.0}/templates/lanes/generic.md +0 -0
  326. {code_mower-1.2.1 → code_mower-1.3.0}/templates/lanes/run_mac_lane.sh +0 -0
  327. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/acp_bridge.yml +0 -0
  328. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/aider.yml +0 -0
  329. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/antigravity_cli.yml +0 -0
  330. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/claude_audit.yml +0 -0
  331. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/claude_review.yml +0 -0
  332. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/coderabbit_cli.yml +0 -0
  333. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/codex.yml +0 -0
  334. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/cursor_bugbot.yml +0 -0
  335. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/cursor_cloud_agent.yml +0 -0
  336. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/devin.yml +0 -0
  337. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/devin_cli.yml +0 -0
  338. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/gemini_cli.yml +0 -0
  339. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/gitar.yml +0 -0
  340. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/greptile.yml +0 -0
  341. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/hermes_cli.yml +0 -0
  342. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/local_llm.yml +0 -0
  343. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/muse_cli.yml +0 -0
  344. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers/qodo.yml +0 -0
  345. {code_mower-1.2.1 → code_mower-1.3.0}/templates/providers.yml +0 -0
  346. {code_mower-1.2.1 → code_mower-1.3.0}/templates/reviewer-spend.example.json +0 -0
  347. {code_mower-1.2.1 → code_mower-1.3.0}/templates/reviewer-value-report.example.md +0 -0
  348. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  349. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
  350. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
  351. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
  352. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
  353. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/dispatch-lanes.yml.j2 +0 -0
  354. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/hosted-bridge.yml.j2 +0 -0
  355. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/lane-mac-runner.yml.j2 +0 -0
  356. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/local-cli-audit.yml.j2 +0 -0
  357. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  358. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/review-clear-stale.yml.j2 +0 -0
  359. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
  360. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
  361. {code_mower-1.2.1 → code_mower-1.3.0}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
  362. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_adoption_diagnostics.py +0 -0
  363. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_adoption_result_semantics.py +0 -0
  364. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_adoption_run_contract.py +0 -0
  365. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_antigravity_cli_audit_pr.py +0 -0
  366. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_antigravity_sdk_probe.py +0 -0
  367. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_audit_comment_posture.py +0 -0
  368. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_audit_limits.py +0 -0
  369. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_board.py +0 -0
  370. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_board_lease.py +0 -0
  371. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_builder_experiment.py +0 -0
  372. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_builder_identity.py +0 -0
  373. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_builder_runs.py +0 -0
  374. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_calibration_effect_report.py +0 -0
  375. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_calibration_truth.py +0 -0
  376. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_campaign_adapters.py +0 -0
  377. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_campaign_discovery.py +0 -0
  378. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_campaign_gh_auth_and_issue_binding_817.py +0 -0
  379. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_campaign_retry_evidence_711.py +0 -0
  380. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_checks.py +0 -0
  381. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_claude_audit_pr.py +0 -0
  382. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_claude_cli_bounce.py +0 -0
  383. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_clear_stale.py +0 -0
  384. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_cloud_client.py +0 -0
  385. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_cloud_git_metadata.py +0 -0
  386. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_cloud_manifest.py +0 -0
  387. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_cloud_reports.py +0 -0
  388. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_coderabbit_cli_audit_pr.py +0 -0
  389. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_codex_audit_env_preflight.py +0 -0
  390. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_codex_audit_pr.py +0 -0
  391. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_controller.py +0 -0
  392. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_decision_audit_integration.py +0 -0
  393. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_decisions.py +0 -0
  394. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_devin_api.py +0 -0
  395. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_devin_builder_lane.py +0 -0
  396. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_devin_cli_audit_pr.py +0 -0
  397. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_devin_provider_contract.py +0 -0
  398. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_actions_cost_summary.py +0 -0
  399. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_actions_failure_selection.py +0 -0
  400. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_boundaries.py +0 -0
  401. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_campaign_auth.py +0 -0
  402. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_campaign_readiness.py +0 -0
  403. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_github_checks.py +0 -0
  404. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_output.py +0 -0
  405. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_privacy.py +0 -0
  406. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_provider_env_required.py +0 -0
  407. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_provider_env_tokens.py +0 -0
  408. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_provider_local_audit_setup.py +0 -0
  409. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_provider_probe.py +0 -0
  410. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_provider_review_hygiene.py +0 -0
  411. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_registry.py +0 -0
  412. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_runtime.py +0 -0
  413. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_self_hosted_runner.py +0 -0
  414. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_doctor_supervised_pilot.py +0 -0
  415. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_file_locks.py +0 -0
  416. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_gate_automerge.py +0 -0
  417. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_gate_health.py +0 -0
  418. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_hosted_dispatch_profile.py +0 -0
  419. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_init_actionlint.py +0 -0
  420. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_init_build_loop.py +0 -0
  421. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_jira_mutations.py +0 -0
  422. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_lane_delivery_contract.py +0 -0
  423. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_local_llm_github_helpers.py +0 -0
  424. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_migration_rehearsal.py +0 -0
  425. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_migration_setup_drift.py +0 -0
  426. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_next_steps.py +0 -0
  427. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_package_install_failure_taxonomy.py +0 -0
  428. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_plan_context.py +0 -0
  429. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_pr_outcome_contract.py +0 -0
  430. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_pr_outcome_coverage.py +0 -0
  431. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_productivity_metrics_contract.py +0 -0
  432. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_productivity_report.py +0 -0
  433. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_productivity_windows.py +0 -0
  434. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_prompts.py +0 -0
  435. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_credentials.py +0 -0
  436. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_fixture_contracts.py +0 -0
  437. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_local_cli.py +0 -0
  438. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_runners_comments.py +0 -0
  439. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_runners_git.py +0 -0
  440. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_runners_github_pr.py +0 -0
  441. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_runners_pr_worktree.py +0 -0
  442. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_runners_process.py +0 -0
  443. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_runners_repo_paths.py +0 -0
  444. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_runners_text_schema.py +0 -0
  445. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_provider_runners_workspace.py +0 -0
  446. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_release_campaigns.py +0 -0
  447. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_release_qualify.py +0 -0
  448. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_remote_qualification_failure_reason_819.py +0 -0
  449. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_reviewer_finding_outcome_contract.py +0 -0
  450. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_reviewer_metrics_core.py +0 -0
  451. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_reviewer_spend.py +0 -0
  452. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_session_lease.py +0 -0
  453. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_supervised_pilot_contract.py +0 -0
  454. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_tracker_config.py +0 -0
  455. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_trailer_comment_labeler.py +0 -0
  456. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_work_orders.py +0 -0
  457. {code_mower-1.2.1 → code_mower-1.3.0}/tests/test_work_type_contract.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-mower
3
- Version: 1.2.1
3
+ Version: 1.3.0
4
4
  Summary: Multi-reviewer AI code audit orchestration
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/codemower-ai/code-mower
@@ -21,6 +21,11 @@ Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
22
  License-File: NOTICE
23
23
  Requires-Dist: PyYAML>=6.0
24
+ Provides-Extra: coworker
25
+ Requires-Dist: mcp<2.3,>=2.2.0; extra == "coworker"
26
+ Requires-Dist: httpx2<3,>=2.12; extra == "coworker"
27
+ Requires-Dist: PyJWT[crypto]<3,>=2.10; extra == "coworker"
28
+ Requires-Dist: keyring<26,>=25; extra == "coworker"
24
29
  Provides-Extra: test
25
30
  Requires-Dist: build>=1.2; extra == "test"
26
31
  Requires-Dist: pytest>=8.0; extra == "test"
@@ -45,6 +50,8 @@ The short version:
45
50
  exposure, or GitHub Actions churn;
46
51
  - turn issue text, external docs, and project doctrine into local work orders
47
52
  before an agent starts coding;
53
+ - optionally give Claude and Codex the same authorized organizational evidence
54
+ through a private Coworker connection, with fresh review when context changes;
48
55
  - generate local reviewer value reports from known-clean and known-blocked PRs;
49
56
  and
50
57
  - optionally share sanitized metadata with [CodeMower.com](https://codemower.com)
@@ -56,8 +63,8 @@ Default cloud bundles exclude source code, raw diffs, raw model transcripts,
56
63
  raw stdout/stderr, auth output, and secrets.
57
64
 
58
65
  Documentation on `main` follows the source on `main`. If you install the
59
- published `code-mower==1.2.1` package, use the documentation from the matching
60
- [`v1.2.1` tag](https://github.com/codemower-ai/code-mower/tree/v1.2.1) so the
66
+ published `code-mower==1.3.0` package, use the documentation from the matching
67
+ [`v1.3.0` tag](https://github.com/codemower-ai/code-mower/tree/v1.3.0) so the
61
68
  commands and package stay aligned as development continues.
62
69
 
63
70
  ## Design Principles
@@ -252,7 +259,7 @@ agent report its actual host posture, exact installed version, doctor result,
252
259
  Board URL, and any owner-only click-list before it mutates the repo.
253
260
 
254
261
  The current package-index announcement entry point is the tagged
255
- [Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.2.1/docs/try-in-10-minutes.md)
262
+ [Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.3.0/docs/try-in-10-minutes.md)
256
263
  guide. The v1.0 supervised-pilot release includes the native Board, the
257
264
  controller dry-run and policy contract, adoption and upgrade hardening from
258
265
  recent install rehearsals, package-index release checks, provider-diversity
@@ -367,7 +374,7 @@ Provider-contract baseline for the next release train:
367
374
 
368
375
  For release verification,
369
376
  [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
370
- the package-index procedure for `v1.2.1` / `code-mower==1.2.1`. The
377
+ the package-index procedure for `v1.3.0` / `code-mower==1.3.0`. The
371
378
  GitHub release records the workflow and rehearsal evidence for the exact tag.
372
379
  After publication, [Release Qualification](docs/release-qualification.md)
373
380
  coordinates provider-specific install and operational checks without treating
@@ -561,8 +568,8 @@ measurement work.
561
568
 
562
569
  ## Installation Status
563
570
 
564
- The current package-index release baseline is `v1.2.1`, with pinned package
565
- install spec `code-mower==1.2.1`. Release evidence is recorded on the GitHub
571
+ The current package-index release baseline is `v1.3.0`, with pinned package
572
+ install spec `code-mower==1.3.0`. Release evidence is recorded on the GitHub
566
573
  release and in the first-user install rehearsal. The public repository is
567
574
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
568
575
  GitHub releases remain the auditable source for tags, build artifacts, and
@@ -676,6 +683,10 @@ first so local work exercises the same package entrypoint users install.
676
683
  - [v1.1.2 Release Notes](docs/v112-release-notes.md)
677
684
  - [v1.2 Release Notes](docs/v12-release-notes.md)
678
685
  - [v1.2.1 Release Notes](docs/v121-release-notes.md)
686
+ - [v1.2.2 Release Notes](docs/v122-release-notes.md)
687
+ - [v1.3.0 Release Notes](docs/v130-release-notes.md)
688
+ - [Optional Coworker Setup](docs/context-setup.md)
689
+ - [Context Qualification and Limits](docs/v130-context-qualification.md)
679
690
  - [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
680
691
  - [v1.0.1 Effectiveness Assessment](docs/v101-effectiveness-assessment.md)
681
692
 
@@ -15,6 +15,8 @@ The short version:
15
15
  exposure, or GitHub Actions churn;
16
16
  - turn issue text, external docs, and project doctrine into local work orders
17
17
  before an agent starts coding;
18
+ - optionally give Claude and Codex the same authorized organizational evidence
19
+ through a private Coworker connection, with fresh review when context changes;
18
20
  - generate local reviewer value reports from known-clean and known-blocked PRs;
19
21
  and
20
22
  - optionally share sanitized metadata with [CodeMower.com](https://codemower.com)
@@ -26,8 +28,8 @@ Default cloud bundles exclude source code, raw diffs, raw model transcripts,
26
28
  raw stdout/stderr, auth output, and secrets.
27
29
 
28
30
  Documentation on `main` follows the source on `main`. If you install the
29
- published `code-mower==1.2.1` package, use the documentation from the matching
30
- [`v1.2.1` tag](https://github.com/codemower-ai/code-mower/tree/v1.2.1) so the
31
+ published `code-mower==1.3.0` package, use the documentation from the matching
32
+ [`v1.3.0` tag](https://github.com/codemower-ai/code-mower/tree/v1.3.0) so the
31
33
  commands and package stay aligned as development continues.
32
34
 
33
35
  ## Design Principles
@@ -222,7 +224,7 @@ agent report its actual host posture, exact installed version, doctor result,
222
224
  Board URL, and any owner-only click-list before it mutates the repo.
223
225
 
224
226
  The current package-index announcement entry point is the tagged
225
- [Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.2.1/docs/try-in-10-minutes.md)
227
+ [Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v1.3.0/docs/try-in-10-minutes.md)
226
228
  guide. The v1.0 supervised-pilot release includes the native Board, the
227
229
  controller dry-run and policy contract, adoption and upgrade hardening from
228
230
  recent install rehearsals, package-index release checks, provider-diversity
@@ -337,7 +339,7 @@ Provider-contract baseline for the next release train:
337
339
 
338
340
  For release verification,
339
341
  [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
340
- the package-index procedure for `v1.2.1` / `code-mower==1.2.1`. The
342
+ the package-index procedure for `v1.3.0` / `code-mower==1.3.0`. The
341
343
  GitHub release records the workflow and rehearsal evidence for the exact tag.
342
344
  After publication, [Release Qualification](docs/release-qualification.md)
343
345
  coordinates provider-specific install and operational checks without treating
@@ -531,8 +533,8 @@ measurement work.
531
533
 
532
534
  ## Installation Status
533
535
 
534
- The current package-index release baseline is `v1.2.1`, with pinned package
535
- install spec `code-mower==1.2.1`. Release evidence is recorded on the GitHub
536
+ The current package-index release baseline is `v1.3.0`, with pinned package
537
+ install spec `code-mower==1.3.0`. Release evidence is recorded on the GitHub
536
538
  release and in the first-user install rehearsal. The public repository is
537
539
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
538
540
  GitHub releases remain the auditable source for tags, build artifacts, and
@@ -646,6 +648,10 @@ first so local work exercises the same package entrypoint users install.
646
648
  - [v1.1.2 Release Notes](docs/v112-release-notes.md)
647
649
  - [v1.2 Release Notes](docs/v12-release-notes.md)
648
650
  - [v1.2.1 Release Notes](docs/v121-release-notes.md)
651
+ - [v1.2.2 Release Notes](docs/v122-release-notes.md)
652
+ - [v1.3.0 Release Notes](docs/v130-release-notes.md)
653
+ - [Optional Coworker Setup](docs/context-setup.md)
654
+ - [Context Qualification and Limits](docs/v130-context-qualification.md)
649
655
  - [Post-v0.8 Effectiveness Assessment](docs/post-v08-effectiveness-assessment.md)
650
656
  - [v1.0.1 Effectiveness Assessment](docs/v101-effectiveness-assessment.md)
651
657
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-mower"
7
- version = "1.2.1"
7
+ version = "1.3.0"
8
8
  description = "Multi-reviewer AI code audit orchestration"
9
9
  requires-python = ">=3.12"
10
10
  readme = "README.md"
@@ -29,6 +29,7 @@ Issues = "https://github.com/codemower-ai/code-mower/issues"
29
29
  Changelog = "https://github.com/codemower-ai/code-mower/blob/main/CHANGELOG.md"
30
30
 
31
31
  [project.optional-dependencies]
32
+ coworker = ["mcp>=2.2.0,<2.3", "httpx2>=2.12,<3", "PyJWT[crypto]>=2.10,<3", "keyring>=25,<26"]
32
33
  test = [
33
34
  "build>=1.2",
34
35
  "pytest>=8.0",
@@ -1,3 +1,3 @@
1
1
  """Code Mower package."""
2
2
 
3
- __version__ = "1.2.1"
3
+ __version__ = "1.3.0"
@@ -25,10 +25,13 @@ import re
25
25
  if __package__:
26
26
  try:
27
27
  from . import decisions as code_mower_decisions
28
+ from . import context_review as code_mower_context_review
28
29
  except ImportError: # pragma: no cover - copied tools fallback
29
30
  import decisions as code_mower_decisions # type: ignore
31
+ import context_review as code_mower_context_review # type: ignore
30
32
  else: # pragma: no cover - direct helper execution
31
33
  import decisions as code_mower_decisions # type: ignore
34
+ import context_review as code_mower_context_review # type: ignore
32
35
 
33
36
  MIN_ABBREVIATED_SHA_LENGTH = 7
34
37
  AUTHOR_EXCLUSION_ENV = "CODE_MOWER_AUTHOR_EXCLUSION_JSON"
@@ -454,6 +457,7 @@ def latest_current_audit_verdict(
454
457
  bool,
455
458
  ],
456
459
  decision_authorities: Sequence[str] = (),
460
+ context_required: bool = False,
457
461
  ) -> str:
458
462
  verdict = latest_current_audit_verdict_detail(
459
463
  lane,
@@ -461,6 +465,7 @@ def latest_current_audit_verdict(
461
465
  head_sha=head_sha,
462
466
  trusted_comment_author=trusted_comment_author,
463
467
  decision_authorities=decision_authorities,
468
+ context_required=context_required,
464
469
  )
465
470
  return verdict.verdict if verdict else ""
466
471
 
@@ -475,8 +480,16 @@ def latest_current_audit_verdict_detail(
475
480
  bool,
476
481
  ],
477
482
  decision_authorities: Sequence[str] = (),
483
+ context_required: bool = False,
478
484
  ) -> AuditVerdict | None:
479
485
  verdicts: list[AuditVerdict] = []
486
+ try:
487
+ context_input = code_mower_context_review.latest_input(comments, authorities=decision_authorities)
488
+ except (ValueError, TypeError, RecursionError):
489
+ # A broken latest control declaration cannot expose an older PASS.
490
+ return None
491
+ if context_required and (context_input is None or not context_input['required']):
492
+ return None
480
493
  decisions = code_mower_decisions.collect_decision_records_from_comments(
481
494
  comments,
482
495
  authorities=decision_authorities,
@@ -492,6 +505,22 @@ def latest_current_audit_verdict_detail(
492
505
  head_sha=head_sha,
493
506
  decisions=decisions,
494
507
  )
508
+ failed_context_check = any(marker in body for marker in (
509
+ "<!-- CODE_MOWER_AUDIT_REQUEUE: kind=unknown -->",
510
+ "<!-- CODE_MOWER_AUDIT_REQUEUE: kind=stale -->",
511
+ )) and audit_comment_head_sha(body) == head_sha
512
+ if context_input is not None:
513
+ matches = code_mower_context_review.review_matches(body, context_input, head=head_sha)
514
+ # If the control-comment fetch itself failed, the wrapper cannot
515
+ # name a revision. Its current-head UNKNOWN still invalidates PASS.
516
+ # A verdict explicitly bound to a different revision never does.
517
+ unbound_failure = failed_context_check and code_mower_context_review.REVIEW_MARKER not in body
518
+ if not matches and not unbound_failure:
519
+ continue
520
+ if context_input is not None and failed_context_check:
521
+ # A later failed authorization/input check must supersede an older
522
+ # PASS even when both the code head and selected revision match.
523
+ verdict = "unknown"
495
524
  if verdict:
496
525
  try:
497
526
  comment_id = int(comment.get("id") or 0)
@@ -25,6 +25,8 @@ from datetime import datetime, timezone
25
25
  from pathlib import Path
26
26
  from typing import Any, Dict, List, Optional, Tuple
27
27
 
28
+ from code_mower import context_audit, context_delivery, context_review
29
+
28
30
  if __package__ in {None, "", "tools"}:
29
31
  try:
30
32
  from tools import audit_limits as code_mower_audit_limits
@@ -247,6 +249,8 @@ class ClaudeAuditConfig:
247
249
  decision_authorities: Tuple[str, ...] = ()
248
250
  merge_authority: bool = True
249
251
  calibration_badge: str = ""
252
+ context_revision: Optional[str] = None
253
+ context_state_dir: Optional[Path] = None
250
254
 
251
255
 
252
256
  @dataclass
@@ -949,6 +953,7 @@ def _review_prompt(
949
953
  review_doctrine: str = "",
950
954
  plan_context_text: str = "",
951
955
  decision_registry_text: str = "",
956
+ private_evidence_text: str = "",
952
957
  ) -> str:
953
958
  safe_branch_name = _one_line(branch_name, 200)
954
959
  safe_title = _one_line(title, 500)
@@ -1005,6 +1010,7 @@ Return only the structured JSON object required by the provided schema.
1005
1010
  {doctrine_block}
1006
1011
  {plan_context_block}
1007
1012
  {decision_registry_block}
1013
+ {private_evidence_text}
1008
1014
 
1009
1015
  Repository: {repo}
1010
1016
  Pull request: #{pr_number}
@@ -1473,7 +1479,18 @@ def audit_pr(config: ClaudeAuditConfig, repo: str, pr_number: int) -> ClaudeAudi
1473
1479
  final_fixture_reason: Optional[str] = None
1474
1480
  unknown_reason = ""
1475
1481
 
1476
- if diff_context.was_truncated:
1482
+ private_context = context_audit.prepare(
1483
+ repository=repo, pr=pr_number, head=head_sha_start, host="claude",
1484
+ authorities=decision_authorities, revision=config.context_revision,
1485
+ state_dir=config.context_state_dir,
1486
+ repo_path=local_repo, base_ref=config.base_ref,
1487
+ fetch_comments=lambda: fetch_issue_comments(repo, pr_number, token=config.github_token),
1488
+ )
1489
+
1490
+ if private_context is not None and not private_context.ready:
1491
+ unknown_reason = "Selected context input is unavailable; authorize the selected connection and retry"
1492
+ parsed = _unknown_structured_verdict(unknown_reason)
1493
+ elif diff_context.was_truncated:
1477
1494
  unknown_reason = _diff_truncation_unknown_reason(diff_context)
1478
1495
  parsed = _unknown_structured_verdict(unknown_reason)
1479
1496
  print(
@@ -1534,6 +1551,7 @@ def audit_pr(config: ClaudeAuditConfig, repo: str, pr_number: int) -> ClaudeAudi
1534
1551
  rendered_plan_context.text if rendered_plan_context is not None else ""
1535
1552
  ),
1536
1553
  decision_registry_text=decision_registry_context,
1554
+ private_evidence_text=private_context.text if private_context is not None else "",
1537
1555
  )
1538
1556
 
1539
1557
  attempt_prompt = prompt
@@ -1579,9 +1597,10 @@ def audit_pr(config: ClaudeAuditConfig, repo: str, pr_number: int) -> ClaudeAudi
1579
1597
  config = replace(config, max_budget_usd=raised_budget)
1580
1598
  continue
1581
1599
  if guardrail_reason and attempt < MAX_CLAUDE_AUDIT_ATTEMPTS:
1600
+ visible_reason = "private context verdict needs validation" if private_context is not None and private_context.private else guardrail_reason
1582
1601
  print(
1583
1602
  " structured-verdict guardrail rejected Claude output: "
1584
- f"{guardrail_reason}; retrying once",
1603
+ f"{visible_reason}; retrying once",
1585
1604
  file=sys.stderr,
1586
1605
  flush=True,
1587
1606
  )
@@ -1595,10 +1614,14 @@ def audit_pr(config: ClaudeAuditConfig, repo: str, pr_number: int) -> ClaudeAudi
1595
1614
  dt = time.time() - t0
1596
1615
  print(f" claude audit completed in {dt:.0f}s", file=sys.stderr, flush=True)
1597
1616
  if parsed.mismatch_note:
1598
- print(f" structured-verdict mismatch: {parsed.mismatch_note}", file=sys.stderr, flush=True)
1617
+ note = "private context verdict needs validation" if private_context is not None and private_context.private else parsed.mismatch_note
1618
+ print(f" structured-verdict mismatch: {note}", file=sys.stderr, flush=True)
1599
1619
 
1600
1620
  pr_meta_after = fetch_pull_request(repo, pr_number, token=config.github_token)
1601
1621
  head_sha_end = pr_meta_after["head"]["sha"]
1622
+ if private_context is not None and not private_context.finish(head=head_sha_end, prose=parsed.prose):
1623
+ unknown_reason = "Selected context authorization or review input changed; reattach and review again"
1624
+ parsed = _unknown_structured_verdict(unknown_reason)
1602
1625
  is_stale = head_sha_start != head_sha_end
1603
1626
  actions_run_id = os.environ.get("GITHUB_RUN_ID") or None
1604
1627
  claude_cli_reason = unknown_reason or _claude_cli_failure_reason(
@@ -1642,6 +1665,17 @@ def audit_pr(config: ClaudeAuditConfig, repo: str, pr_number: int) -> ClaudeAudi
1642
1665
  result_verdict = parsed.verdict
1643
1666
  trailer = BLOCKED_TRAILER if parsed.verdict == "BLOCKED" else DONE_TRAILER
1644
1667
 
1668
+ if private_context is not None and private_context.metadata is not None:
1669
+ if private_context.private:
1670
+ comment_body = context_delivery.public_verdict(
1671
+ private_context.delivery, provider="Claude", head=head_sha_start,
1672
+ verdict=result_verdict, counts=[parsed.p0_count, parsed.p1_count, parsed.p2_count, parsed.p3_count],
1673
+ trailer=trailer, actions_run_id=actions_run_id, merge_authority=config.merge_authority,
1674
+ )
1675
+ else:
1676
+ footer = context_review.marker(private_context.metadata, review=True) + "\n" + trailer
1677
+ comment_body = limit_comment_body(comment_body.rsplit(trailer, 1)[0] + footer + "\n", footer, provider_name="Claude")
1678
+
1645
1679
  result = ClaudeAuditResult(
1646
1680
  repo=repo,
1647
1681
  pr_number=pr_number,
@@ -1656,7 +1690,7 @@ def audit_pr(config: ClaudeAuditConfig, repo: str, pr_number: int) -> ClaudeAudi
1656
1690
  )
1657
1691
 
1658
1692
  if not config.dry_run:
1659
- if result_verdict == "UNKNOWN":
1693
+ if result_verdict == "UNKNOWN" and not (private_context is not None and private_context.private):
1660
1694
  dump_path = _dump_claude_cli_failure(
1661
1695
  repo=repo,
1662
1696
  pr_number=pr_number,
@@ -1694,7 +1728,8 @@ def audit_pr(config: ClaudeAuditConfig, repo: str, pr_number: int) -> ClaudeAudi
1694
1728
  file=sys.stderr,
1695
1729
  flush=True,
1696
1730
  )
1697
- _write_claude_raw_output_sidecar(artifact_path, raw_output_attempts)
1731
+ if not (private_context is not None and private_context.private):
1732
+ _write_claude_raw_output_sidecar(artifact_path, raw_output_attempts)
1698
1733
  if quarantine_reason:
1699
1734
  print(
1700
1735
  " runtime guard quarantined verdict artifact: "
@@ -1785,6 +1820,8 @@ def _parse_args(argv: Optional[List[str]] = None) -> argparse.Namespace:
1785
1820
  ),
1786
1821
  )
1787
1822
  ap.add_argument("--repo-paths", default=os.environ.get("CLAUDE_AUDIT_REPO_PATHS", ""))
1823
+ ap.add_argument("--context-revision", help="Require this explicitly attached private context input revision")
1824
+ ap.add_argument("--context-state-dir", type=Path, help="Private context store outside the repository")
1788
1825
  ap.add_argument("--claude-cli-path", default=os.environ.get("CLAUDE_CLI_PATH", DEFAULT_CLAUDE_CLI_PATH))
1789
1826
  ap.add_argument("--model", default=os.environ.get("CLAUDE_AUDIT_MODEL", DEFAULT_CLAUDE_MODEL))
1790
1827
  ap.add_argument("--max-budget-usd", default=_env_text("CLAUDE_AUDIT_MAX_BUDGET_USD"))
@@ -1997,6 +2034,8 @@ def main(argv: Optional[List[str]] = None) -> int:
1997
2034
  prompt_lenses=code_mower_prompts.split_lenses(args.prompt_lenses),
1998
2035
  prompt_dir=args.prompt_dir,
1999
2036
  include_plan_context=not args.no_plan_context,
2037
+ context_revision=args.context_revision,
2038
+ context_state_dir=args.context_state_dir,
2000
2039
  project_context_manifest=args.project_context_manifest,
2001
2040
  external_context_manifest=args.external_context_manifest,
2002
2041
  max_plan_context_bytes=args.max_plan_context_bytes,
@@ -68,6 +68,9 @@ Trailer protocol (mirrors Devin/local LLM):
68
68
 
69
69
  from __future__ import annotations
70
70
 
71
+ from code_mower import context_audit, context_delivery, context_review
72
+ from code_mower.context_contract import ContextError
73
+
71
74
  import argparse
72
75
  import json
73
76
  import os
@@ -288,6 +291,9 @@ class AuditConfig:
288
291
  # Optional human-facing calibration status. This must never decide merge
289
292
  # authority; it only renders as a separate badge line in the comment.
290
293
  calibration_badge: str = ""
294
+ context_revision: Optional[str] = None
295
+ context_state_dir: Optional[Path] = None
296
+ private_evidence: str = field(default="", repr=False)
291
297
 
292
298
 
293
299
  @dataclass
@@ -1351,12 +1357,15 @@ def run_codex_review(
1351
1357
  review_path = tmp_dir / "review.txt"
1352
1358
  prompt = ""
1353
1359
  context_omission_notice = ""
1354
- if trusted_context.strip():
1360
+ if trusted_context.strip() or config.private_evidence:
1355
1361
  wrapper_context = _build_codex_wrapper_review_context(
1356
1362
  worktree_path,
1357
1363
  config,
1358
1364
  )
1359
1365
  if wrapper_context.was_truncated:
1366
+ if config.private_evidence:
1367
+ shutil.rmtree(str(tmp_dir), ignore_errors=True)
1368
+ raise ContextError("private evidence cannot be omitted from the review")
1360
1369
  context_omission_notice = _codex_context_omission_notice(
1361
1370
  diff_bytes=wrapper_context.full_diff_bytes,
1362
1371
  hard_limit_bytes=wrapper_context.hard_limit_bytes,
@@ -1376,6 +1385,7 @@ def run_codex_review(
1376
1385
  base_ref=config.base_ref,
1377
1386
  trusted_context=trusted_context,
1378
1387
  review_context=wrapper_context,
1388
+ private_evidence_text=config.private_evidence,
1379
1389
  )
1380
1390
  env = _build_subprocess_env(None)
1381
1391
  if not prompt:
@@ -1461,6 +1471,7 @@ def _codex_wrapper_review_prompt(
1461
1471
  base_ref: str,
1462
1472
  trusted_context: str,
1463
1473
  review_context: _CodexWrapperReviewContext,
1474
+ private_evidence_text: str = "",
1464
1475
  ) -> str:
1465
1476
  nonce = secrets.token_hex(8)
1466
1477
  context_begin = f"----- BEGIN TRUSTED AUDIT CONTEXT [{nonce}] -----"
@@ -1497,6 +1508,8 @@ Trusted Code Mower audit context:
1497
1508
  {trusted_context.rstrip()}
1498
1509
  {context_end}
1499
1510
 
1511
+ {private_evidence_text}
1512
+
1500
1513
  Base ref: {base_ref}
1501
1514
  Diff truncation: {truncation_note}
1502
1515
  Diff bytes: included {review_context.included_diff_bytes} of at least
@@ -1863,6 +1876,16 @@ def audit_pr(config: AuditConfig, repo: str, pr_number: int) -> AuditResult:
1863
1876
  config.decision_authorities,
1864
1877
  trusted_ref=config.base_ref,
1865
1878
  )
1879
+ private_context = context_audit.prepare(
1880
+ repository=repo, pr=pr_number, head=head_sha_start, host="codex",
1881
+ authorities=decision_authorities, revision=config.context_revision,
1882
+ state_dir=config.context_state_dir,
1883
+ repo_path=local_repo, base_ref=config.base_ref,
1884
+ fetch_comments=lambda: fetch_issue_comments(repo, pr_number, token=config.github_token),
1885
+ )
1886
+ private_input_unavailable = private_context is not None and not private_context.ready
1887
+ if private_context is not None:
1888
+ config = replace(config, private_evidence=private_context.text)
1866
1889
  review_context_summary = "review context diagnostics unavailable"
1867
1890
  review_context: ReviewContextDiagnostics | None = None
1868
1891
  context_notice = ""
@@ -2027,7 +2050,7 @@ def audit_pr(config: AuditConfig, repo: str, pr_number: int) -> AuditResult:
2027
2050
  )
2028
2051
  effective_trusted_context = trusted_audit_context
2029
2052
  if (
2030
- trusted_audit_context.strip()
2053
+ (trusted_audit_context.strip() or config.private_evidence)
2031
2054
  and review_context is not None
2032
2055
  and review_context.was_truncated
2033
2056
  ):
@@ -2036,23 +2059,33 @@ def audit_pr(config: AuditConfig, repo: str, pr_number: int) -> AuditResult:
2036
2059
  hard_limit_bytes=review_context.hard_limit_bytes,
2037
2060
  )
2038
2061
  effective_trusted_context = ""
2062
+ if config.private_evidence:
2063
+ private_input_unavailable = True
2039
2064
  print(
2040
- f" {context_notice}; using context-free codex review --base",
2065
+ f" {context_notice}; " + ("selected context cannot be omitted; emitting UNKNOWN"
2066
+ if config.private_evidence else "using context-free codex review --base"),
2041
2067
  file=sys.stderr,
2042
2068
  flush=True,
2043
2069
  )
2044
2070
  t0 = time.time()
2045
- review_text, review_stderr = run_codex_review(
2046
- config,
2047
- worktree_path,
2048
- effective_trusted_context,
2049
- )
2071
+ review_text, review_stderr = "", ""
2072
+ if not private_input_unavailable:
2073
+ try:
2074
+ review_text, review_stderr = run_codex_review(
2075
+ config,
2076
+ worktree_path,
2077
+ effective_trusted_context,
2078
+ )
2079
+ except ContextError:
2080
+ private_input_unavailable = True
2050
2081
  if not context_notice:
2051
2082
  context_notice = _codex_context_omission_notice_from_diagnostics(
2052
2083
  review_stderr
2053
2084
  )
2054
2085
  if context_notice:
2055
2086
  effective_trusted_context = ""
2087
+ if config.private_evidence:
2088
+ private_input_unavailable = True
2056
2089
  dt = time.time() - t0
2057
2090
  print(f" codex review completed in {dt:.0f}s", file=sys.stderr, flush=True)
2058
2091
  finally:
@@ -2063,11 +2096,15 @@ def audit_pr(config: AuditConfig, repo: str, pr_number: int) -> AuditResult:
2063
2096
  # may receive the same trusted context only to apply transport policy
2064
2097
  # to findings already present in the review prose.
2065
2098
  t0 = time.time()
2066
- parsed, structure_stdout, structure_stderr = run_codex_verdict_structuring(
2067
- config,
2068
- review_text,
2069
- effective_trusted_context,
2070
- )
2099
+ if private_input_unavailable:
2100
+ parsed = _unknown_structured_verdict("Selected context input could not be delivered; reattach and review again")
2101
+ structure_stdout, structure_stderr = "", ""
2102
+ else:
2103
+ parsed, structure_stdout, structure_stderr = run_codex_verdict_structuring(
2104
+ config,
2105
+ review_text,
2106
+ effective_trusted_context,
2107
+ )
2071
2108
  dt = time.time() - t0
2072
2109
  print(
2073
2110
  f" codex verdict structuring completed in {dt:.0f}s",
@@ -2075,8 +2112,9 @@ def audit_pr(config: AuditConfig, repo: str, pr_number: int) -> AuditResult:
2075
2112
  flush=True,
2076
2113
  )
2077
2114
  if parsed.mismatch_note:
2115
+ note = "private context verdict needs validation" if private_context is not None and private_context.private else parsed.mismatch_note
2078
2116
  print(
2079
- f" structured-verdict mismatch: {parsed.mismatch_note}",
2117
+ f" structured-verdict mismatch: {note}",
2080
2118
  file=sys.stderr,
2081
2119
  flush=True,
2082
2120
  )
@@ -2097,6 +2135,8 @@ def audit_pr(config: AuditConfig, repo: str, pr_number: int) -> AuditResult:
2097
2135
  # the verdict applies to a no-longer-current SHA — requeue.
2098
2136
  pr_meta_after = fetch_pull_request(repo, pr_number, token=config.github_token)
2099
2137
  head_sha_end = pr_meta_after["head"]["sha"]
2138
+ if private_context is not None and not private_context.finish(head=head_sha_end, prose=parsed.prose):
2139
+ parsed = _unknown_structured_verdict("Selected context authorization or review input changed; reattach and review again")
2100
2140
  is_stale = head_sha_start != head_sha_end
2101
2141
  actions_run_id = os.environ.get("GITHUB_RUN_ID") or None
2102
2142
 
@@ -2125,7 +2165,7 @@ def audit_pr(config: AuditConfig, repo: str, pr_number: int) -> AuditResult:
2125
2165
  # without this dump there's no way to diagnose "real structured
2126
2166
  # output drift or one-shot Codex CLI flake?" after the fact.
2127
2167
  # Best-effort: a logging failure must not interrupt the audit.
2128
- dump_path = dump_cli_failure(
2168
+ dump_path = None if private_context is not None and private_context.private else dump_cli_failure(
2129
2169
  repo=repo,
2130
2170
  pr_number=pr_number,
2131
2171
  head_sha=head_sha_start,
@@ -2166,6 +2206,17 @@ def audit_pr(config: AuditConfig, repo: str, pr_number: int) -> AuditResult:
2166
2206
  result_verdict = parsed.verdict
2167
2207
  trailer = BLOCKED_TRAILER if parsed.verdict == "BLOCKED" else DONE_TRAILER
2168
2208
 
2209
+ if private_context is not None and private_context.metadata is not None:
2210
+ if private_context.private:
2211
+ comment_body = context_delivery.public_verdict(
2212
+ private_context.delivery, provider="Codex", head=head_sha_start,
2213
+ verdict=result_verdict, counts=[parsed.p0_count, parsed.p1_count, parsed.p2_count, parsed.p3_count],
2214
+ trailer=trailer, actions_run_id=actions_run_id, merge_authority=config.merge_authority,
2215
+ )
2216
+ else:
2217
+ footer = context_review.marker(private_context.metadata, review=True) + "\n" + trailer
2218
+ comment_body = limit_comment_body(comment_body.rsplit(trailer, 1)[0] + footer + "\n", footer, provider_name="Codex")
2219
+
2169
2220
  result = AuditResult(
2170
2221
  repo=repo,
2171
2222
  pr_number=pr_number,
@@ -2256,6 +2307,8 @@ def _parse_args(argv: Optional[List[str]] = None) -> argparse.Namespace:
2256
2307
  )
2257
2308
  ap.add_argument("--repo", help="owner/repo, e.g. owner/repo")
2258
2309
  ap.add_argument("--pr", type=int, help="PR number")
2310
+ ap.add_argument("--context-revision", help="Require this explicitly attached private context input revision")
2311
+ ap.add_argument("--context-state-dir", type=Path, help="Private context store outside the repository")
2259
2312
  ap.add_argument(
2260
2313
  "--repost-verdict-artifact",
2261
2314
  type=Path,
@@ -2602,6 +2655,8 @@ def main(argv: Optional[List[str]] = None) -> int:
2602
2655
  venv_path=explicit_venv,
2603
2656
  disable_venv=disable_venv,
2604
2657
  include_plan_context=not args.no_plan_context,
2658
+ context_revision=args.context_revision,
2659
+ context_state_dir=args.context_state_dir,
2605
2660
  project_context_manifest=args.project_context_manifest,
2606
2661
  external_context_manifest=args.external_context_manifest,
2607
2662
  max_plan_context_bytes=args.max_plan_context_bytes,