code-mower 0.5.0b9__tar.gz → 0.5.0b10__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 (265) hide show
  1. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/PKG-INFO +8 -8
  2. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/README.md +7 -7
  3. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/pyproject.toml +1 -1
  4. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/__init__.py +1 -1
  5. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/clear_stale.py +18 -0
  6. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud.py +5 -0
  7. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/operations.py +11 -0
  8. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/init.py +122 -1
  9. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/package_content.py +17 -0
  10. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/package_manifest.py +5 -0
  11. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/code-mower.example.yml +6 -0
  12. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/providers.yml +6 -2
  13. code_mower-0.5.0b10/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +41 -0
  14. code_mower-0.5.0b10/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +47 -0
  15. code_mower-0.5.0b10/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +34 -0
  16. code_mower-0.5.0b10/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +58 -0
  17. code_mower-0.5.0b10/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +57 -0
  18. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower.egg-info/PKG-INFO +8 -8
  19. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower.egg-info/SOURCES.txt +5 -0
  20. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/claude_audit.yml +3 -1
  21. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/codex.yml +3 -1
  22. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers.yml +6 -2
  23. code_mower-0.5.0b10/templates/workflows/audit-label-cleanup.yml.j2 +41 -0
  24. code_mower-0.5.0b10/templates/workflows/hosted-bridge.yml.j2 +47 -0
  25. code_mower-0.5.0b10/templates/workflows/local-cli-audit.yml.j2 +34 -0
  26. code_mower-0.5.0b10/templates/workflows/saas-reviewer-labeler.yml.j2 +58 -0
  27. code_mower-0.5.0b10/templates/workflows/trailer-comment-labeler.yml.j2 +57 -0
  28. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_clear_stale.py +5 -0
  29. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_cloud_client.py +8 -0
  30. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_release_hygiene.py +234 -34
  31. code_mower-0.5.0b9/templates/workflows/audit-label-cleanup.yml.j2 +0 -10
  32. code_mower-0.5.0b9/templates/workflows/hosted-bridge.yml.j2 +0 -10
  33. code_mower-0.5.0b9/templates/workflows/local-cli-audit.yml.j2 +0 -10
  34. code_mower-0.5.0b9/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -10
  35. code_mower-0.5.0b9/templates/workflows/trailer-comment-labeler.yml.j2 +0 -10
  36. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/CODE_OF_CONDUCT.md +0 -0
  37. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/LICENSE +0 -0
  38. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/MANIFEST.in +0 -0
  39. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/NOTICE +0 -0
  40. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/SUPPORT.md +0 -0
  41. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/requirements/requirements.txt +0 -0
  42. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/setup.cfg +0 -0
  43. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/adapters/__init__.py +0 -0
  44. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/adapters/_base.py +0 -0
  45. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/adapters/cursor_bugbot.py +0 -0
  46. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/adapters/gitar.py +0 -0
  47. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/adapters/greptile.py +0 -0
  48. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/adapters/qodo.py +0 -0
  49. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
  50. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/audit_handoff_log.py +0 -0
  51. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/audit_labeler_lib.py +0 -0
  52. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/audit_progress.py +0 -0
  53. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/blind_review_artifacts.py +0 -0
  54. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/blind_review_coordinator.py +0 -0
  55. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/bootstrap.py +0 -0
  56. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/builder_experiment.py +0 -0
  57. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/__init__.py +0 -0
  58. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/arms.py +0 -0
  59. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/auto_discovery.py +0 -0
  60. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/commands.py +0 -0
  61. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/context_inputs.py +0 -0
  62. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/corpus.py +0 -0
  63. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/evidence.py +0 -0
  64. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/evidence_report.py +0 -0
  65. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/identity.py +0 -0
  66. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/metrics.py +0 -0
  67. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/overlap.py +0 -0
  68. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/planning.py +0 -0
  69. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/policy.py +0 -0
  70. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/results.py +0 -0
  71. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/run_results.py +0 -0
  72. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/run_status.py +0 -0
  73. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/runner.py +0 -0
  74. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/truth.py +0 -0
  75. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/calibration/value_report.py +0 -0
  76. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/checks.py +0 -0
  77. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/claude_audit_pr.py +0 -0
  78. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/claude_cli_bounce.py +0 -0
  79. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/claude_cli_environment.py +0 -0
  80. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cli.py +0 -0
  81. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/__init__.py +0 -0
  82. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/bundle.py +0 -0
  83. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/doctor.py +0 -0
  84. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/dogfood.py +0 -0
  85. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/endpoints.py +0 -0
  86. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/errors.py +0 -0
  87. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/events.py +0 -0
  88. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/export.py +0 -0
  89. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/git_metadata.py +0 -0
  90. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/manifest.py +0 -0
  91. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/reports.py +0 -0
  92. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/setup.py +0 -0
  93. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/cloud_client/upload.py +0 -0
  94. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/code_mower_calibration.py +0 -0
  95. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/code_mower_context_packs.py +0 -0
  96. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/code_mower_merge.py +0 -0
  97. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/code_mower_telemetry.py +0 -0
  98. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
  99. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/codex_audit_env_preflight.py +0 -0
  100. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/codex_audit_pr.py +0 -0
  101. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/codex_audit_schema_smoke.py +0 -0
  102. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/codex_audit_verdict.schema.json +0 -0
  103. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/config.py +0 -0
  104. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor.py +0 -0
  105. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/__init__.py +0 -0
  106. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/cloud.py +0 -0
  107. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/common.py +0 -0
  108. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github.py +0 -0
  109. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_actions.py +0 -0
  110. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
  111. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
  112. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
  113. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
  114. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
  115. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
  116. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
  117. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
  118. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_api.py +0 -0
  119. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_branch.py +0 -0
  120. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_config.py +0 -0
  121. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_provider.py +0 -0
  122. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/github_repo.py +0 -0
  123. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/groups.py +0 -0
  124. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/models.py +0 -0
  125. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/output.py +0 -0
  126. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/presets.py +0 -0
  127. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/privacy.py +0 -0
  128. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
  129. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
  130. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
  131. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_env.py +0 -0
  132. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
  133. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
  134. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
  135. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
  136. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
  137. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_probe.py +0 -0
  138. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
  139. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
  140. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
  141. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
  142. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/providers.py +0 -0
  143. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/registry.py +0 -0
  144. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/runner.py +0 -0
  145. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/runtime.py +0 -0
  146. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
  147. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/gemini_cli_audit_pr.py +0 -0
  148. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/hermes_cli_audit_pr.py +0 -0
  149. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/lane_configs/__init__.py +0 -0
  150. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/lane_configs/aider.py +0 -0
  151. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
  152. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/lane_configs/claude.py +0 -0
  153. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/lane_configs/codex.py +0 -0
  154. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/lane_configs/devin.py +0 -0
  155. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/lane_configs/gemini_cli.py +0 -0
  156. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/lane_configs/hermes_cli.py +0 -0
  157. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/lane_configs/local_llm.py +0 -0
  158. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/local_llm_audit_pr.py +0 -0
  159. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/local_llm_bakeoff.py +0 -0
  160. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/local_llm_calibration.py +0 -0
  161. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/local_llm_profiles.py +0 -0
  162. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/migration.py +0 -0
  163. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/migration_install.py +0 -0
  164. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/migration_mirror.py +0 -0
  165. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/migration_readiness.py +0 -0
  166. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/migration_rehearsal.py +0 -0
  167. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/next_steps.py +0 -0
  168. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/package.py +0 -0
  169. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/package_paths.py +0 -0
  170. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/package_rendering.py +0 -0
  171. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/package_static.py +0 -0
  172. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/prompts.py +0 -0
  173. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_registry.py +0 -0
  174. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/__init__.py +0 -0
  175. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/comments.py +0 -0
  176. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/git.py +0 -0
  177. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/github_auth.py +0 -0
  178. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/github_pr.py +0 -0
  179. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/process.py +0 -0
  180. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/repo_paths.py +0 -0
  181. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/text_schema.py +0 -0
  182. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
  183. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/provider_runners/workspace.py +0 -0
  184. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/release_readiness.py +0 -0
  185. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/reviewer_metrics.py +0 -0
  186. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/saas_reviewer_labeler.py +0 -0
  187. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/secrets.py +0 -0
  188. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/builder-experiment.example.json +0 -0
  189. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/calibration-corpus.example.json +0 -0
  190. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/calibration-corpus.json +0 -0
  191. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/context-packs.example.json +0 -0
  192. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
  193. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
  194. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
  195. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
  196. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
  197. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/lane_prompts/operability.md +0 -0
  198. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
  199. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
  200. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/product-support/code_mower +0 -0
  201. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
  202. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
  203. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
  204. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
  205. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
  206. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/reviewer-spend.example.json +0 -0
  207. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
  208. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  209. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
  210. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/trailer_comment_labeler.py +0 -0
  211. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower/versioning.py +0 -0
  212. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower.egg-info/dependency_links.txt +0 -0
  213. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower.egg-info/entry_points.txt +0 -0
  214. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower.egg-info/requires.txt +0 -0
  215. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/src/code_mower.egg-info/top_level.txt +0 -0
  216. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/builder-experiment.example.json +0 -0
  217. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/calibration-corpus.example.json +0 -0
  218. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/calibration-corpus.json +0 -0
  219. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/code-mower.yml.j2 +0 -0
  220. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/context-packs.example.json +0 -0
  221. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/cursor/BUGBOT.md +0 -0
  222. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/acp_bridge.yml +0 -0
  223. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/aider.yml +0 -0
  224. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/antigravity_cli.yml +0 -0
  225. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/claude_review.yml +0 -0
  226. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/coderabbit_cli.yml +0 -0
  227. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/cursor_bugbot.yml +0 -0
  228. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/devin.yml +0 -0
  229. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/gemini_cli.yml +0 -0
  230. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/gitar.yml +0 -0
  231. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/greptile.yml +0 -0
  232. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/hermes_cli.yml +0 -0
  233. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/local_llm.yml +0 -0
  234. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/providers/qodo.yml +0 -0
  235. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/reviewer-spend.example.json +0 -0
  236. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/reviewer-value-report.example.md +0 -0
  237. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
  238. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
  239. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/templates/workflows/review-clear-stale.yml.j2 +0 -0
  240. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_calibration_truth.py +0 -0
  241. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_checks.py +0 -0
  242. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_claude_cli_bounce.py +0 -0
  243. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_cloud_git_metadata.py +0 -0
  244. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_cloud_manifest.py +0 -0
  245. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_cloud_reports.py +0 -0
  246. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_coderabbit_cli_audit_pr.py +0 -0
  247. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_actions_cost_summary.py +0 -0
  248. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_actions_failure_selection.py +0 -0
  249. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_boundaries.py +0 -0
  250. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_github_checks.py +0 -0
  251. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_output.py +0 -0
  252. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_privacy.py +0 -0
  253. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_provider_env_required.py +0 -0
  254. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_provider_env_tokens.py +0 -0
  255. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_provider_probe.py +0 -0
  256. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_doctor_registry.py +0 -0
  257. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_local_llm_github_helpers.py +0 -0
  258. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_provider_runners_comments.py +0 -0
  259. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_provider_runners_git.py +0 -0
  260. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_provider_runners_github_pr.py +0 -0
  261. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_provider_runners_process.py +0 -0
  262. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_provider_runners_repo_paths.py +0 -0
  263. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_provider_runners_text_schema.py +0 -0
  264. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/tests/test_provider_runners_workspace.py +0 -0
  265. {code_mower-0.5.0b9 → code_mower-0.5.0b10}/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.0b9
