code-mower 0.9.0b1__tar.gz → 0.9.1b1__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.
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/PKG-INFO +18 -8
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/README.md +17 -7
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/pyproject.toml +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/__init__.py +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/board.py +15 -7
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/__init__.py +4 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/adoption.py +157 -9
- code_mower-0.9.1b1/src/code_mower/doctor_checks/github_trusted_authors.py +38 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/runner.py +33 -1
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_status.py +59 -7
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/migration.py +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/package_manifest.py +5 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/PKG-INFO +18 -8
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/SOURCES.txt +1 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_board.py +3 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_github_checks.py +55 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_registry.py +208 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_lane_status.py +38 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_release_hygiene.py +87 -34
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/CODE_OF_CONDUCT.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/LICENSE +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/MANIFEST.in +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/NOTICE +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/SUPPORT.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/requirements/requirements.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/setup.cfg +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/_base.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/cursor_bugbot.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/gitar.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/greptile.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/adapters/qodo.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/antigravity_sdk_probe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/audit_handoff_log.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/audit_labeler_lib.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/audit_limits.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/audit_progress.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/blind_review_artifacts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/blind_review_coordinator.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/board_store.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/bootstrap.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/builder_experiment.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/builder_runs.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/arms.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/auto_discovery.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/commands.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/context_inputs.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/corpus.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/effect_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/evidence.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/evidence_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/identity.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/metrics.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/overlap.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/planning.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/policy.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/results.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/run_results.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/run_status.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/runner.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/truth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/calibration/value_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/checks.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/claude_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/claude_cli_bounce.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/claude_cli_environment.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/clear_stale.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/bundle.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/doctor.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/dogfood.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/endpoints.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/errors.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/events.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/export.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/git_metadata.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/manifest.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/operations.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/reports.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/setup.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/tokens.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/cloud_client/upload.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/code_mower_calibration.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/code_mower_context_packs.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/code_mower_merge.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/code_mower_telemetry.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/codex_audit_env_preflight.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/codex_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/codex_audit_schema_smoke.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/codex_audit_verdict.schema.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/config.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/decisions.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/audit_limits.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/cloud.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/common.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_api.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_branch.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_config.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_human_token.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_provider.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/github_repo.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/groups.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/models.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/output.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/presets.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/privacy.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_env.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_local_audit_setup.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/provider_review_hygiene.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/providers.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/registry.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/runtime.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/doctor_checks/self_hosted_runner.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/gate_health.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/gemini_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/git_identity.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/grok_build_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/hermes_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/init.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/aider.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/claude.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/codex.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/devin.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/gemini_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/grok_build.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/hermes_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/lane_configs/local_llm.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/local_llm_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/local_llm_bakeoff.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/local_llm_calibration.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/local_llm_profiles.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/migration_install.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/migration_mirror.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/migration_readiness.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/migration_rehearsal.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/next_steps.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/observe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/package.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/package_content.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/package_paths.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/package_rendering.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/package_static.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/plan_context.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/prompts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_registry.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/comments.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/exit_codes.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/git.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/github_auth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/github_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/pr_worktree.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/process.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/repo_paths.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/text_schema.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/provider_runners/workspace.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/providers/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/providers/local_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/providers/provenance.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/release_readiness.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/reviewer_metrics.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/reviewer_spend.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/saas_reviewer_labeler.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/secrets.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/builder-experiment.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/calibration-corpus.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/code-mower.example.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/context-packs.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/operability.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/plan-conformance.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/README.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/claude.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/codex.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/cursor.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/generic.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/code_mower +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/product-support/status_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/providers.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/needs-owner-notify.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/templates/workflows/weekly-status.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/trailer_comment_labeler.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/versioning.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/work_orders.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower/workflow_actionlint.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/dependency_links.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/entry_points.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/requires.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/src/code_mower.egg-info/top_level.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/builder-experiment.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/calibration-corpus.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/code-mower.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/context-packs.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/cursor/BUGBOT.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/lanes/README.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/lanes/claude.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/lanes/codex.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/lanes/cursor.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/lanes/generic.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/acp_bridge.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/aider.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/antigravity_cli.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/claude_audit.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/claude_review.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/coderabbit_cli.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/codex.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/cursor_bugbot.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/devin.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/gemini_cli.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/gitar.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/greptile.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/hermes_cli.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/local_llm.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers/qodo.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/providers.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_antigravity_sdk_probe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_audit_comment_posture.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_audit_limits.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_builder_experiment.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_builder_identity.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_builder_runs.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_calibration_effect_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_calibration_truth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_checks.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_claude_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_claude_cli_bounce.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_clear_stale.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_cloud_client.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_cloud_git_metadata.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_cloud_manifest.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_cloud_reports.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_codex_audit_env_preflight.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_codex_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_decision_audit_integration.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_decisions.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_actions_cost_summary.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_actions_failure_selection.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_boundaries.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_output.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_privacy.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_env_required.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_env_tokens.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_local_audit_setup.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_probe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_provider_review_hygiene.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_runtime.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_doctor_self_hosted_runner.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_gate_health.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_init_actionlint.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_init_build_loop.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_local_llm_github_helpers.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_migration_setup_drift.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_observe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_plan_context.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_prompts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_fixture_contracts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_local_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_comments.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_git.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_github_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_pr_worktree.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_process.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_repo_paths.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_text_schema.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_provider_runners_workspace.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_reviewer_metrics_core.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_reviewer_spend.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_trailer_comment_labeler.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.1b1}/tests/test_work_orders.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: code-mower
|
|
3
|
-
Version: 0.9.
|
|
3
|
+
Version: 0.9.1b1
|
|
4
4
|
Summary: Multi-reviewer AI code audit orchestration
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Requires-Python: >=3.12
|
|
@@ -95,12 +95,17 @@ wrappers, run `code-mower migration setup-drift --repo-path .` before copying a
|
|
|
95
95
|
fresh `.code-mower.generated` tree. It is read-only and reports path-level
|
|
96
96
|
classifications (`same`, `differs`, `new`, `repo-only`,
|
|
97
97
|
`missing-from-output`) without file contents or diffs.
|
|
98
|
+
Use [Upgrade An Existing Repository](docs/upgrade-existing-repo.md) for the
|
|
99
|
+
reviewed PR flow, repo-only file handling, builder identity checks, and
|
|
100
|
+
wrapper/pin drift checks.
|
|
98
101
|
|
|
99
102
|
After `init` and `doctor`, use `code-mower lanes status --repo OWNER/REPO` to
|
|
100
103
|
see active builder/reviewer lanes, gate/check state, recent Code Mower
|
|
101
104
|
workflows, local board/process hints when present, and the next operator
|
|
102
105
|
action. Text and JSON output redact local cwd paths by default; use
|
|
103
|
-
`--show-local-paths` only for local debugging.
|
|
106
|
+
`--show-local-paths` only for local debugging. Local Board discovery is
|
|
107
|
+
best-effort across common macOS and Linux listener tools; when a host restricts
|
|
108
|
+
listener inventory, remote PR/check status still reports normally.
|
|
104
109
|
|
|
105
110
|
For the same redacted metadata in a local browser view, run
|
|
106
111
|
`code-mower board serve --repo OWNER/REPO` and open the printed localhost URL.
|
|
@@ -164,10 +169,12 @@ after reinstalling, especially when switching between pipx and uv.
|
|
|
164
169
|
| C. Builder experiment | You want to compare authoring loops before trusting them broadly. | Use a work order or experiment spec, run `code-mower builder-experiment run` around an explicit command, then review the source-free `authoringRun` artifact and normal audit evidence. | [Builder Experiments](docs/builder-experiments.md) |
|
|
165
170
|
|
|
166
171
|
The current package-index announcement entry point is the tagged
|
|
167
|
-
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.9.
|
|
172
|
+
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.9.1-beta.1/docs/try-in-10-minutes.md)
|
|
168
173
|
guide. The v0.9 beta includes the completed native Board work plus the adoption
|
|
169
|
-
and upgrade hardening from recent install rehearsals
|
|
170
|
-
|
|
174
|
+
and upgrade hardening from recent install rehearsals; v0.9.1 adds a smaller
|
|
175
|
+
announcement-hardening pass on Board visibility, doctor guidance, and safer
|
|
176
|
+
setup docs. Package-only users can start from the public package rather than a
|
|
177
|
+
source checkout.
|
|
171
178
|
|
|
172
179
|
## What Calibration Does And Does Not Prove
|
|
173
180
|
|
|
@@ -190,13 +197,15 @@ review-request signals to propose known-clean and known-blocked cases. Review
|
|
|
190
197
|
every disposition before using it for lane promotion or merge policy.
|
|
191
198
|
|
|
192
199
|
Full walkthrough: [docs/try-in-10-minutes.md](docs/try-in-10-minutes.md).
|
|
200
|
+
Existing-repo upgrade flow:
|
|
201
|
+
[docs/upgrade-existing-repo.md](docs/upgrade-existing-repo.md).
|
|
193
202
|
First-time command map: [docs/launch-command-surface.md](docs/launch-command-surface.md).
|
|
194
203
|
Provider-contract baseline for the next release train:
|
|
195
204
|
[docs/v06-truth-baseline.md](docs/v06-truth-baseline.md).
|
|
196
205
|
|
|
197
206
|
For release verification,
|
|
198
207
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
199
|
-
the package-index procedure for `v0.9.
|
|
208
|
+
the package-index procedure for `v0.9.1-beta.1` / `code-mower==0.9.1b1`. The
|
|
200
209
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
201
210
|
|
|
202
211
|
## Optional: Plan Before Coding
|
|
@@ -382,8 +391,8 @@ measurement work.
|
|
|
382
391
|
|
|
383
392
|
## Installation Status
|
|
384
393
|
|
|
385
|
-
The current package-index beta baseline is `v0.9.
|
|
386
|
-
install spec `code-mower==0.9.
|
|
394
|
+
The current package-index beta baseline is `v0.9.1-beta.1`, with pinned package
|
|
395
|
+
install spec `code-mower==0.9.1b1`. Release evidence is recorded on the GitHub
|
|
387
396
|
release and in the first-user install rehearsal. The public repository is
|
|
388
397
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
389
398
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -424,6 +433,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
424
433
|
## Docs Map
|
|
425
434
|
|
|
426
435
|
- [Install And Bootstrap](docs/install.md)
|
|
436
|
+
- [Upgrade An Existing Repository](docs/upgrade-existing-repo.md)
|
|
427
437
|
- [Try Code Mower In 10 Minutes](docs/try-in-10-minutes.md)
|
|
428
438
|
- [Build Loop In 30 Minutes](docs/build-loop-in-30-minutes.md)
|
|
429
439
|
- [Quickstart Reference](docs/quickstart.md)
|
|
@@ -78,12 +78,17 @@ wrappers, run `code-mower migration setup-drift --repo-path .` before copying a
|
|
|
78
78
|
fresh `.code-mower.generated` tree. It is read-only and reports path-level
|
|
79
79
|
classifications (`same`, `differs`, `new`, `repo-only`,
|
|
80
80
|
`missing-from-output`) without file contents or diffs.
|
|
81
|
+
Use [Upgrade An Existing Repository](docs/upgrade-existing-repo.md) for the
|
|
82
|
+
reviewed PR flow, repo-only file handling, builder identity checks, and
|
|
83
|
+
wrapper/pin drift checks.
|
|
81
84
|
|
|
82
85
|
After `init` and `doctor`, use `code-mower lanes status --repo OWNER/REPO` to
|
|
83
86
|
see active builder/reviewer lanes, gate/check state, recent Code Mower
|
|
84
87
|
workflows, local board/process hints when present, and the next operator
|
|
85
88
|
action. Text and JSON output redact local cwd paths by default; use
|
|
86
|
-
`--show-local-paths` only for local debugging.
|
|
89
|
+
`--show-local-paths` only for local debugging. Local Board discovery is
|
|
90
|
+
best-effort across common macOS and Linux listener tools; when a host restricts
|
|
91
|
+
listener inventory, remote PR/check status still reports normally.
|
|
87
92
|
|
|
88
93
|
For the same redacted metadata in a local browser view, run
|
|
89
94
|
`code-mower board serve --repo OWNER/REPO` and open the printed localhost URL.
|
|
@@ -147,10 +152,12 @@ after reinstalling, especially when switching between pipx and uv.
|
|
|
147
152
|
| C. Builder experiment | You want to compare authoring loops before trusting them broadly. | Use a work order or experiment spec, run `code-mower builder-experiment run` around an explicit command, then review the source-free `authoringRun` artifact and normal audit evidence. | [Builder Experiments](docs/builder-experiments.md) |
|
|
148
153
|
|
|
149
154
|
The current package-index announcement entry point is the tagged
|
|
150
|
-
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.9.
|
|
155
|
+
[Try Code Mower In 10 Minutes](https://github.com/codemower-ai/code-mower/blob/v0.9.1-beta.1/docs/try-in-10-minutes.md)
|
|
151
156
|
guide. The v0.9 beta includes the completed native Board work plus the adoption
|
|
152
|
-
and upgrade hardening from recent install rehearsals
|
|
153
|
-
|
|
157
|
+
and upgrade hardening from recent install rehearsals; v0.9.1 adds a smaller
|
|
158
|
+
announcement-hardening pass on Board visibility, doctor guidance, and safer
|
|
159
|
+
setup docs. Package-only users can start from the public package rather than a
|
|
160
|
+
source checkout.
|
|
154
161
|
|
|
155
162
|
## What Calibration Does And Does Not Prove
|
|
156
163
|
|
|
@@ -173,13 +180,15 @@ review-request signals to propose known-clean and known-blocked cases. Review
|
|
|
173
180
|
every disposition before using it for lane promotion or merge policy.
|
|
174
181
|
|
|
175
182
|
Full walkthrough: [docs/try-in-10-minutes.md](docs/try-in-10-minutes.md).
|
|
183
|
+
Existing-repo upgrade flow:
|
|
184
|
+
[docs/upgrade-existing-repo.md](docs/upgrade-existing-repo.md).
|
|
176
185
|
First-time command map: [docs/launch-command-surface.md](docs/launch-command-surface.md).
|
|
177
186
|
Provider-contract baseline for the next release train:
|
|
178
187
|
[docs/v06-truth-baseline.md](docs/v06-truth-baseline.md).
|
|
179
188
|
|
|
180
189
|
For release verification,
|
|
181
190
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
182
|
-
the package-index procedure for `v0.9.
|
|
191
|
+
the package-index procedure for `v0.9.1-beta.1` / `code-mower==0.9.1b1`. The
|
|
183
192
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
184
193
|
|
|
185
194
|
## Optional: Plan Before Coding
|
|
@@ -365,8 +374,8 @@ measurement work.
|
|
|
365
374
|
|
|
366
375
|
## Installation Status
|
|
367
376
|
|
|
368
|
-
The current package-index beta baseline is `v0.9.
|
|
369
|
-
install spec `code-mower==0.9.
|
|
377
|
+
The current package-index beta baseline is `v0.9.1-beta.1`, with pinned package
|
|
378
|
+
install spec `code-mower==0.9.1b1`. Release evidence is recorded on the GitHub
|
|
370
379
|
release and in the first-user install rehearsal. The public repository is
|
|
371
380
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
372
381
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -407,6 +416,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
407
416
|
## Docs Map
|
|
408
417
|
|
|
409
418
|
- [Install And Bootstrap](docs/install.md)
|
|
419
|
+
- [Upgrade An Existing Repository](docs/upgrade-existing-repo.md)
|
|
410
420
|
- [Try Code Mower In 10 Minutes](docs/try-in-10-minutes.md)
|
|
411
421
|
- [Build Loop In 30 Minutes](docs/build-loop-in-30-minutes.md)
|
|
412
422
|
- [Quickstart Reference](docs/quickstart.md)
|
|
@@ -655,6 +655,14 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
655
655
|
const stateClass = (value) => /fail|error|blocked/i.test(text(value)) ? "bad" : /warn|pending|waiting|queued|progress/i.test(text(value)) ? "warn" : "ok";
|
|
656
656
|
const seconds = (value) => Number.isFinite(Number(value)) ? `${{Number(value).toFixed(1)}}s` : "n/a";
|
|
657
657
|
const money = (value) => Number.isFinite(Number(value)) ? `$${{Number(value).toFixed(3)}}` : "n/a";
|
|
658
|
+
const localTime = (value) => {{
|
|
659
|
+
const raw = text(value);
|
|
660
|
+
if (!raw) return "";
|
|
661
|
+
const date = new Date(raw);
|
|
662
|
+
if (Number.isNaN(date.getTime())) return esc(raw);
|
|
663
|
+
const local = new Intl.DateTimeFormat(undefined, {{year:"numeric", month:"short", day:"numeric", hour:"numeric", minute:"2-digit", second:"2-digit", timeZoneName:"short"}}).format(date);
|
|
664
|
+
return `<time datetime="${{esc(raw)}}" title="UTC ${{esc(raw)}}">${{esc(local)}}</time>`;
|
|
665
|
+
}};
|
|
658
666
|
function labels(groups) {{
|
|
659
667
|
return Object.values(groups || {{}}).flat().map(pill).join(" ") || '<span class="muted">none</span>';
|
|
660
668
|
}}
|
|
@@ -663,7 +671,7 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
663
671
|
}}
|
|
664
672
|
function render(data) {{
|
|
665
673
|
document.getElementById("repo").textContent = REPO;
|
|
666
|
-
document.getElementById("generated").
|
|
674
|
+
document.getElementById("generated").innerHTML = data.generated_at ? `Generated ${{localTime(data.generated_at)}}` : "Loading...";
|
|
667
675
|
const prs = data.remote?.pull_requests || [];
|
|
668
676
|
const runs = data.remote?.workflow_runs || [];
|
|
669
677
|
const alerts = data.remote?.gate_health?.alerts || [];
|
|
@@ -681,18 +689,18 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
681
689
|
`<div class="metric"><span class="muted">Agent cards</span><b>${{agentCards.length}}</b></div>`,
|
|
682
690
|
`<div class="metric"><span class="muted">Gate alerts</span><b class="${{alerts.length ? "warn" : "ok"}}">${{alerts.length}}</b></div>`
|
|
683
691
|
].join(""));
|
|
684
|
-
put("owner", ownerQueue.length ? ownerQueue.map(item => `<div class="row"><div class="line"><a href="${{esc(href(item.url))}}">#${{esc(item.pr_number)}} ${{esc(item.kind)}}</a>${{pill(item.next_action)}}${{pill(item.head_sha_prefix)}}</div><div class="muted">${{esc(item.branch)}} by ${{esc(item.author)}} updated ${{
|
|
685
|
-
put("agents", agentCards.length ? agentCards.map(agent => `<div class="row"><div class="line"><b>${{esc(agent.provider)}}</b>${{pill(agent.role)}}${{pill(agent.status)}}${{agent.lane ? pill(agent.lane) : ""}}${{agent.pr_number ? pill(`#${{agent.pr_number}}`) : ""}}</div><div>${{esc(agent.title || agent.next_action || "local agent")}}</div><div class="muted">${{esc(agent.branch || agent.repo || "")}}${{agent.pid ? ` pid=${{esc(agent.pid)}}` : ""}}${{agent.cwd ? ` cwd=${{esc(agent.cwd)}}` : ""}}${{agent.updated_at ? ` updated ${{
|
|
692
|
+
put("owner", ownerQueue.length ? ownerQueue.map(item => `<div class="row"><div class="line"><a href="${{esc(href(item.url))}}">#${{esc(item.pr_number)}} ${{esc(item.kind)}}</a>${{pill(item.next_action)}}${{pill(item.head_sha_prefix)}}</div><div class="muted">${{esc(item.branch)}} by ${{esc(item.author)}}${{item.updated_at ? ` updated ${{localTime(item.updated_at)}}` : ""}}</div></div>`).join("") : empty(data.owner_queue?.message || "No owner queue items."));
|
|
693
|
+
put("agents", agentCards.length ? agentCards.map(agent => `<div class="row"><div class="line"><b>${{esc(agent.provider)}}</b>${{pill(agent.role)}}${{pill(agent.status)}}${{agent.lane ? pill(agent.lane) : ""}}${{agent.pr_number ? pill(`#${{agent.pr_number}}`) : ""}}</div><div>${{esc(agent.title || agent.next_action || "local agent")}}</div><div class="muted">${{esc(agent.branch || agent.repo || "")}}${{agent.pid ? ` pid=${{esc(agent.pid)}}` : ""}}${{agent.cwd ? ` cwd=${{esc(agent.cwd)}}` : ""}}${{agent.updated_at ? ` updated ${{localTime(agent.updated_at)}}` : ""}}</div></div>`).join("") : empty(data.agent_adapters?.message || "No local agent adapter cards."));
|
|
686
694
|
put("prs", prs.length ? prs.map(pr => `<div class="row">
|
|
687
695
|
<div class="line"><a href="${{esc(href(pr.url))}}">#${{esc(pr.number)}} ${{esc(pr.title)}}</a>${{pill(pr.merge_state)}}${{pr.is_draft ? pill("draft") : ""}}${{pr.stale ? pill("stale") : ""}}</div>
|
|
688
|
-
<div class="muted">${{esc(pr.branch)}} by ${{esc(pr.author)}} updated ${{
|
|
696
|
+
<div class="muted">${{esc(pr.branch)}} by ${{esc(pr.author)}}${{pr.updated_at ? ` updated ${{localTime(pr.updated_at)}}` : ""}}</div>
|
|
689
697
|
<div>labels: ${{labels(pr.labels)}}</div>
|
|
690
698
|
<div>checks: ${{checks(pr.checks)}}</div>
|
|
691
699
|
<div>next: <b>${{esc(pr.next_action)}}</b></div>
|
|
692
700
|
</div>`).join("") : empty("No open pull requests."));
|
|
693
701
|
put("alerts", alerts.length ? alerts.map(a => `<div class="row"><b class="warn">${{esc(a.kind)}}</b> ${{esc(a.message)}}</div>`).join("") : empty("No gate alerts."));
|
|
694
|
-
put("runs", runs.length ? runs.slice(0, 8).map(run => `<div class="row"><div class="line"><a href="${{esc(href(run.url))}}">${{esc(run.workflow || "workflow")}}</a>${{pill(run.conclusion || run.status || "unknown")}}</div><div class="muted">${{esc(run.branch)}} updated ${{
|
|
695
|
-
put("verdicts", verdicts.length ? verdicts.map(v => `<div class="row"><div class="line"><a href="${{esc(href(v.url))}}">#${{esc(v.pr_number)}} ${{esc(v.lane)}}</a>${{pill(v.verdict)}}${{pill(v.head_sha_prefix)}}</div><div class="muted">${{
|
|
702
|
+
put("runs", runs.length ? runs.slice(0, 8).map(run => `<div class="row"><div class="line"><a href="${{esc(href(run.url))}}">${{esc(run.workflow || "workflow")}}</a>${{pill(run.conclusion || run.status || "unknown")}}</div><div class="muted">${{esc(run.branch)}}${{run.updated_at ? ` updated ${{localTime(run.updated_at)}}` : ""}}</div></div>`).join("") : empty("No recent Code Mower workflow runs."));
|
|
703
|
+
put("verdicts", verdicts.length ? verdicts.map(v => `<div class="row"><div class="line"><a href="${{esc(href(v.url))}}">#${{esc(v.pr_number)}} ${{esc(v.lane)}}</a>${{pill(v.verdict)}}${{pill(v.head_sha_prefix)}}</div><div class="muted">${{localTime(v.created_at)}}</div></div>`).join("") : empty(timelines.verdicts?.message || "No local reviewer verdict history yet."));
|
|
696
704
|
const spendRows = [
|
|
697
705
|
...spendGroups.map(g => `<div class="row"><div class="line"><b>${{esc(g.lane)}}</b>${{pill(g.verdict)}}${{pill(`${{g.runs}} runs`)}}</div><div class="muted">${{seconds(g.wall_seconds_total)}} total / ${{seconds(g.wall_seconds_avg)}} avg / ${{money(g.cost_usd_total)}} / ${{esc(g.total_tokens || 0)}} tokens</div></div>`),
|
|
698
706
|
spend.skipped_rows ? `<div class="row muted">Skipped ${{esc(spend.skipped_rows)}} malformed spend row(s).</div>` : "",
|
|
@@ -708,7 +716,7 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
708
716
|
put("history", events.length ? events.slice().reverse().map(event => {{
|
|
709
717
|
const s = event.summary || {{}};
|
|
710
718
|
const remote = s.remote_available ? "remote available" : "remote unavailable";
|
|
711
|
-
return `<div class="row"><div class="line"><b>${{
|
|
719
|
+
return `<div class="row"><div class="line"><b>${{localTime(event.created_at)}}</b>${{pill(remote)}}</div><div>next: <b>${{esc(s.next_action || "inspect")}}</b></div><div class="muted">PRs ${{esc(s.open_prs ?? 0)}} / alerts ${{esc(s.gate_alerts ?? 0)}} / local ${{esc((s.local_boards ?? 0) + (s.local_processes ?? 0))}}</div></div>`;
|
|
712
720
|
}}).join("") : empty(history.message || "No local board events recorded yet."));
|
|
713
721
|
}}
|
|
714
722
|
async function load() {{
|
|
@@ -13,6 +13,7 @@ from .cloud import (
|
|
|
13
13
|
token_file_mentions_cloud_token,
|
|
14
14
|
)
|
|
15
15
|
from .adoption import (
|
|
16
|
+
check_adoption_posture_guidance,
|
|
16
17
|
check_adoption_setup,
|
|
17
18
|
config_with_repository_target,
|
|
18
19
|
detect_repo_slug,
|
|
@@ -31,6 +32,7 @@ from .github_human_token import (
|
|
|
31
32
|
human_automation_token_config,
|
|
32
33
|
human_automation_token_required,
|
|
33
34
|
)
|
|
35
|
+
from .github_trusted_authors import trusted_author_variable_statuses
|
|
34
36
|
from .groups import GROUP_LABELS, doctor_check_group_id
|
|
35
37
|
from .models import (
|
|
36
38
|
STATUS_FAIL,
|
|
@@ -105,11 +107,13 @@ __all__ = [
|
|
|
105
107
|
"auth_probe_output_detail",
|
|
106
108
|
"build_doctor_run_plan",
|
|
107
109
|
"check_cloud_token_surface",
|
|
110
|
+
"check_adoption_posture_guidance",
|
|
108
111
|
"check_adoption_setup",
|
|
109
112
|
"check_github_auth_surface",
|
|
110
113
|
"check_macos_runner_launchagent",
|
|
111
114
|
"check_github_setup",
|
|
112
115
|
"check_human_automation_token",
|
|
116
|
+
"trusted_author_variable_statuses",
|
|
113
117
|
"check_repository_posture",
|
|
114
118
|
"check_lane_runtime",
|
|
115
119
|
"check_review_hygiene",
|
|
@@ -5,13 +5,25 @@ from __future__ import annotations
|
|
|
5
5
|
import re
|
|
6
6
|
import subprocess
|
|
7
7
|
from pathlib import Path
|
|
8
|
-
from typing import Any, Mapping
|
|
8
|
+
from typing import Any, Mapping, Sequence
|
|
9
9
|
|
|
10
10
|
from .models import STATUS_PASS, STATUS_WARN, DoctorCheck
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
OWNER_REPO_RE = re.compile(r"^[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+$")
|
|
14
14
|
OWNER_LOGIN_PLACEHOLDER = "TODO_OWNER_LOGIN"
|
|
15
|
+
TRUSTED_AUDIT_AUTHOR_VARIABLES = (
|
|
16
|
+
"CLAUDE_AUDIT_BOT_AUTHORS",
|
|
17
|
+
"CODEX_BOT_AUTHORS",
|
|
18
|
+
)
|
|
19
|
+
GENERATED_SETUP_MARKERS = {
|
|
20
|
+
"generated_config": (".code-mower.generated/code-mower.yml",),
|
|
21
|
+
"installed_gate_workflow": (".github/workflows/code-mower-gate.yml",),
|
|
22
|
+
"installed_dispatch_workflow": (".github/workflows/dispatch-lanes.yml",),
|
|
23
|
+
"installed_agent_pr_labeler": (
|
|
24
|
+
".github/workflows/code-mower-agent-pr-labeler.yml",
|
|
25
|
+
),
|
|
26
|
+
}
|
|
15
27
|
|
|
16
28
|
|
|
17
29
|
def normalize_repo_slug(value: str, *, option: str = "--repo") -> str:
|
|
@@ -103,6 +115,85 @@ def _configured_repositories(config: Mapping[str, Any] | None) -> list[str]:
|
|
|
103
115
|
return slugs
|
|
104
116
|
|
|
105
117
|
|
|
118
|
+
def _generated_setup_marker_types(repo_root: Path | None) -> list[str]:
|
|
119
|
+
if repo_root is None:
|
|
120
|
+
return []
|
|
121
|
+
marker_types: list[str] = []
|
|
122
|
+
for marker_type, relative_paths in GENERATED_SETUP_MARKERS.items():
|
|
123
|
+
if any((repo_root / relative_path).exists() for relative_path in relative_paths):
|
|
124
|
+
marker_types.append(marker_type)
|
|
125
|
+
return marker_types
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def _config_source_state(
|
|
129
|
+
*,
|
|
130
|
+
source: str,
|
|
131
|
+
using_packaged_example: bool,
|
|
132
|
+
generated_marker_types: Sequence[str],
|
|
133
|
+
) -> str:
|
|
134
|
+
if not using_packaged_example:
|
|
135
|
+
return source or "repository_config"
|
|
136
|
+
if source == "source_tree_starter":
|
|
137
|
+
return "source_tree_starter"
|
|
138
|
+
if generated_marker_types:
|
|
139
|
+
return "generated_without_root_config"
|
|
140
|
+
return "cold_configless"
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def check_adoption_posture_guidance(
|
|
144
|
+
checks: Sequence[DoctorCheck],
|
|
145
|
+
*,
|
|
146
|
+
adoption: bool,
|
|
147
|
+
adoption_posture: str,
|
|
148
|
+
) -> tuple[DoctorCheck, ...]:
|
|
149
|
+
"""Return first-run guidance when default posture may not match this host."""
|
|
150
|
+
|
|
151
|
+
if not adoption or adoption_posture != "reviewer-gate":
|
|
152
|
+
return ()
|
|
153
|
+
local_provider_gap_names = {"runtime.local_cli", "runtime.local_cli.probe"}
|
|
154
|
+
gap_lanes = sorted(
|
|
155
|
+
{
|
|
156
|
+
str(check.lane)
|
|
157
|
+
for check in checks
|
|
158
|
+
if check.lane
|
|
159
|
+
and (
|
|
160
|
+
check.name in local_provider_gap_names
|
|
161
|
+
or check.name.startswith("runtime.local_audit")
|
|
162
|
+
)
|
|
163
|
+
and check.status == STATUS_WARN
|
|
164
|
+
}
|
|
165
|
+
)
|
|
166
|
+
if not gap_lanes:
|
|
167
|
+
return ()
|
|
168
|
+
return (
|
|
169
|
+
DoctorCheck(
|
|
170
|
+
name="doctor.adoption.posture_hint",
|
|
171
|
+
status=STATUS_WARN,
|
|
172
|
+
message=(
|
|
173
|
+
"default reviewer-gate posture found local provider setup gaps"
|
|
174
|
+
),
|
|
175
|
+
detail={
|
|
176
|
+
"adoption_posture": adoption_posture,
|
|
177
|
+
"local_provider_gap_lanes": gap_lanes,
|
|
178
|
+
"next_steps": [
|
|
179
|
+
"rerun_orchestrator_only_if_this_host_only_coordinates",
|
|
180
|
+
"rerun_hosted_builders_if_this_host_observes_hosted_lanes",
|
|
181
|
+
"finish_local_cli_setup_if_this_host_runs_reviewers",
|
|
182
|
+
],
|
|
183
|
+
"commands": [
|
|
184
|
+
"code-mower doctor --adoption --orchestrator-only --repo OWNER/REPO",
|
|
185
|
+
"code-mower doctor --adoption --hosted-builders --repo OWNER/REPO",
|
|
186
|
+
],
|
|
187
|
+
},
|
|
188
|
+
remediation=(
|
|
189
|
+
"If this host only coordinates or observes hosted builders, "
|
|
190
|
+
"rerun with `--orchestrator-only` or `--hosted-builders`; "
|
|
191
|
+
"otherwise finish the local CLI/token setup for the listed lanes."
|
|
192
|
+
),
|
|
193
|
+
),
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
|
|
106
197
|
def check_adoption_setup(
|
|
107
198
|
*,
|
|
108
199
|
config: Mapping[str, Any] | None,
|
|
@@ -112,6 +203,8 @@ def check_adoption_setup(
|
|
|
112
203
|
repo_source: str,
|
|
113
204
|
using_packaged_example: bool,
|
|
114
205
|
config_source: str = "",
|
|
206
|
+
repo_root: Path | None = None,
|
|
207
|
+
trusted_author_variables: Mapping[str, str] | None = None,
|
|
115
208
|
) -> tuple[DoctorCheck, ...]:
|
|
116
209
|
"""Return first-run adoption posture checks."""
|
|
117
210
|
|
|
@@ -148,27 +241,64 @@ def check_adoption_setup(
|
|
|
148
241
|
source = config_source or (
|
|
149
242
|
"packaged_starter" if using_packaged_example else "repository_config"
|
|
150
243
|
)
|
|
244
|
+
generated_marker_types = _generated_setup_marker_types(repo_root)
|
|
245
|
+
source_state = _config_source_state(
|
|
246
|
+
source=source,
|
|
247
|
+
using_packaged_example=using_packaged_example,
|
|
248
|
+
generated_marker_types=generated_marker_types,
|
|
249
|
+
)
|
|
151
250
|
source_messages = {
|
|
152
251
|
"explicit_config": "using explicit Code Mower config",
|
|
252
|
+
"cold_configless": (
|
|
253
|
+
"using packaged starter config because no repository code-mower.yml was found"
|
|
254
|
+
),
|
|
255
|
+
"generated_without_root_config": (
|
|
256
|
+
"using packaged starter config because generated Code Mower setup exists "
|
|
257
|
+
"but repository code-mower.yml is not installed"
|
|
258
|
+
),
|
|
153
259
|
"packaged_starter": "using packaged starter config for adoption checks",
|
|
154
260
|
"repository_config": "using repository Code Mower config",
|
|
155
261
|
"source_tree_starter": "using source-tree starter config for adoption checks",
|
|
156
262
|
}
|
|
263
|
+
next_steps = (
|
|
264
|
+
[
|
|
265
|
+
"review_generated_setup",
|
|
266
|
+
"install_root_config",
|
|
267
|
+
"rerun_adoption_doctor",
|
|
268
|
+
]
|
|
269
|
+
if source_state == "generated_without_root_config"
|
|
270
|
+
else [
|
|
271
|
+
"run_init_easy_apply",
|
|
272
|
+
"edit_generated_config",
|
|
273
|
+
"rerun_adoption_doctor",
|
|
274
|
+
]
|
|
275
|
+
if source_state == "cold_configless"
|
|
276
|
+
else []
|
|
277
|
+
)
|
|
157
278
|
detail = {
|
|
158
279
|
"config_path": str(config_path),
|
|
159
280
|
"config_source": source,
|
|
281
|
+
"config_source_state": source_state,
|
|
160
282
|
"configured_repositories": repositories,
|
|
161
283
|
"effective_repository": repo_slug,
|
|
284
|
+
"repository_config_present": not using_packaged_example,
|
|
285
|
+
"generated_setup_detected": bool(generated_marker_types),
|
|
286
|
+
"generated_setup_marker_types": generated_marker_types,
|
|
162
287
|
}
|
|
288
|
+
if next_steps:
|
|
289
|
+
detail["next_steps"] = next_steps
|
|
163
290
|
if using_packaged_example:
|
|
164
291
|
checks.append(
|
|
165
292
|
DoctorCheck(
|
|
166
293
|
name="doctor.adoption.config_source",
|
|
167
294
|
status=STATUS_WARN,
|
|
168
|
-
message=source_messages.get(
|
|
295
|
+
message=source_messages.get(source_state, source_messages["packaged_starter"]),
|
|
169
296
|
detail=detail,
|
|
170
297
|
remediation=(
|
|
171
|
-
"
|
|
298
|
+
"Review the generated setup, commit an edited code-mower.yml "
|
|
299
|
+
"at the repository root, then rerun doctor."
|
|
300
|
+
if source_state == "generated_without_root_config"
|
|
301
|
+
else "Run `code-mower init --easy --apply`, review the generated "
|
|
172
302
|
"setup, and commit an edited code-mower.yml before relying "
|
|
173
303
|
"on recurring workflows."
|
|
174
304
|
),
|
|
@@ -236,17 +366,35 @@ def check_adoption_setup(
|
|
|
236
366
|
)
|
|
237
367
|
)
|
|
238
368
|
|
|
369
|
+
trusted_detail: dict[str, Any] = {
|
|
370
|
+
"variables": list(TRUSTED_AUDIT_AUTHOR_VARIABLES)
|
|
371
|
+
}
|
|
372
|
+
if trusted_author_variables is not None:
|
|
373
|
+
variable_status = {
|
|
374
|
+
name: str(trusted_author_variables.get(name) or "missing")
|
|
375
|
+
for name in TRUSTED_AUDIT_AUTHOR_VARIABLES
|
|
376
|
+
}
|
|
377
|
+
trusted_detail["variable_status"] = variable_status
|
|
378
|
+
all_present = all(
|
|
379
|
+
variable_status[name] == "present" for name in TRUSTED_AUDIT_AUTHOR_VARIABLES
|
|
380
|
+
)
|
|
381
|
+
if all_present:
|
|
382
|
+
checks.append(
|
|
383
|
+
DoctorCheck(
|
|
384
|
+
name="doctor.adoption.trusted_authors",
|
|
385
|
+
status=STATUS_PASS,
|
|
386
|
+
message="trusted audit-comment author variables are configured",
|
|
387
|
+
detail=trusted_detail,
|
|
388
|
+
)
|
|
389
|
+
)
|
|
390
|
+
return tuple(checks)
|
|
391
|
+
|
|
239
392
|
checks.append(
|
|
240
393
|
DoctorCheck(
|
|
241
394
|
name="doctor.adoption.trusted_authors",
|
|
242
395
|
status=STATUS_WARN,
|
|
243
396
|
message="human-run audit comments must be listed as trusted lane authors",
|
|
244
|
-
detail=
|
|
245
|
-
"variables": [
|
|
246
|
-
"CLAUDE_AUDIT_BOT_AUTHORS",
|
|
247
|
-
"CODEX_BOT_AUTHORS",
|
|
248
|
-
]
|
|
249
|
-
},
|
|
397
|
+
detail=trusted_detail,
|
|
250
398
|
remediation=(
|
|
251
399
|
"For manual pilot audits, set repository variables such as "
|
|
252
400
|
"CLAUDE_AUDIT_BOT_AUTHORS and CODEX_BOT_AUTHORS to the "
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""GitHub repository variable checks for trusted audit-comment authors."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
|
|
7
|
+
from .github_api import _github_api_json
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def trusted_author_variable_statuses(
|
|
11
|
+
*,
|
|
12
|
+
gh_path: str,
|
|
13
|
+
slug: str,
|
|
14
|
+
variables: Iterable[str],
|
|
15
|
+
http_timeout: int,
|
|
16
|
+
) -> dict[str, str]:
|
|
17
|
+
"""Return safe presence statuses for trusted-author repository variables."""
|
|
18
|
+
|
|
19
|
+
statuses: dict[str, str] = {}
|
|
20
|
+
for variable in variables:
|
|
21
|
+
name = str(variable).strip()
|
|
22
|
+
if not name:
|
|
23
|
+
continue
|
|
24
|
+
payload, _detail = _github_api_json(
|
|
25
|
+
gh_path,
|
|
26
|
+
f"repos/{slug}/actions/variables/{name}",
|
|
27
|
+
http_timeout=http_timeout,
|
|
28
|
+
)
|
|
29
|
+
if payload is None:
|
|
30
|
+
statuses[name] = "missing"
|
|
31
|
+
elif str(payload.get("value") or "").strip():
|
|
32
|
+
statuses[name] = "present"
|
|
33
|
+
else:
|
|
34
|
+
statuses[name] = "empty"
|
|
35
|
+
return statuses
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
__all__ = ("trusted_author_variable_statuses",)
|
|
@@ -3,16 +3,23 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
from pathlib import Path
|
|
6
|
+
import shutil
|
|
6
7
|
from typing import Any, Mapping
|
|
7
8
|
|
|
8
9
|
from code_mower import config as code_mower_config
|
|
9
10
|
|
|
10
|
-
from .adoption import
|
|
11
|
+
from .adoption import (
|
|
12
|
+
TRUSTED_AUDIT_AUTHOR_VARIABLES,
|
|
13
|
+
check_adoption_posture_guidance,
|
|
14
|
+
check_adoption_setup,
|
|
15
|
+
config_with_repository_target,
|
|
16
|
+
)
|
|
11
17
|
from .audit_limits import check_effective_audit_limits
|
|
12
18
|
from .cloud import check_cloud_token_surface
|
|
13
19
|
from .common import ACTIONS_COST_SAMPLE_DEFAULT, load_inputs
|
|
14
20
|
from .github import check_github_setup
|
|
15
21
|
from .github_config import check_repository_posture
|
|
22
|
+
from .github_trusted_authors import trusted_author_variable_statuses
|
|
16
23
|
from .models import STATUS_FAIL, STATUS_PASS, DoctorCheck, DoctorReport
|
|
17
24
|
from .providers import check_lane_runtime, effective_lane, provider_template_coverage, selected_lanes
|
|
18
25
|
from .registry import DoctorCheckStage, build_doctor_run_plan
|
|
@@ -108,6 +115,22 @@ def run_doctor(
|
|
|
108
115
|
repo_root = None if config_path.name == "code-mower.example.yml" else config_path.parent
|
|
109
116
|
config, templates, checks = load_inputs(config_path, provider_templates_path)
|
|
110
117
|
using_packaged_example = config_path.name == "code-mower.example.yml"
|
|
118
|
+
trusted_author_variables = None
|
|
119
|
+
trusted_author_repo_slug = repo_slug
|
|
120
|
+
if not trusted_author_repo_slug and isinstance(config, Mapping):
|
|
121
|
+
for repository in config.get("repositories") or []:
|
|
122
|
+
if isinstance(repository, Mapping) and repository.get("slug"):
|
|
123
|
+
trusted_author_repo_slug = str(repository.get("slug") or "")
|
|
124
|
+
break
|
|
125
|
+
if github and trusted_author_repo_slug:
|
|
126
|
+
gh_path = shutil.which("gh")
|
|
127
|
+
if gh_path:
|
|
128
|
+
trusted_author_variables = trusted_author_variable_statuses(
|
|
129
|
+
gh_path=gh_path,
|
|
130
|
+
slug=trusted_author_repo_slug,
|
|
131
|
+
variables=TRUSTED_AUDIT_AUTHOR_VARIABLES,
|
|
132
|
+
http_timeout=http_timeout,
|
|
133
|
+
)
|
|
111
134
|
checks.extend(
|
|
112
135
|
check_adoption_setup(
|
|
113
136
|
config=config,
|
|
@@ -117,6 +140,8 @@ def run_doctor(
|
|
|
117
140
|
repo_source=repo_source,
|
|
118
141
|
config_source=config_source,
|
|
119
142
|
using_packaged_example=using_packaged_example,
|
|
143
|
+
repo_root=Path.cwd() if using_packaged_example else config_path.parent,
|
|
144
|
+
trusted_author_variables=trusted_author_variables,
|
|
120
145
|
)
|
|
121
146
|
)
|
|
122
147
|
if config is not None and repo_slug:
|
|
@@ -217,6 +242,13 @@ def run_doctor(
|
|
|
217
242
|
http_timeout=http_timeout,
|
|
218
243
|
)
|
|
219
244
|
)
|
|
245
|
+
checks.extend(
|
|
246
|
+
check_adoption_posture_guidance(
|
|
247
|
+
checks,
|
|
248
|
+
adoption=adoption,
|
|
249
|
+
adoption_posture=adoption_posture,
|
|
250
|
+
)
|
|
251
|
+
)
|
|
220
252
|
|
|
221
253
|
if "github" in enabled_stages:
|
|
222
254
|
checks.extend(
|