code-mower 0.5.0b27__tar.gz → 0.5.0b29__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 (270) hide show
  1. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/PKG-INFO +6 -6
  2. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/README.md +5 -5
  3. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/pyproject.toml +1 -1
  4. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/__init__.py +1 -1
  5. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cli.py +4 -1
  6. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/doctor.py +40 -9
  7. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/export.py +42 -0
  8. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/providers/provenance.py +21 -2
  9. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower.egg-info/PKG-INFO +6 -6
  10. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_cloud_client.py +56 -1
  11. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_provider_local_cli.py +61 -2
  12. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_release_hygiene.py +34 -34
  13. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/CODE_OF_CONDUCT.md +0 -0
  14. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/LICENSE +0 -0
  15. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/MANIFEST.in +0 -0
  16. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/NOTICE +0 -0
  17. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/SUPPORT.md +0 -0
  18. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/requirements/requirements.txt +0 -0
  19. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/setup.cfg +0 -0
  20. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/adapters/__init__.py +0 -0
  21. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/adapters/_base.py +0 -0
  22. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/adapters/cursor_bugbot.py +0 -0
  23. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/adapters/gitar.py +0 -0
  24. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/adapters/greptile.py +0 -0
  25. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/adapters/qodo.py +0 -0
  26. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
  27. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/audit_handoff_log.py +0 -0
  28. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/audit_labeler_lib.py +0 -0
  29. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/audit_progress.py +0 -0
  30. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/blind_review_artifacts.py +0 -0
  31. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/blind_review_coordinator.py +0 -0
  32. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/bootstrap.py +0 -0
  33. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/builder_experiment.py +0 -0
  34. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/__init__.py +0 -0
  35. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/arms.py +0 -0
  36. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/auto_discovery.py +0 -0
  37. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/commands.py +0 -0
  38. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/context_inputs.py +0 -0
  39. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/corpus.py +0 -0
  40. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/effect_report.py +0 -0
  41. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/evidence.py +0 -0
  42. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/evidence_report.py +0 -0
  43. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/identity.py +0 -0
  44. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/metrics.py +0 -0
  45. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/overlap.py +0 -0
  46. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/planning.py +0 -0
  47. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/policy.py +0 -0
  48. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/results.py +0 -0
  49. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/run_results.py +0 -0
  50. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/run_status.py +0 -0
  51. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/runner.py +0 -0
  52. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/truth.py +0 -0
  53. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/calibration/value_report.py +0 -0
  54. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/checks.py +0 -0
  55. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/claude_audit_pr.py +0 -0
  56. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/claude_cli_bounce.py +0 -0
  57. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/claude_cli_environment.py +0 -0
  58. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/clear_stale.py +0 -0
  59. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud.py +0 -0
  60. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/__init__.py +0 -0
  61. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/bundle.py +0 -0
  62. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/dogfood.py +0 -0
  63. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/endpoints.py +0 -0
  64. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/errors.py +0 -0
  65. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/events.py +0 -0
  66. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/git_metadata.py +0 -0
  67. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/manifest.py +0 -0
  68. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/operations.py +0 -0
  69. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/reports.py +0 -0
  70. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/setup.py +0 -0
  71. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/cloud_client/upload.py +0 -0
  72. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/code_mower_calibration.py +0 -0
  73. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/code_mower_context_packs.py +0 -0
  74. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/code_mower_merge.py +0 -0
  75. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/code_mower_telemetry.py +0 -0
  76. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
  77. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/codex_audit_env_preflight.py +0 -0
  78. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/codex_audit_pr.py +0 -0
  79. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/codex_audit_schema_smoke.py +0 -0
  80. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/codex_audit_verdict.schema.json +0 -0
  81. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/config.py +0 -0
  82. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor.py +0 -0
  83. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/__init__.py +0 -0
  84. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/cloud.py +0 -0
  85. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/common.py +0 -0
  86. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github.py +0 -0
  87. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_actions.py +0 -0
  88. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
  89. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
  90. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
  91. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
  92. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
  93. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
  94. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
  95. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
  96. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_api.py +0 -0
  97. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_branch.py +0 -0
  98. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_config.py +0 -0
  99. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_provider.py +0 -0
  100. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/github_repo.py +0 -0
  101. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/groups.py +0 -0
  102. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/models.py +0 -0
  103. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/output.py +0 -0
  104. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/presets.py +0 -0
  105. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/privacy.py +0 -0
  106. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
  107. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
  108. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
  109. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_env.py +0 -0
  110. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
  111. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
  112. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
  113. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
  114. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
  115. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_probe.py +0 -0
  116. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
  117. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
  118. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
  119. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
  120. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/provider_review_hygiene.py +0 -0
  121. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/providers.py +0 -0
  122. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/registry.py +0 -0
  123. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/runner.py +0 -0
  124. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/runtime.py +0 -0
  125. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
  126. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/gemini_cli_audit_pr.py +0 -0
  127. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/hermes_cli_audit_pr.py +0 -0
  128. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/init.py +0 -0
  129. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/lane_configs/__init__.py +0 -0
  130. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/lane_configs/aider.py +0 -0
  131. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
  132. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/lane_configs/claude.py +0 -0
  133. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/lane_configs/codex.py +0 -0
  134. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/lane_configs/devin.py +0 -0
  135. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/lane_configs/gemini_cli.py +0 -0
  136. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/lane_configs/hermes_cli.py +0 -0
  137. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/lane_configs/local_llm.py +0 -0
  138. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/local_llm_audit_pr.py +0 -0
  139. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/local_llm_bakeoff.py +0 -0
  140. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/local_llm_calibration.py +0 -0
  141. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/local_llm_profiles.py +0 -0
  142. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/migration.py +0 -0
  143. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/migration_install.py +0 -0
  144. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/migration_mirror.py +0 -0
  145. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/migration_readiness.py +0 -0
  146. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/migration_rehearsal.py +0 -0
  147. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/next_steps.py +0 -0
  148. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/package.py +0 -0
  149. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/package_content.py +0 -0
  150. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/package_manifest.py +0 -0
  151. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/package_paths.py +0 -0
  152. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/package_rendering.py +0 -0
  153. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/package_static.py +0 -0
  154. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/prompts.py +0 -0
  155. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_registry.py +0 -0
  156. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/__init__.py +0 -0
  157. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/comments.py +0 -0
  158. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/git.py +0 -0
  159. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/github_auth.py +0 -0
  160. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/github_pr.py +0 -0
  161. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/pr_worktree.py +0 -0
  162. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/process.py +0 -0
  163. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/repo_paths.py +0 -0
  164. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/text_schema.py +0 -0
  165. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
  166. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/provider_runners/workspace.py +0 -0
  167. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/providers/__init__.py +0 -0
  168. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/providers/local_cli.py +0 -0
  169. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/release_readiness.py +0 -0
  170. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/reviewer_metrics.py +0 -0
  171. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/saas_reviewer_labeler.py +0 -0
  172. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/secrets.py +0 -0
  173. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/builder-experiment.example.json +0 -0
  174. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/calibration-corpus.example.json +0 -0
  175. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/calibration-corpus.json +0 -0
  176. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/code-mower.example.yml +0 -0
  177. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/context-packs.example.json +0 -0
  178. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
  179. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
  180. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
  181. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
  182. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
  183. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/lane_prompts/operability.md +0 -0
  184. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
  185. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
  186. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/product-support/code_mower +0 -0
  187. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
  188. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
  189. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
  190. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
  191. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
  192. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/providers.yml +0 -0
  193. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/reviewer-spend.example.json +0 -0
  194. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
  195. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  196. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
  197. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
  198. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  199. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
  200. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
  201. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
  202. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/trailer_comment_labeler.py +0 -0
  203. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower/versioning.py +0 -0
  204. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower.egg-info/SOURCES.txt +0 -0
  205. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower.egg-info/dependency_links.txt +0 -0
  206. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower.egg-info/entry_points.txt +0 -0
  207. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower.egg-info/requires.txt +0 -0
  208. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/src/code_mower.egg-info/top_level.txt +0 -0
  209. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/builder-experiment.example.json +0 -0
  210. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/calibration-corpus.example.json +0 -0
  211. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/calibration-corpus.json +0 -0
  212. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/code-mower.yml.j2 +0 -0
  213. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/context-packs.example.json +0 -0
  214. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/cursor/BUGBOT.md +0 -0
  215. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/acp_bridge.yml +0 -0
  216. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/aider.yml +0 -0
  217. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/antigravity_cli.yml +0 -0
  218. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/claude_audit.yml +0 -0
  219. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/claude_review.yml +0 -0
  220. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/coderabbit_cli.yml +0 -0
  221. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/codex.yml +0 -0
  222. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/cursor_bugbot.yml +0 -0
  223. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/devin.yml +0 -0
  224. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/gemini_cli.yml +0 -0
  225. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/gitar.yml +0 -0
  226. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/greptile.yml +0 -0
  227. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/hermes_cli.yml +0 -0
  228. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/local_llm.yml +0 -0
  229. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers/qodo.yml +0 -0
  230. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/providers.yml +0 -0
  231. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/reviewer-spend.example.json +0 -0
  232. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/reviewer-value-report.example.md +0 -0
  233. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
  234. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
  235. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/workflows/hosted-bridge.yml.j2 +0 -0
  236. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/workflows/local-cli-audit.yml.j2 +0 -0
  237. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  238. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/workflows/review-clear-stale.yml.j2 +0 -0
  239. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
  240. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
  241. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_calibration_effect_report.py +0 -0
  242. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_calibration_truth.py +0 -0
  243. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_checks.py +0 -0
  244. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_claude_cli_bounce.py +0 -0
  245. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_clear_stale.py +0 -0
  246. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_cloud_git_metadata.py +0 -0
  247. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_cloud_manifest.py +0 -0
  248. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_cloud_reports.py +0 -0
  249. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_coderabbit_cli_audit_pr.py +0 -0
  250. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_actions_cost_summary.py +0 -0
  251. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_actions_failure_selection.py +0 -0
  252. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_boundaries.py +0 -0
  253. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_github_checks.py +0 -0
  254. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_output.py +0 -0
  255. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_privacy.py +0 -0
  256. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_provider_env_required.py +0 -0
  257. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_provider_env_tokens.py +0 -0
  258. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_provider_probe.py +0 -0
  259. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_provider_review_hygiene.py +0 -0
  260. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_doctor_registry.py +0 -0
  261. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_local_llm_github_helpers.py +0 -0
  262. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_provider_runners_comments.py +0 -0
  263. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_provider_runners_git.py +0 -0
  264. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_provider_runners_github_pr.py +0 -0
  265. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_provider_runners_pr_worktree.py +0 -0
  266. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_provider_runners_process.py +0 -0
  267. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_provider_runners_repo_paths.py +0 -0
  268. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_provider_runners_text_schema.py +0 -0
  269. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_provider_runners_workspace.py +0 -0
  270. {code_mower-0.5.0b27 → code_mower-0.5.0b29}/tests/test_reviewer_metrics_core.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-mower