3
+ Version: 0.5.0b10
4
4
  Summary: Multi-reviewer AI code audit orchestration
5
5
  License-Expression: Apache-2.0
6
6
  Requires-Python: >=3.11
@@ -98,11 +98,11 @@ Code Mower currently targets Python 3.11+; Python 3.12 is recommended.
98
98
 
99
99
  ```bash
100
100
  python3.12 --version
101
- pipx install --python python3.12 code-mower==0.5.0b9
101
+ pipx install --python python3.12 code-mower==0.5.0b10
102
102
  code-mower --version
103
103
  ```
104
104
 
105
- `0.5.0b9` is a beta release. Until Code Mower publishes a stable `1.0`
105
+ `0.5.0b10` is a beta release. Until Code Mower publishes a stable `1.0`
106
106
  line, use the explicit beta version above or allow prereleases with:
107
107
 
108
108
  ```bash
@@ -246,11 +246,11 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
246
246
 
247
247
  ## Installation Status
248
248
 
249
- The current public beta is `v0.5.0-beta.9` from
250
- [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and it
251
- is published as `code-mower==0.5.0b9` on
252
- [PyPI](https://pypi.org/project/code-mower/). GitHub releases remain the
253
- auditable source for tags, build artifacts, and release notes.
249
+ The current release target is `v0.5.0-beta.10` from
250
+ [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
251
+ as `code-mower==0.5.0b10` on [PyPI](https://pypi.org/project/code-mower/)
252
+ after release gates pass. GitHub releases remain the auditable source for tags,
253
+ build artifacts, and release notes.
254
254
 
255
255
  For source checkout development and release rehearsal, use:
256
256
 
@@ -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.0b9
89
+ pipx install --python python3.12 code-mower==0.5.0b10
90
90
  code-mower --version
91
91
  ```