3
- Version: 0.5.0b27
3
+ Version: 0.5.0b29
4
4
  Summary: Multi-reviewer AI code audit orchestration
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.11
@@ -101,11 +101,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
101
101
 
102
102
  ```bash
103
103
  python3.12 --version
104
- pipx install --python python3.12 code-mower==0.5.0b27
104
+ pipx install --python python3.12 code-mower==0.5.0b29
105
105
  code-mower --version
106
106
  ```
107
107
 
108
- `0.5.0b27` is a beta release. Until Code Mower publishes a stable `1.0`
108
+ `0.5.0b29` is a beta release. Until Code Mower publishes a stable `1.0`
109
109
  line, use the explicit beta version above or allow prereleases with:
110
110
 
111
111
  ```bash
@@ -148,7 +148,7 @@ First-time command map: [docs/launch-command-surface.md](docs/launch-command-sur
148
148
 
149
149
  The current PyPI beta has been rehearsed end-to-end from a clean install:
150
150
  [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
151
- the latest 10/10 public-package readiness proof for `code-mower==0.5.0b27`.
151
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b29`.
152
152
 
153
153
  ## Why Not Just Run Codex Or Claude Yourself?
154
154
 
@@ -253,9 +253,9 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
253
253
 
254
254
  ## Installation Status