92
92
 
93
- `0.5.0b9` is a beta release. Until Code Mower publishes a stable `1.0`
93
+ `0.5.0b10` 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
@@ -234,11 +234,11 @@ best?" to "which AI builder plus reviewer loop ships best on this product?" See
234
234
 
235
235
  ## Installation Status
236
236
 
237
- The current public beta is `v0.5.0-beta.9` from
238
- [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and it
239
- is published as `code-mower==0.5.0b9` on
240
- [PyPI](https://pypi.org/project/code-mower/). GitHub releases remain the
241
- auditable source for tags, build artifacts, and release notes.
237
+ The current release target is `v0.5.0-beta.10` from
238
+ [codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), published
239
+ as `code-mower==0.5.0b10` on [PyPI](https://pypi.org/project/code-mower/)
240
+ after release gates pass. GitHub releases remain the auditable source for tags,
241
+ build artifacts, and release notes.
242
242
 
243
243
  For source checkout development and release rehearsal, use:
244
244
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "code-mower"
7
- version = "0.5.0b9"
7
+ version = "0.5.0b10"
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.0b9"
3
+ __version__ = "0.5.0b10"
@@ -80,6 +80,9 @@ class StaleClearResult:
80
80
  reason: str
81
81
  requeue_added: bool = False
82
82
  dispatch_requested: bool = False
83
+ trusted_terminal_status: Optional[str] = None
84
+ trusted_terminal_sha: Optional[str] = None
85
+ trusted_terminal_author: Optional[str] = None
83
86
 
84
87
 
85
88
  def _comment_created_at(comment: dict[str, Any]) -> str:
@@ -148,6 +151,9 @@ def resolve_stale_clear_decision(
148
151
  f"terminal label is current: {current_comment.status} by "
149
152
  f"{current_comment.author} for {current_comment.reviewed_sha}"
150
153
  ),
154
+ trusted_terminal_status=current_comment.status,
155
+ trusted_terminal_sha=current_comment.reviewed_sha,
156
+ trusted_terminal_author=current_comment.author,
151
157
  )
152
158
  return StaleClearResult(
153
159
  LabelDecision(
@@ -164,6 +170,9 @@ def resolve_stale_clear_decision(
164
170
  "terminal audit label mismatch for current trusted "
165
171
  f"{current_comment.status} result"
166
172
  ),
173
+ trusted_terminal_status=current_comment.status,
174
+ trusted_terminal_sha=current_comment.reviewed_sha,
175
+ trusted_terminal_author=current_comment.author,
167
176
  )
168
177
 
169
178
  decision = LabelDecision(
@@ -179,6 +188,9 @@ def resolve_stale_clear_decision(
179
188
  decision,
180
189
  "terminal audit label is stale or lacks a current trusted Head SHA",
181
190
  requeue_added=config.needs_label not in label_set,
191
+ trusted_terminal_status=current_comment.status if current_comment else None,
192
+ trusted_terminal_sha=current_comment.reviewed_sha if current_comment else None,
193
+ trusted_terminal_author=current_comment.author if current_comment else None,
182
194
  )
183
195
 
184
196
 
@@ -356,6 +368,12 @@ def main(argv: Optional[Sequence[str]] = None) -> int:
356
368
  "decision": result.decision.__dict__ if result.decision else None,
357
369
  "requeue_added": result.requeue_added,
358
370
  "dispatch_requested": dispatch_requested,
371
+ "trusted_terminal": {
372
+ "status": result.trusted_terminal_status,
373
+ "reviewed_sha": result.trusted_terminal_sha,
374
+ "author": result.trusted_terminal_author,
375
+ "head_bound": bool(result.trusted_terminal_sha),
376
+ },
359
377
  }
360
378
  if args.json or args.dry_run:
361
379
  print(json.dumps(output, indent=2, sort_keys=True))
@@ -602,6 +602,11 @@ def main(argv: list[str] | None = None) -> int:
602
602
  print(f"Repository: {result['repo_slug']}")
603
603
  print(f"Runs: {result['run_count']}")
604
604
  print("Provenance: imported history (not calibration evidence)")
605
+ guidance = result.get("catch_up", {}).get("trust_guidance", {})
606
+ if guidance:
607
+ print(f"Use for: {guidance.get('use_for', '')}")
608
+ print(f"Do not use for: {guidance.get('do_not_use_for', '')}")
609
+ print(f"Next: {guidance.get('next_step', '')}")
605
610
  print(f"Bundle: {result['export']['output_dir']}")
606
611
  print(f"Events: {result['export']['event_count']}")
607
612
  if result["status"] == "uploaded":
@@ -23,6 +23,16 @@ from .setup import DEFAULT_INSTALL_ID_ENV, DEFAULT_TEAM_ID_ENV
23
23
  from .upload import build_upload_payload, post_upload_payload
24
24
 
25
25
 
26
+ CATCH_UP_TRUST_GUIDANCE = {
27
+ "use_for": "historical activity context and dashboard coverage backfill",
28
+ "do_not_use_for": "reviewer or lens accuracy, lane promotion, or merge-gate policy",
29
+ "next_step": (
30
+ "run current dogfood uploads plus reviewer-runs or calibration evidence "
31
+ "before making provider/lens decisions"
32
+ ),
33
+ }
34
+
35
+
26
36
  def build_catch_up_summary(
27
37
  *,
28
38
  repo_slug: str,
@@ -63,6 +73,7 @@ def build_catch_up_summary(
63
73
  "source_category": "history",
64
74
  "history_only": True,
65
75
  "calibration_evidence": False,
76
+ "trust_guidance": CATCH_UP_TRUST_GUIDANCE,
66
77
  "git_ref_included": include_git_ref,
67
78
  "workflow_counts": dict(sorted(workflow_counts.items())),
68
79
  "status_counts": dict(sorted(status_counts.items())),
@@ -169,6 +169,89 @@ def _lane_module_name(lane_id: str) -> str:
169
169
  return lane_id.replace("-", "_")
170
170
 
171
171
 
172
+ def _display_name(raw_name: str) -> str:
173
+ return raw_name.replace("_", " ").replace("-", " ").title()
174
+
175
+
176
+ def _workflow_name_for_target(target: str) -> str:
177
+ stem = Path(target).stem.replace("-", " ")
178
+ return stem[:1].upper() + stem[1:]
179
+
180
+
181
+ def _audit_token_env(lane: Mapping[str, Any]) -> str:
182
+ token_env = lane.get("token_env", [])
183
+ if not isinstance(token_env, list):
184
+ token_env = []
185
+ names = [str(name) for name in token_env]
186
+ for name in names:
187
+ if name != "GITHUB_TOKEN" and name.endswith("_LABEL_TOKEN"):
188
+ return name
189
+ for name in names:
190
+ if name != "GITHUB_TOKEN":
191
+ return name
192
+ return "CODE_MOWER_AUDIT_LABEL_TOKEN"
193
+
194
+
195
+ def _authors_env_for_trailer_lane(trailer_lane: str) -> str:
196
+ normalized = trailer_lane.replace("-", "_").upper()
197
+ explicit = {
198
+ "CLAUDE": "CLAUDE_AUDIT_BOT_AUTHORS",
199
+ "CODEX": "CODEX_BOT_AUTHORS",
200
+ "DEVIN": "DEVIN_BOT_AUTHORS",
201
+ }
202
+ return explicit.get(normalized, f"{normalized}_BOT_AUTHORS")
203
+
204
+
205
+ def _trailer_prefix_for_lane(trailer_lane: str) -> str:
206
+ return f"{trailer_lane.replace('-', '_').upper()}_AUDIT_STATE"
207
+
208
+
209
+ def _workflow_entry_for_target(
210
+ lane_id: str,
211
+ lane: Mapping[str, Any],
212
+ target: str,
213
+ ) -> dict[str, str]:
214
+ driver = str(lane.get("driver"))
215
+ labels = _labels_for(lane)
216
+ trailer_lane = _trailer_lane_name(lane_id, lane)
217
+ common = {
218
+ "path": target,
219
+ "lane_id": lane_id,
220
+ "workflow_name": _workflow_name_for_target(target),
221
+ "display_name": _display_name(trailer_lane),
222
+ "needs_label": str(labels["needs"]),
223
+ "done_label": str(labels["done"]),
224
+ "blocked_label": str(labels["blocked"]),
225
+ "label_token_env": _audit_token_env(lane),
226
+ }
227
+ if target.endswith("-bridge.yml"):
228
+ return {
229
+ **common,
230
+ "source": "hosted-bridge-workflow-template",
231
+ "copy_from": "templates/workflows/hosted-bridge.yml.j2",
232
+ "package_copy_from": "templates/workflows/hosted-bridge.yml.j2",
233
+ }
234
+ if driver == "saas_event":
235
+ adapter = str(lane.get("adapter") or lane.get("provider") or lane_id)
236
+ return {
237
+ **common,
238
+ "source": "saas-reviewer-labeler-workflow-template",
239
+ "copy_from": "templates/workflows/saas-reviewer-labeler.yml.j2",
240
+ "package_copy_from": "templates/workflows/saas-reviewer-labeler.yml.j2",
241
+ "adapter": adapter,
242
+ "authors_env": f"{adapter.replace('-', '_').upper()}_BOT_AUTHORS",
243
+ }
244
+ return {
245
+ **common,
246
+ "source": "trailer-comment-labeler-workflow-template",
247
+ "copy_from": "templates/workflows/trailer-comment-labeler.yml.j2",
248
+ "package_copy_from": "templates/workflows/trailer-comment-labeler.yml.j2",
249
+ "trailer_lane": trailer_lane,
250
+ "trailer_prefix": _trailer_prefix_for_lane(trailer_lane),
251
+ "authors_env": _authors_env_for_trailer_lane(trailer_lane),
252
+ }
253
+
254
+
172
255
  def _running_as_package() -> bool:
173
256
  return bool(__package__ and __package__ != "tools")
174
257
 
@@ -475,6 +558,37 @@ def _render_stale_workflow_template(text: str, *, lane: str) -> str:
475
558
  )
476
559
 
477
560
 
561
+ def _render_workflow_template(text: str, entry: Mapping[str, Any]) -> str:
562
+ """Render lightweight workflow placeholders without requiring Jinja."""
563
+
564
+ rendered = text.replace("{% raw %}", "").replace("{% endraw %}", "")
565
+ replacements = {
566
+ "__ADAPTER__": str(entry.get("adapter") or ""),
567
+ "__AUTHORS_ENV__": str(entry.get("authors_env") or ""),
568
+ "__BLOCKED_LABEL__": str(entry.get("blocked_label") or ""),
569
+ "__DISPLAY_NAME__": str(entry.get("display_name") or ""),
570
+ "__DONE_LABEL__": str(entry.get("done_label") or ""),
571
+ "__LABEL_TOKEN_ENV__": str(entry.get("label_token_env") or ""),
572
+ "__LANE_ID__": str(entry.get("lane_id") or ""),
573
+ "__NEEDS_LABEL__": str(entry.get("needs_label") or ""),
574
+ "__TRAILER_LANE__": str(entry.get("trailer_lane") or ""),
575
+ "__TRAILER_PREFIX__": str(entry.get("trailer_prefix") or ""),
576
+ "__WORKFLOW_NAME__": str(entry.get("workflow_name") or "Code Mower labeler"),
577
+ }
578
+ for placeholder, value in replacements.items():
579
+ rendered = rendered.replace(placeholder, value)
580
+ return rendered
581
+
582
+
583
+ def _workflow_template_needs_render(source: str) -> bool:
584
+ return source in {
585
+ "shared-cleanup-template",
586
+ "hosted-bridge-workflow-template",
587
+ "saas-reviewer-labeler-workflow-template",
588
+ "trailer-comment-labeler-workflow-template",
589
+ }
590
+
591
+
478
592
  def _copy_source_candidates(source_root: Path, entry: Mapping[str, Any], path: str) -> tuple[Path, ...]:
479
593
  candidates: list[Path] = []
480
594
  package_copy_from = entry.get("package_copy_from")
@@ -586,6 +700,11 @@ def apply_init_plan(
586
700
  ),
587
701
  encoding="utf-8",
588
702
  )
703
+ elif _workflow_template_needs_render(str(entry.get("source"))):
704
+ destination.write_text(
705
+ _render_workflow_template(source.read_text(encoding="utf-8"), entry),
706
+ encoding="utf-8",
707
+ )
589
708
  else:
590
709
  shutil.copyfile(source, destination)
591
710
  else:
@@ -674,7 +793,7 @@ def render_init_plan(
674
793
  )
675
794
  if target not in generated_paths:
676
795
  generated_paths.add(target)
677
- generated_files.append({"path": target, "source": "workflow-template"})
796
+ generated_files.append(_workflow_entry_for_target(lane_id, lane, target))
678
797
  if lane.get("driver") in {"local_cli", "hosted_bridge", "api_model"}:
679
798
  trailer_lane = _trailer_lane_name(lane_id, lane)
680
799
  trailer_module = _lane_module_name(trailer_lane)
@@ -700,6 +819,8 @@ def render_init_plan(
700
819
  {
701
820
  "path": cleanup_path,
702
821
  "source": "shared-cleanup-template",
822
+ "copy_from": "templates/workflows/audit-label-cleanup.yml.j2",
823
+ "package_copy_from": "templates/workflows/audit-label-cleanup.yml.j2",
703
824
  }
704
825
  )
705
826
  for lane_id, lane in selected_lanes.items():
@@ -53,7 +53,24 @@ def _pyproject_text(package_name: str, *, version: str) -> str:
53
53
  )
54
54
 
55
55
 
56
+ def _workflow_template_file_text(target: str) -> str | None:
57
+ module_dir = Path(__file__).resolve().parent
58
+ filename = Path(target).name
59
+ candidates = (
60
+ module_dir / "templates" / "workflows" / filename,
61
+ module_dir.parent / "templates" / "workflows" / filename,
62
+ module_dir.parents[1] / "templates" / "workflows" / filename,
63
+ )
64
+ for candidate in candidates:
65
+ if candidate.is_file():
66
+ return candidate.read_text(encoding="utf-8")
67
+ return None
68
+
69
+
56
70
  def _workflow_template_text(target: str) -> str:
71
+ file_text = _workflow_template_file_text(target)
72
+ if file_text is not None:
73
+ return file_text
57
74
  if target.endswith("blind-review-artifacts-dry-run.yml.j2"):
58
75
  return "\n".join(
59
76
  [
@@ -443,6 +443,11 @@ TEMPLATE_FILES = (
443
443
  ("workflow", "templates/workflows/hosted-bridge.yml.j2"),
444
444
  ("workflow", "templates/workflows/audit-label-cleanup.yml.j2"),
445
445
  ("workflow", "templates/workflows/review-clear-stale.yml.j2"),
446
+ ("workflow", "src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2"),
447
+ ("workflow", "src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2"),
448
+ ("workflow", "src/code_mower/templates/workflows/local-cli-audit.yml.j2"),
449
+ ("workflow", "src/code_mower/templates/workflows/hosted-bridge.yml.j2"),
450
+ ("workflow", "src/code_mower/templates/workflows/audit-label-cleanup.yml.j2"),
446
451
  ("workflow", "src/code_mower/templates/workflows/review-clear-stale.yml.j2"),
447
452
  ("workflow", "templates/workflows/private-standalone-shadow.yml.j2"),
448
453
  ("workflow", "src/code_mower/templates/workflows/private-standalone-shadow.yml.j2"),
@@ -26,6 +26,9 @@ lanes:
26
26
  command: codex
27
27
  doctor_probe_args:
28
28
  - --version
29
+ review_hygiene:
30
+ workflow: .github/workflows/codex-clear-stale.yml
31
+ token_env: GITHUB_TOKEN
29
32
 
30
33
  claude_review:
31
34
  type: review
@@ -81,6 +84,9 @@ lanes:
81
84
  - api_error_status
82
85
  doctor_probe_auth_status_fields:
83
86
  - api_error_status
87
+ review_hygiene:
88
+ workflow: .github/workflows/claude-clear-stale.yml
89
+ token_env: GITHUB_TOKEN
84
90
 
85
91
  greptile:
86
92
  type: audit
@@ -120,7 +120,9 @@ provider_templates:
120
120
  - "api_error_status"
121
121
  doctor_probe_auth_status_fields:
122
122
  - "api_error_status"
123
- review_hygiene: {}
123
+ review_hygiene:
124
+ workflow: ".github/workflows/claude-clear-stale.yml"
125
+ token_env: "GITHUB_TOKEN"
124
126
  claude_review:
125
127
  provider: "claude"
126
128
  driver: "manual"
@@ -179,7 +181,9 @@ provider_templates:
179
181
  command: "codex"
180
182
  doctor_probe_args:
181
183
  - "--version"
182
- review_hygiene: {}
184
+ review_hygiene:
185
+ workflow: ".github/workflows/codex-clear-stale.yml"
186
+ token_env: "GITHUB_TOKEN"
183
187
  cursor_bugbot:
184
188
  provider: "cursor_bugbot"
185
189
  driver: "saas_event"
@@ -0,0 +1,41 @@
1
+ # Code Mower workflow template: manually remove stale or retired audit labels.
2
+ name: Code Mower Audit Label Cleanup
3
+
4
+ on:
5
+ workflow_dispatch:
6
+ inputs:
7
+ pr_number:
8
+ description: "Pull request number"
9
+ required: true
10
+ labels:
11
+ description: "Comma-separated labels to remove"
12
+ required: true
13
+
14
+ permissions:
15
+ contents: read
16
+ issues: write
17
+
18
+ env:
19
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
20
+
21
+ jobs:
22
+ cleanup:
23
+ runs-on: ubuntu-latest
24
+ timeout-minutes: 5
25
+ steps:
26
+ - name: Remove requested audit labels
27
+ env:
28
+ GH_TOKEN: {% raw %}${{ secrets.AUDIT_LABEL_CLEANUP_TOKEN || github.token }}{% endraw %}
29
+ PR_NUMBER: {% raw %}${{ github.event.inputs.pr_number }}{% endraw %}
30
+ LABELS: {% raw %}${{ github.event.inputs.labels }}{% endraw %}
31
+ run: |
32
+ set -euo pipefail
33
+
34
+ IFS=',' read -r -a labels <<< "${LABELS}"
35
+ for raw_label in "${labels[@]}"; do
36
+ label="$(printf '%s' "${raw_label}" | xargs)"
37
+ [ -n "${label}" ] || continue
38
+ gh issue edit "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --remove-label "${label}" || {
39
+ echo "::notice::Could not remove label ${label}; it may already be absent."
40
+ }
41
+ done
@@ -0,0 +1,47 @@
1
+ # Code Mower workflow template: manually requeue a hosted reviewer lane.
2
+ #
3
+ # Hosted provider apps own the actual review session. This bridge gives
4
+ # maintainers a cheap, auditable way to re-add the lane's needs label and, when
5
+ # an expected head SHA is supplied, refuse to queue against an unexpected head.
6
+ name: __WORKFLOW_NAME__
7
+
8
+ on:
9
+ workflow_dispatch:
10
+ inputs:
11
+ pr_number:
12
+ description: "Pull request number to requeue"
13
+ required: true
14
+ head_sha:
15
+ description: "Optional expected current PR head SHA"
16
+ required: false
17
+
18
+ permissions:
19
+ contents: read
20
+ issues: write
21
+ pull-requests: read
22
+
23
+ env:
24
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
25
+
26
+ jobs:
27
+ requeue:
28
+ runs-on: ubuntu-latest
29
+ timeout-minutes: 5
30
+ steps:
31
+ - name: Requeue __DISPLAY_NAME__ hosted review
32
+ env:
33
+ GH_TOKEN: {% raw %}${{ secrets.__LABEL_TOKEN_ENV__ || github.token }}{% endraw %}
34
+ PR_NUMBER: {% raw %}${{ github.event.inputs.pr_number }}{% endraw %}
35
+ EXPECTED_HEAD_SHA: {% raw %}${{ github.event.inputs.head_sha }}{% endraw %}
36
+ NEEDS_LABEL: "__NEEDS_LABEL__"
37
+ run: |
38
+ set -euo pipefail
39
+
40
+ current_head="$(gh pr view "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --json headRefOid --jq .headRefOid)"
41
+ if [ -n "${EXPECTED_HEAD_SHA:-}" ] && [ "${EXPECTED_HEAD_SHA}" != "${current_head}" ]; then
42
+ echo "::error::PR #${PR_NUMBER} current head ${current_head} does not match expected ${EXPECTED_HEAD_SHA}"
43
+ exit 1
44
+ fi
45
+
46
+ gh issue edit "${PR_NUMBER}" --repo "${GITHUB_REPOSITORY}" --add-label "${NEEDS_LABEL}"
47
+ echo "Queued ${NEEDS_LABEL} for ${GITHUB_REPOSITORY}#${PR_NUMBER} at ${current_head}."
@@ -0,0 +1,34 @@
1
+ # Code Mower workflow template: local CLI audit operating note.
2
+ #
3
+ # Local CLI lanes run in a trusted developer/operator environment so provider
4
+ # auth, local checkout paths, and paid model credentials do not cross fork PR
5
+ # boundaries inside GitHub Actions.
6
+ name: Code Mower Local CLI Audit Note
7
+
8
+ on:
9
+ workflow_dispatch:
10
+ inputs:
11
+ pr_number:
12
+ description: "Pull request number to audit locally"
13
+ required: true
14
+
15
+ permissions:
16
+ contents: read
17
+
18
+ jobs:
19
+ instructions:
20
+ runs-on: ubuntu-latest
21
+ timeout-minutes: 2
22
+ steps:
23
+ - name: Print local audit command shape
24
+ env:
25
+ PR_NUMBER: {% raw %}${{ github.event.inputs.pr_number }}{% endraw %}
26
+ run: |
27
+ cat <<EOF
28
+ Local CLI audit lanes should be run from a trusted checkout, then the
29
+ resulting audit comment should be posted back to PR #${PR_NUMBER}.
30
+
31
+ Example command shapes:
32
+ tools/run_codex_audit_pr.sh --repo "${GITHUB_REPOSITORY}" --pr "${PR_NUMBER}"
33
+ tools/run_claude_audit_pr.sh --repo "${GITHUB_REPOSITORY}" --pr "${PR_NUMBER}"
34
+ EOF
@@ -0,0 +1,58 @@
1
+ # Code Mower workflow template: apply advisory labels from hosted/SaaS reviewer events.
2
+ name: __WORKFLOW_NAME__
3
+
4
+ on:
5
+ issue_comment:
6
+ types: [created, edited]
7
+ issues:
8
+ types: [labeled]
9
+ pull_request_review:
10
+ types: [submitted, edited]
11
+ check_run:
12
+ types: [completed]
13
+ workflow_dispatch:
14
+ inputs:
15
+ adapter:
16
+ description: "SaaS reviewer adapter to classify"
17
+ required: false
18
+ default: "__ADAPTER__"
19
+
20
+ permissions:
21
+ contents: read
22
+ checks: read
23
+ issues: write
24
+ pull-requests: read
25
+
26
+ env:
27
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
28
+
29
+ jobs:
30
+ label:
31
+ if: >-
32
+ github.event_name == 'workflow_dispatch' ||
33
+ (
34
+ github.event_name == 'issue_comment' &&
35
+ github.event.issue.pull_request
36
+ ) ||
37
+ (
38
+ github.event_name == 'issues' &&
39
+ github.event.issue.pull_request
40
+ ) ||
41
+ github.event_name == 'pull_request_review' ||
42
+ github.event_name == 'check_run'
43
+ runs-on: ubuntu-latest
44
+ timeout-minutes: 5
45
+ steps:
46
+ - name: Check out Code Mower support files from default branch
47
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
48
+ with:
49
+ ref: {% raw %}${{ github.event.repository.default_branch }}{% endraw %}
50
+ persist-credentials: false
51
+
52
+ - name: Apply __DISPLAY_NAME__ reviewer labels
53
+ env:
54
+ GITHUB_TOKEN: {% raw %}${{ github.token }}{% endraw %}
55
+ __LABEL_TOKEN_ENV__: {% raw %}${{ secrets.__LABEL_TOKEN_ENV__ }}{% endraw %}
56
+ __AUTHORS_ENV__: {% raw %}${{ vars.__AUTHORS_ENV__ }}{% endraw %}
57
+ REVIEWER_ADAPTER: {% raw %}${{ github.event.inputs.adapter || '__ADAPTER__' }}{% endraw %}
58
+ run: tools/code_mower saas-reviewer-labeler --adapter "${REVIEWER_ADAPTER}"
@@ -0,0 +1,57 @@
1
+ # Code Mower workflow template: apply labels from trusted audit-result comments.
2
+ name: __WORKFLOW_NAME__
3
+
4
+ on:
5
+ issue_comment:
6
+ types: [created]
7
+ workflow_dispatch:
8
+ inputs:
9
+ lane:
10
+ description: "Trailer-comment lane to classify"
11
+ required: false
12
+ default: "__TRAILER_LANE__"
13
+
14
+ permissions:
15
+ contents: read
16
+ issues: write
17
+ pull-requests: read
18
+
19
+ env:
20
+ FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
21
+
22
+ jobs:
23
+ label:
24
+ if: >-
25
+ github.event_name == 'workflow_dispatch' ||
26
+ (
27
+ github.event_name == 'issue_comment' &&
28
+ github.event.issue.pull_request &&
29
+ (
30
+ contains(github.event.comment.body, '__TRAILER_PREFIX__') ||
31
+ contains(github.event.comment.body, '__DISPLAY_NAME__ Audit') ||
32
+ contains(github.event.comment.body, 'HEAD_CHANGED_DURING_REVIEW') ||
33
+ contains(github.event.comment.body, 'Label state:') ||
34
+ contains(github.event.comment.body, 'Intended label state:') ||
35
+ contains(github.event.comment.body, 'Expected labels:') ||
36
+ contains(github.event.comment.body, 'Intended labels:') ||
37
+ contains(github.event.comment.body, '__NEEDS_LABEL__') ||
38
+ contains(github.event.comment.body, '__DONE_LABEL__') ||
39
+ contains(github.event.comment.body, '__BLOCKED_LABEL__')
40
+ )
41
+ )
42
+ runs-on: ubuntu-latest
43
+ timeout-minutes: 5
44
+ steps:
45
+ - name: Check out Code Mower support files from default branch
46
+ uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10
47
+ with:
48
+ ref: {% raw %}${{ github.event.repository.default_branch }}{% endraw %}
49
+ persist-credentials: false
50
+
51
+ - name: Apply __DISPLAY_NAME__ audit labels
52
+ env:
53
+ GITHUB_TOKEN: {% raw %}${{ github.token }}{% endraw %}
54
+ __LABEL_TOKEN_ENV__: {% raw %}${{ secrets.__LABEL_TOKEN_ENV__ }}{% endraw %}
55
+ __AUTHORS_ENV__: {% raw %}${{ vars.__AUTHORS_ENV__ }}{% endraw %}
56
+ TRAILER_LANE: {% raw %}${{ github.event.inputs.lane || '__TRAILER_LANE__' }}{% endraw %}
57
+ run: tools/code_mower trailer-comment-labeler --lane "${TRAILER_LANE}"