255
255
 
256
- The current public beta is `v0.5.0-beta.27` from
256
+ The current public beta is `v0.5.0-beta.29` from
257
257
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
258
- as `code-mower==0.5.0b27` on [PyPI](https://pypi.org/project/code-mower/).
258
+ as `code-mower==0.5.0b29` on [PyPI](https://pypi.org/project/code-mower/).
259
259
  GitHub releases remain the auditable source for tags, build artifacts, and
260
260
  release notes.
261
261
 
@@ -86,11 +86,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
86
86
 
87
87
  ```bash
88
88
  python3.12 --version
89
- pipx install --python python3.12 code-mower==0.5.0b27
89
+ pipx install --python python3.12 code-mower==0.5.0b29
90
90
  code-mower --version
91
91
  ```
92
92
 
93
- `0.5.0b27` is a beta release. Until Code Mower publishes a stable `1.0`
93
+ `0.5.0b29` is a beta release. Until Code Mower publishes a stable `1.0`
94
94
  line, use the explicit beta version above or allow prereleases with:
95
95
 
96
96
  ```bash
@@ -133,7 +133,7 @@ First-time command map: [docs/launch-command-surface.md](docs/launch-command-sur
133
133
 
134
134
  The current PyPI beta has been rehearsed end-to-end from a clean install:
135
135
  [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
136
- the latest 10/10 public-package readiness proof for `code-mower==0.5.0b27`.
136
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b29`.
137
137
 
138
138
  ## Why Not Just Run Codex Or Claude Yourself?
139
139
 
@@ -238,9 +238,9 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
238
238
 
239
239
  ## Installation Status
240
240
 
241
- The current public beta is `v0.5.0-beta.27` from
241
+ The current public beta is `v0.5.0-beta.29` from
242
242
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
243
- as `code-mower==0.5.0b27` on [PyPI](https://pypi.org/project/code-mower/).
243
+ as `code-mower==0.5.0b29` on [PyPI](https://pypi.org/project/code-mower/).
244
244
  GitHub releases remain the auditable source for tags, build artifacts, and
245
245
  release notes.
246
246
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-mower"
7
- version = "0.5.0b27"
7
+ version = "0.5.0b29"
8
8
  description = "Multi-reviewer AI code audit orchestration"
9
9
  requires-python = ">=3.11"
10
10
  readme = "README.md"
@@ -1,3 +1,3 @@
1
1
  """Code Mower package."""
2
2
 
3
- __version__ = "0.5.0b27"
3
+ __version__ = "0.5.0b29"
@@ -14,7 +14,7 @@ from pathlib import Path
14
14
  if __package__ in {None, ""}:
15
15
  raise SystemExit(
16
16
  "code_mower.cli is a packaged entrypoint. Install Code Mower with "
17
- "`pipx install code-mower==0.5.0b27`, or run source checkouts with "
17
+ "`pipx install code-mower==0.5.0b29`, or run source checkouts with "
18
18
  "`PYTHONPATH=src python -m code_mower.cli`."
19
19
  )
20
20
 
@@ -175,6 +175,7 @@ def _providers_main(argv: list[str]) -> int:
175
175
  print(f"Status: {report['status']}")
176
176
  print(f"Providers: {report['provider_count']}")
177
177
  print(f"Missing model env: {report['missing_model_env_count']}")
178
+ print(f"Missing CLI version probes: {report['missing_version_probe_count']}")
178
179
  for row in report["providers"]:
179
180
  if row["action"] == "set_model_env":
180
181
  aliases = ", ".join(row["env_names"]) or "none"
@@ -182,6 +183,8 @@ def _providers_main(argv: list[str]) -> int:
182
183
  f"- {row['lane_id']}: set {row['preferred_env']} "
183
184
  f"(aliases: {aliases})"
184
185
  )
186
+ elif row["driver"] == "local_cli" and row["version_source"] == "missing":
187
+ print(f"- {row['lane_id']}: CLI version probe is missing")
185
188
  elif row["model_source"] == "vendor_hidden":
186
189
  print(f"- {row['lane_id']}: provider hides model/version metadata")
187
190
  elif row["model_source"] == "default":
@@ -183,19 +183,40 @@ def run_cloud_doctor(
183
183
  )
184
184
  if isinstance(provenance, dict):
185
185
  missing_model_events = int(
186
+ provenance.get(
187
+ "benchmark_events_missing_model_provenance",
188
+ provenance.get("events_missing_model_provenance"),
189
+ )
190
+ or 0
191
+ )
192
+ raw_missing_model_events = int(
186
193
  provenance.get("events_missing_model_provenance") or 0
187
194
  )
188
195
  provenance_tools = provenance.get("tools", [])
189
196
  if not isinstance(provenance_tools, list):
190
197
  provenance_tools = []
191
- missing_model_tools = sorted(
192
- {
193
- str(tool.get("provider") or tool.get("tool_name") or "unknown")
194
- for tool in provenance_tools
195
- if isinstance(tool, dict)
196
- and "missing" in set(tool.get("model_sources") or [])
197
- }
198
+ benchmark_missing_providers = provenance.get(
199
+ "benchmark_model_missing_providers"
198
200
  )
201
+ if isinstance(benchmark_missing_providers, list):
202
+ missing_model_tools = sorted(
203
+ {
204
+ str(provider).strip()
205
+ for provider in benchmark_missing_providers
206
+ if str(provider).strip()
207
+ }
208
+ )
209
+ else:
210
+ missing_model_tools = sorted(
211
+ {
212
+ str(
213
+ tool.get("provider") or tool.get("tool_name") or "unknown"
214
+ )
215
+ for tool in provenance_tools
216
+ if isinstance(tool, dict)
217
+ and "missing" in set(tool.get("model_sources") or [])
218
+ }
219
+ )
199
220
  model_env_by_provider = _provider_model_env_names(missing_model_tools)
200
221
  model_env_examples = sorted(
201
222
  {
@@ -236,10 +257,13 @@ def run_cloud_doctor(
236
257
  "name": "model-provenance",
237
258
  "status": "warn",
238
259
  "message": (
239
- f"{missing_model_events} events are missing model provenance"
260
+ f"{missing_model_events} benchmark evidence events "
261
+ "are missing model provenance"
240
262
  ),
241
263
  "detail": {
242
264
  "providers": missing_model_tools,
265
+ "raw_missing_model_events": raw_missing_model_events,
266
+ "benchmark_missing_model_events": missing_model_events,
243
267
  "model_env_by_provider": model_env_by_provider,
244
268
  "model_env_examples": model_env_examples,
245
269
  "model_env_commands": model_env_commands,
@@ -253,7 +277,14 @@ def run_cloud_doctor(
253
277
  {
254
278
  "name": "model-provenance",
255
279
  "status": "pass",
256
- "message": "bundle has model provenance for all structured events",
280
+ "message": (
281
+ "bundle has model provenance for all benchmark evidence "
282
+ "events"
283
+ ),
284
+ "detail": {
285
+ "raw_missing_model_events": raw_missing_model_events,
286
+ "benchmark_missing_model_events": missing_model_events,
287
+ },
257
288
  }
258
289
  )
259
290
  except CloudBundleError as exc:
@@ -20,6 +20,15 @@ from .errors import CloudBundleError
20
20
  from .events import normalize_event, safe_kind
21
21
 
22
22
 
23
+ INVENTORY_ONLY_PROVENANCE_EVENT_TYPES = {"provider_catalog_snapshot"}
24
+
25
+
26
+ def is_benchmark_provenance_event(event: dict[str, Any]) -> bool:
27
+ """Return whether an event should count toward benchmark provenance coverage."""
28
+
29
+ return str(event.get("event_type") or "") not in INVENTORY_ONLY_PROVENANCE_EVENT_TYPES
30
+
31
+
23
32
  def safe_target_name(path: Path, index: int, *, anonymous: bool = False) -> str:
24
33
  suffix = path.suffix.lower()
25
34
  if suffix not in {".json", ".jsonl", ".md", ".txt"}:
@@ -245,12 +254,25 @@ def build_provenance_summary(events: list[dict[str, Any]]) -> dict[str, Any]:
245
254
  missing_tool_events = 0
246
255
  missing_model_events = 0
247
256
  missing_tool_version_events = 0
257
+ benchmark_event_count = 0
258
+ benchmark_missing_model_events = 0
259
+ benchmark_missing_tool_version_events = 0
260
+ benchmark_model_missing_providers: set[str] = set()
248
261
  for event in events:
262
+ is_benchmark_event = is_benchmark_provenance_event(event)
263
+ if is_benchmark_event:
264
+ benchmark_event_count += 1
249
265
  tool = event.get("tool")
250
266
  if not isinstance(tool, dict):
251
267
  missing_tool_events += 1
252
268
  missing_model_events += 1
253
269
  missing_tool_version_events += 1
270
+ if is_benchmark_event:
271
+ benchmark_missing_model_events += 1
272
+ benchmark_missing_tool_version_events += 1
273
+ benchmark_model_missing_providers.add(
274
+ str(event.get("provider") or "unknown").strip() or "unknown"
275
+ )
254
276
  continue
255
277
  tool_name = str(tool.get("tool_name") or "").strip()
256
278
  provider = str(tool.get("provider") or event.get("provider") or "").strip()
@@ -262,13 +284,24 @@ def build_provenance_summary(events: list[dict[str, Any]]) -> dict[str, Any]:
262
284
  missing_tool_events += 1
263
285
  missing_model_events += 1
264
286
  missing_tool_version_events += 1
287
+ if is_benchmark_event:
288
+ benchmark_missing_model_events += 1
289
+ benchmark_missing_tool_version_events += 1
290
+ benchmark_model_missing_providers.add("unknown")
265
291
  continue
266
292
  if not model and not model_version_raw and model_source in {"", "missing"}:
267
293
  missing_model_events += 1
294
+ if is_benchmark_event:
295
+ benchmark_missing_model_events += 1
296
+ benchmark_model_missing_providers.add(
297
+ provider or tool_name or "unknown"
298
+ )
268
299
  if not tool_version:
269
300
  version_source = str(tool.get("version_source") or "").strip()
270
301
  if version_source in {"", "missing"}:
271
302
  missing_tool_version_events += 1
303
+ if is_benchmark_event:
304
+ benchmark_missing_tool_version_events += 1
272
305
  key = (tool_name or "unknown", provider or "unknown", model or "")
273
306
  row = tools.setdefault(
274
307
  key,
@@ -328,6 +361,15 @@ def build_provenance_summary(events: list[dict[str, Any]]) -> dict[str, Any]:
328
361
  "events_with_tool_version_provenance": len(events)
329
362
  - missing_tool_version_events,
330
363
  "events_missing_tool_version_provenance": missing_tool_version_events,
364
+ "inventory_event_count": len(events) - benchmark_event_count,
365
+ "benchmark_event_count": benchmark_event_count,
366
+ "benchmark_events_with_model_provenance": benchmark_event_count
367
+ - benchmark_missing_model_events,
368
+ "benchmark_events_missing_model_provenance": benchmark_missing_model_events,
369
+ "benchmark_events_with_tool_version_provenance": benchmark_event_count
370
+ - benchmark_missing_tool_version_events,
371
+ "benchmark_events_missing_tool_version_provenance": benchmark_missing_tool_version_events,
372
+ "benchmark_model_missing_providers": sorted(benchmark_model_missing_providers),
331
373
  "tools": normalized_tools,
332
374
  }
333
375
 
@@ -235,7 +235,12 @@ def build_provider_model_env_report(
235
235
  matched.add(provider)
236
236
  config = _provider_config(lane)
237
237
  driver = _safe_text(_lane_value(lane, "driver")) or "unknown"
238
- model, model_source = _configured_model(config, driver)
238
+ tool, provenance_detail = build_provider_lane_tool_provenance(
239
+ lane_id,
240
+ lane,
241
+ source="code-mower providers provenance-env",
242
+ )
243
+ model_source = _safe_text(provenance_detail.get("model_source"))
239
244
  env_names = model_env_names(config)
240
245
  preferred_env = preferred_model_env_name(config)
241
246
  env_status = [
@@ -256,8 +261,16 @@ def build_provider_model_env_report(
256
261
  "lane_id": lane_id,
257
262
  "provider": provider,
258
263
  "driver": driver,
259
- "model_known": bool(model),
264
+ "model_known": bool(provenance_detail.get("model_known")),
260
265
  "model_source": model_source,
266
+ "tool_name": tool.get("tool_name", ""),
267
+ "tool_version": tool.get("tool_version", ""),
268
+ "version_known": bool(provenance_detail.get("version_known")),
269
+ "version_source": _safe_text(
270
+ provenance_detail.get("version_source")
271
+ ),
272
+ "command": _safe_text(provenance_detail.get("command")),
273
+ "command_found": bool(provenance_detail.get("command_found")),
261
274
  "env_names": list(env_names),
262
275
  "preferred_env": preferred_env,
263
276
  "env_status": env_status,
@@ -267,11 +280,17 @@ def build_provider_model_env_report(
267
280
  )
268
281
  unknown = sorted(requested - matched)
269
282
  missing = [row for row in rows if row["action"] == "set_model_env"]
283
+ missing_version_probe = [
284
+ row
285
+ for row in rows
286
+ if row["driver"] == "local_cli" and row["version_source"] == "missing"
287
+ ]
270
288
  return {
271
289
  "mode": "code-mower-provider-model-env-report",
272
290
  "providers": rows,
273
291
  "provider_count": len(rows),
274
292
  "missing_model_env_count": len(missing),
293
+ "missing_version_probe_count": len(missing_version_probe),
275
294
  "unknown_providers": unknown,
276
295
  "status": "fail" if unknown else "pass",
277
296
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: code-mower
3
- Version: 0.5.0b27
3
+ Version: 0.5.0b29
4
4
  Summary: Multi-reviewer AI code audit orchestration
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.11
@@ -101,11 +101,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
101
101
 
102
102
  ```bash
103
103
  python3.12 --version
104
- pipx install --python python3.12 code-mower==0.5.0b27
104
+ pipx install --python python3.12 code-mower==0.5.0b29
105
105
  code-mower --version
106
106
  ```
107
107
 
108
- `0.5.0b27` is a beta release. Until Code Mower publishes a stable `1.0`
108
+ `0.5.0b29` is a beta release. Until Code Mower publishes a stable `1.0`
109
109
  line, use the explicit beta version above or allow prereleases with:
110
110
 
111
111
  ```bash
@@ -148,7 +148,7 @@ First-time command map: [docs/launch-command-surface.md](docs/launch-command-sur
148
148
 
149
149
  The current PyPI beta has been rehearsed end-to-end from a clean install:
150
150
  [First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
151
- the latest 10/10 public-package readiness proof for `code-mower==0.5.0b27`.
151
+ the latest 10/10 public-package readiness proof for `code-mower==0.5.0b29`.
152
152
 
153
153
  ## Why Not Just Run Codex Or Claude Yourself?
154
154
 
@@ -253,9 +253,9 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
253
253
 
254
254
  ## Installation Status
255
255
 
256
- The current public beta is `v0.5.0-beta.27` from
256
+ The current public beta is `v0.5.0-beta.29` from
257
257
  [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
258
- as `code-mower==0.5.0b27` on [PyPI](https://pypi.org/project/code-mower/).
258
+ as `code-mower==0.5.0b29` on [PyPI](https://pypi.org/project/code-mower/).
259
259
  GitHub releases remain the auditable source for tags, build artifacts, and
260
260
  release notes.
261
261
 
@@ -279,6 +279,11 @@ def test_provenance_summary_treats_vendor_hidden_model_as_known_source() -> None
279
279
  assert summary["events_missing_model_provenance"] == 0
280
280
  assert summary["events_with_tool_version_provenance"] == 1
281
281
  assert summary["events_missing_tool_version_provenance"] == 0
282
+ assert summary["inventory_event_count"] == 1
283
+ assert summary["benchmark_event_count"] == 0
284
+ assert summary["benchmark_events_with_model_provenance"] == 0
285
+ assert summary["benchmark_events_missing_model_provenance"] == 0
286
+ assert summary["benchmark_model_missing_providers"] == []
282
287
  assert summary["tools"][0]["model_sources"] == ["vendor_hidden"]
283
288
  assert summary["tools"][0]["version_sources"] == ["not_probed"]
284
289
 
@@ -299,7 +304,7 @@ def test_provenance_summary_preserves_source_quality_fields() -> None:
299
304
  "tool": {
300
305
  "role": "reporter",
301
306
  "tool_name": "code-mower",
302
- "tool_version": "0.5.0b27",
307
+ "tool_version": "0.5.0b29",
303
308
  "provider": "code-mower",
304
309
  "model": "",
305
310
  "model_source": "not_applicable",
@@ -337,6 +342,13 @@ def test_provenance_summary_preserves_source_quality_fields() -> None:
337
342
  assert summary["events_missing_model_provenance"] == 1
338
343
  assert summary["events_with_tool_version_provenance"] == 2
339
344
  assert summary["events_missing_tool_version_provenance"] == 0
345
+ assert summary["inventory_event_count"] == 1
346
+ assert summary["benchmark_event_count"] == 1
347
+ assert summary["benchmark_events_with_model_provenance"] == 1
348
+ assert summary["benchmark_events_missing_model_provenance"] == 0
349
+ assert summary["benchmark_events_with_tool_version_provenance"] == 1
350
+ assert summary["benchmark_events_missing_tool_version_provenance"] == 0
351
+ assert summary["benchmark_model_missing_providers"] == []
340
352
  rows = {row["tool_name"]: row for row in summary["tools"]}
341
353
  assert rows["code-mower"]["model_sources"] == ["not_applicable"]
342
354
  assert rows["code-mower"]["version_sources"] == ["package_version"]
@@ -460,6 +472,49 @@ def test_cloud_doctor_warns_when_model_provenance_is_missing() -> None:
460
472
  assert "CODE_MOWER_CODEX_MODEL" in check["remediation"]
461
473
 
462
474
 
475
+ def test_cloud_doctor_does_not_warn_for_inventory_only_model_gaps() -> None:
476
+ with tempfile.TemporaryDirectory() as tmp:
477
+ root = Path(tmp)
478
+ build_cloud_bundle(
479
+ reports=[],
480
+ events=[
481
+ {
482
+ "event_type": "provider_catalog_snapshot",
483
+ "repo_slug": "owner/repo",
484
+ "provider": "gemini",
485
+ "lens": "base",
486
+ "status": "observed",
487
+ "dimensions": {"catalog_snapshot": True},
488
+ "tool": {
489
+ "role": "reviewer",
490
+ "tool_name": "gemini",
491
+ "provider": "gemini",
492
+ "tool_version": "0.45.2",
493
+ "model_source": "missing",
494
+ },
495
+ }
496
+ ],
497
+ output_dir=root / "bundle",
498
+ repo_slug="owner/repo",
499
+ )
500
+
501
+ report = run_cloud_doctor(
502
+ bundle_dir=root / "bundle",
503
+ endpoint="https://codemower.com/api/ingest",
504
+ token_env="CODE_MOWER_TEST_CLOUD_TOKEN",
505
+ require_token=False,
506
+ )
507
+
508
+ check = next(
509
+ item for item in report["checks"] if item["name"] == "model-provenance"
510
+ )
511
+ assert report["status"] == "pass"
512
+ assert check["status"] == "pass"
513
+ assert "benchmark evidence events" in check["message"]
514
+ assert check["detail"]["raw_missing_model_events"] == 1
515
+ assert check["detail"]["benchmark_missing_model_events"] == 0
516
+
517
+
463
518
  def test_cloud_doctor_fans_out_multiple_model_provenance_commands() -> None:
464
519
  with tempfile.TemporaryDirectory() as tmp:
465
520
  root = Path(tmp)
@@ -178,6 +178,65 @@ def test_provider_model_env_report_never_exposes_env_value(monkeypatch) -> None:
178
178
  assert row["action"] == "none"
179
179
 
180
180
 
181
+ def test_provider_model_env_report_includes_cli_version_status(
182
+ monkeypatch,
183
+ tmp_path: Path,
184
+ ) -> None:
185
+ executable = _write_executable(
186
+ tmp_path / "custom-reviewer",
187
+ "#!/bin/sh\nprintf 'custom-reviewer 2.0.0\\n'\n",
188
+ )
189
+ monkeypatch.setenv("PATH", os.fspath(executable.parent))
190
+ monkeypatch.setenv("CUSTOM_REVIEWER_MODEL", "do-not-render-this-model")
191
+ lanes = {
192
+ "custom_reviewer": {
193
+ "driver": "local_cli",
194
+ "provider": "custom",
195
+ "provider_config": {
196
+ "command": "custom-reviewer",
197
+ "model_env": "CUSTOM_REVIEWER_MODEL",
198
+ },
199
+ }
200
+ }
201
+
202
+ report = build_provider_model_env_report(lanes)
203
+
204
+ assert report["missing_model_env_count"] == 0
205
+ assert report["missing_version_probe_count"] == 0
206
+ row = report["providers"][0]
207
+ assert row["tool_name"] == "custom-reviewer"
208
+ assert row["tool_version"] == "custom-reviewer 2.0.0"
209
+ assert row["version_known"] is True
210
+ assert row["version_source"] == "cli_version_probe"
211
+ assert row["command"] == "custom-reviewer"
212
+ assert row["command_found"] is True
213
+ assert "do-not-render-this-model" not in str(report)
214
+
215
+
216
+ def test_provider_model_env_report_counts_missing_cli_version_probe(monkeypatch) -> None:
217
+ monkeypatch.setenv("PATH", "")
218
+ lanes = {
219
+ "missing_reviewer": {
220
+ "driver": "local_cli",
221
+ "provider": "missing",
222
+ "provider_config": {
223
+ "command": "missing-reviewer",
224
+ "model_env": "MISSING_REVIEWER_MODEL",
225
+ },
226
+ }
227
+ }
228
+
229
+ report = build_provider_model_env_report(lanes)
230
+
231
+ assert report["missing_model_env_count"] == 1
232
+ assert report["missing_version_probe_count"] == 1
233
+ row = report["providers"][0]
234
+ assert row["version_known"] is False
235
+ assert row["version_source"] == "missing"
236
+ assert row["command"] == "missing-reviewer"
237
+ assert row["command_found"] is False
238
+
239
+
181
240
  def test_providers_provenance_env_cli_shell_output(monkeypatch, capsys) -> None:
182
241
  monkeypatch.delenv("CODE_MOWER_ANTIGRAVITY_MODEL", raising=False)
183
242
  monkeypatch.delenv("ANTIGRAVITY_MODEL", raising=False)
@@ -377,11 +436,11 @@ def test_provider_lane_tool_provenance_reads_model_from_selected_profile(
377
436
  def test_code_mower_reporter_provenance_marks_model_not_applicable() -> None:
378
437
  tool = build_code_mower_tool_provenance(
379
438
  source="unit-test",
380
- version="0.5.0b27",
439
+ version="0.5.0b29",
381
440
  )
382
441
 
383
442
  assert tool["tool_name"] == "code-mower"
384
- assert tool["tool_version"] == "0.5.0b27"
443
+ assert tool["tool_version"] == "0.5.0b29"
385
444
  assert tool["provider"] == "code-mower"
386
445
  assert tool["model"] == ""
387
446
  assert tool["model_source"] == "not_applicable"