code-mower 0.9.0b1__tar.gz → 0.9.2b1__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.2b1}/PKG-INFO +19 -8
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/README.md +18 -7
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/pyproject.toml +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/__init__.py +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/board.py +17 -8
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/board_store.py +4 -2
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cli.py +0 -3
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/__init__.py +4 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/adoption.py +157 -9
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_human_token.py +4 -6
- code_mower-0.9.2b1/src/code_mower/doctor_checks/github_trusted_authors.py +38 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/runner.py +33 -1
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_status.py +117 -18
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/migration.py +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/package_manifest.py +5 -1
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower.egg-info/PKG-INFO +19 -8
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower.egg-info/SOURCES.txt +1 -2
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/builder-provenance.yml.j2 +1 -1
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_board.py +5 -2
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_github_checks.py +71 -4
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_registry.py +208 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_lane_status.py +133 -8
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_release_hygiene.py +91 -38
- code_mower-0.9.0b1/src/code_mower/observe.py +0 -324
- code_mower-0.9.0b1/tests/test_observe.py +0 -111
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/CODE_OF_CONDUCT.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/LICENSE +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/MANIFEST.in +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/NOTICE +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/SUPPORT.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/requirements/requirements.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/setup.cfg +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/adapters/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/adapters/_base.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/adapters/cursor_bugbot.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/adapters/gitar.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/adapters/greptile.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/adapters/qodo.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/antigravity_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/antigravity_sdk_probe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/audit_handoff_log.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/audit_labeler_lib.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/audit_limits.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/audit_progress.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/blind_review_artifacts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/blind_review_coordinator.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/bootstrap.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/builder_experiment.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/builder_runs.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/arms.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/auto_discovery.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/commands.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/context_inputs.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/corpus.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/effect_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/evidence.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/evidence_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/identity.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/metrics.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/overlap.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/planning.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/policy.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/results.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/run_results.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/run_status.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/runner.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/truth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/calibration/value_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/checks.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/claude_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/claude_cli_bounce.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/claude_cli_environment.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/clear_stale.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/bundle.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/doctor.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/dogfood.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/endpoints.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/errors.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/events.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/export.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/git_metadata.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/manifest.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/operations.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/reports.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/setup.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/tokens.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/cloud_client/upload.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/code_mower_calibration.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/code_mower_context_packs.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/code_mower_merge.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/code_mower_telemetry.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/codex_audit_env_preflight.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/codex_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/codex_audit_schema_smoke.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/codex_audit_verdict.schema.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/config.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/decisions.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/audit_limits.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/cloud.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/common.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_actions.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_actions_cost.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_actions_cost_summary.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_actions_failure_annotations.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_actions_failure_models.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_actions_failure_scan.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_actions_failure_selection.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_actions_failures.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_actions_permissions.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_api.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_branch.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_config.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_provider.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_repo.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/groups.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/models.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/output.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/presets.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/privacy.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_api_model.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_api_model_openai.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_api_model_profiles.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_env.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_env_required.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_env_tokens.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_local_audit_setup.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_local_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_local_cli_commands.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_local_cli_probe_config.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_probe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_probe_auth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_probe_evaluation.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_probe_json.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_probe_remediation.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/provider_review_hygiene.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/providers.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/registry.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/runtime.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/runtime_github_auth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/self_hosted_runner.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/gate_health.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/gemini_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/git_identity.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/grok_build_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/hermes_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/init.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/aider.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/antigravity_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/claude.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/codex.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/devin.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/gemini_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/grok_build.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/hermes_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/lane_configs/local_llm.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/local_llm_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/local_llm_bakeoff.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/local_llm_calibration.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/local_llm_profiles.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/migration_install.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/migration_mirror.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/migration_readiness.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/migration_rehearsal.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/next_steps.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/package.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/package_content.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/package_paths.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/package_rendering.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/package_static.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/plan_context.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/prompts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_registry.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/comments.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/exit_codes.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/git.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/github_auth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/github_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/pr_worktree.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/process.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/repo_paths.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/text_schema.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/verdict_artifacts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/provider_runners/workspace.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/providers/__init__.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/providers/local_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/providers/provenance.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/release_readiness.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/reviewer_metrics.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/reviewer_spend.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/saas_reviewer_labeler.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/secrets.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/builder-experiment.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/calibration-corpus.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/code-mower.example.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/context-packs.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lane_prompts/base-audit.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lane_prompts/calibration-policy.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lane_prompts/context-driven-quality.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lane_prompts/docs-design.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lane_prompts/generic-programming.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lane_prompts/operability.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lane_prompts/package-runtime.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lane_prompts/plan-conformance.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lane_prompts/security-threat-model.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lanes/README.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lanes/claude.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lanes/codex.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lanes/cursor.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lanes/generic.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/product-support/code_mower +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/product-support/code_mower_standalone_pin.env +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/product-support/code_mower_standalone_shadow.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/product-support/run_claude_audit_pr.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/product-support/run_codex_audit_pr.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/product-support/safe_gh_comment.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/product-support/status_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/providers.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/needs-owner-notify.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/templates/workflows/weekly-status.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/trailer_comment_labeler.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/versioning.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/work_orders.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/workflow_actionlint.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower.egg-info/dependency_links.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower.egg-info/entry_points.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower.egg-info/requires.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower.egg-info/top_level.txt +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/builder-experiment.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/calibration-corpus.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/calibration-corpus.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/code-mower.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/context-packs.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/cursor/BUGBOT.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/lanes/README.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/lanes/claude.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/lanes/codex.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/lanes/cursor.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/lanes/generic.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/lanes/run_mac_lane.sh +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/acp_bridge.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/aider.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/antigravity_cli.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/claude_audit.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/claude_review.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/coderabbit_cli.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/codex.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/cursor_bugbot.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/devin.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/gemini_cli.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/gitar.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/greptile.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/hermes_cli.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/local_llm.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers/qodo.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/providers.yml +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/reviewer-spend.example.json +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/reviewer-value-report.example.md +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/audit-label-cleanup.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/blind-review-artifacts-dry-run.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/code-mower-agent-pr-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/code-mower-fix-round-dispatch.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/code-mower-gate-health.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/code-mower-gate.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/dispatch-lanes.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/hosted-bridge.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/lane-mac-runner.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/local-cli-audit.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/private-standalone-shadow.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/review-clear-stale.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/saas-reviewer-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/self-hosted-local-audit.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/templates/workflows/trailer-comment-labeler.yml.j2 +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_antigravity_sdk_probe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_audit_comment_posture.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_audit_limits.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_builder_experiment.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_builder_identity.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_builder_runs.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_calibration_effect_report.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_calibration_truth.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_checks.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_claude_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_claude_cli_bounce.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_clear_stale.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_cloud_client.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_cloud_git_metadata.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_cloud_manifest.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_cloud_reports.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_coderabbit_cli_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_codex_audit_env_preflight.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_codex_audit_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_decision_audit_integration.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_decisions.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_actions_cost_summary.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_actions_failure_selection.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_boundaries.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_output.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_privacy.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_provider_env_required.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_provider_env_tokens.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_provider_local_audit_setup.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_provider_probe.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_provider_review_hygiene.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_runtime.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_doctor_self_hosted_runner.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_gate_health.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_init_actionlint.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_init_build_loop.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_local_llm_github_helpers.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_migration_setup_drift.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_plan_context.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_prompts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_fixture_contracts.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_local_cli.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_runners_comments.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_runners_git.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_runners_github_pr.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_runners_pr_worktree.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_runners_process.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_runners_repo_paths.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_runners_text_schema.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_provider_runners_workspace.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_reviewer_metrics_core.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_reviewer_spend.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/tests/test_trailer_comment_labeler.py +0 -0
- {code_mower-0.9.0b1 → code_mower-0.9.2b1}/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.2b1
|
|
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,13 @@ 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.2-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.2 keeps the path
|
|
175
|
+
simple by removing the retired third-party observe bridge, softening
|
|
176
|
+
dispatch-token expiry metadata when the secret is present, and making
|
|
177
|
+
stale-audit waits name the runner/dispatcher requeue path. Package-only users
|
|
178
|
+
can start from the public package rather than a source checkout.
|
|
171
179
|
|
|
172
180
|
## What Calibration Does And Does Not Prove
|
|
173
181
|
|
|
@@ -190,13 +198,15 @@ review-request signals to propose known-clean and known-blocked cases. Review
|
|
|
190
198
|
every disposition before using it for lane promotion or merge policy.
|
|
191
199
|
|
|
192
200
|
Full walkthrough: [docs/try-in-10-minutes.md](docs/try-in-10-minutes.md).
|
|
201
|
+
Existing-repo upgrade flow:
|
|
202
|
+
[docs/upgrade-existing-repo.md](docs/upgrade-existing-repo.md).
|
|
193
203
|
First-time command map: [docs/launch-command-surface.md](docs/launch-command-surface.md).
|
|
194
204
|
Provider-contract baseline for the next release train:
|
|
195
205
|
[docs/v06-truth-baseline.md](docs/v06-truth-baseline.md).
|
|
196
206
|
|
|
197
207
|
For release verification,
|
|
198
208
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
199
|
-
the package-index procedure for `v0.9.
|
|
209
|
+
the package-index procedure for `v0.9.2-beta.1` / `code-mower==0.9.2b1`. The
|
|
200
210
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
201
211
|
|
|
202
212
|
## Optional: Plan Before Coding
|
|
@@ -382,8 +392,8 @@ measurement work.
|
|
|
382
392
|
|
|
383
393
|
## Installation Status
|
|
384
394
|
|
|
385
|
-
The current package-index beta baseline is `v0.9.
|
|
386
|
-
install spec `code-mower==0.9.
|
|
395
|
+
The current package-index beta baseline is `v0.9.2-beta.1`, with pinned package
|
|
396
|
+
install spec `code-mower==0.9.2b1`. Release evidence is recorded on the GitHub
|
|
387
397
|
release and in the first-user install rehearsal. The public repository is
|
|
388
398
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
389
399
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -424,6 +434,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
424
434
|
## Docs Map
|
|
425
435
|
|
|
426
436
|
- [Install And Bootstrap](docs/install.md)
|
|
437
|
+
- [Upgrade An Existing Repository](docs/upgrade-existing-repo.md)
|
|
427
438
|
- [Try Code Mower In 10 Minutes](docs/try-in-10-minutes.md)
|
|
428
439
|
- [Build Loop In 30 Minutes](docs/build-loop-in-30-minutes.md)
|
|
429
440
|
- [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,13 @@ 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.2-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.2 keeps the path
|
|
158
|
+
simple by removing the retired third-party observe bridge, softening
|
|
159
|
+
dispatch-token expiry metadata when the secret is present, and making
|
|
160
|
+
stale-audit waits name the runner/dispatcher requeue path. Package-only users
|
|
161
|
+
can start from the public package rather than a source checkout.
|
|
154
162
|
|
|
155
163
|
## What Calibration Does And Does Not Prove
|
|
156
164
|
|
|
@@ -173,13 +181,15 @@ review-request signals to propose known-clean and known-blocked cases. Review
|
|
|
173
181
|
every disposition before using it for lane promotion or merge policy.
|
|
174
182
|
|
|
175
183
|
Full walkthrough: [docs/try-in-10-minutes.md](docs/try-in-10-minutes.md).
|
|
184
|
+
Existing-repo upgrade flow:
|
|
185
|
+
[docs/upgrade-existing-repo.md](docs/upgrade-existing-repo.md).
|
|
176
186
|
First-time command map: [docs/launch-command-surface.md](docs/launch-command-surface.md).
|
|
177
187
|
Provider-contract baseline for the next release train:
|
|
178
188
|
[docs/v06-truth-baseline.md](docs/v06-truth-baseline.md).
|
|
179
189
|
|
|
180
190
|
For release verification,
|
|
181
191
|
[First-User Install Rehearsal](docs/first-user-install-rehearsal.md) records
|
|
182
|
-
the package-index procedure for `v0.9.
|
|
192
|
+
the package-index procedure for `v0.9.2-beta.1` / `code-mower==0.9.2b1`. The
|
|
183
193
|
GitHub release records the workflow and rehearsal evidence for the exact tag.
|
|
184
194
|
|
|
185
195
|
## Optional: Plan Before Coding
|
|
@@ -365,8 +375,8 @@ measurement work.
|
|
|
365
375
|
|
|
366
376
|
## Installation Status
|
|
367
377
|
|
|
368
|
-
The current package-index beta baseline is `v0.9.
|
|
369
|
-
install spec `code-mower==0.9.
|
|
378
|
+
The current package-index beta baseline is `v0.9.2-beta.1`, with pinned package
|
|
379
|
+
install spec `code-mower==0.9.2b1`. Release evidence is recorded on the GitHub
|
|
370
380
|
release and in the first-user install rehearsal. The public repository is
|
|
371
381
|
[codemower-ai/code-mower](https://github.com/codemower-ai/code-mower), and
|
|
372
382
|
GitHub releases remain the auditable source for tags, build artifacts, and
|
|
@@ -407,6 +417,7 @@ first so local work exercises the same package entrypoint users install.
|
|
|
407
417
|
## Docs Map
|
|
408
418
|
|
|
409
419
|
- [Install And Bootstrap](docs/install.md)
|
|
420
|
+
- [Upgrade An Existing Repository](docs/upgrade-existing-repo.md)
|
|
410
421
|
- [Try Code Mower In 10 Minutes](docs/try-in-10-minutes.md)
|
|
411
422
|
- [Build Loop In 30 Minutes](docs/build-loop-in-30-minutes.md)
|
|
412
423
|
- [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,25 +689,26 @@ 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>
|
|
700
|
+
${{pr.next_detail ? `<div class="muted">${{esc(pr.next_detail)}}</div>` : ""}}
|
|
692
701
|
</div>`).join("") : empty("No open pull requests."));
|
|
693
702
|
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">${{
|
|
703
|
+
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."));
|
|
704
|
+
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
705
|
const spendRows = [
|
|
697
706
|
...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
707
|
spend.skipped_rows ? `<div class="row muted">Skipped ${{esc(spend.skipped_rows)}} malformed spend row(s).</div>` : "",
|
|
699
708
|
spend.filtered_rows ? `<div class="row muted">Filtered ${{esc(spend.filtered_rows)}} spend row(s) from other repos.</div>` : ""
|
|
700
709
|
].filter(Boolean);
|
|
701
710
|
put("spend", spendRows.length ? spendRows.join("") : empty(spend.message || "No reviewer spend rows for this repo yet."));
|
|
702
|
-
const boards = data.
|
|
711
|
+
const boards = data.local_boards?.boards || [];
|
|
703
712
|
const procs = data.local_processes?.processes || [];
|
|
704
713
|
put("local", [...boards.map(b => `<div class="row">board localhost:${{esc(b.port)}} pid=${{esc(b.pid)}} cwd=<code>${{esc(b.cwd || "")}}</code></div>`), ...procs.slice(0, 8).map(p => `<div class="row">${{esc(p.provider)}} pid=${{esc(p.pid)}} cwd=<code>${{esc(p.cwd || "")}}</code></div>`)].join("") || empty("No local boards or lane processes visible."));
|
|
705
714
|
}}
|
|
@@ -708,7 +717,7 @@ def render_board_html(config: BoardConfig) -> str:
|
|
|
708
717
|
put("history", events.length ? events.slice().reverse().map(event => {{
|
|
709
718
|
const s = event.summary || {{}};
|
|
710
719
|
const remote = s.remote_available ? "remote available" : "remote unavailable";
|
|
711
|
-
return `<div class="row"><div class="line"><b>${{
|
|
720
|
+
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
721
|
}}).join("") : empty(history.message || "No local board events recorded yet."));
|
|
713
722
|
}}
|
|
714
723
|
async function load() {{
|
|
@@ -83,14 +83,16 @@ def _redact_local_paths(value: Any) -> Any:
|
|
|
83
83
|
|
|
84
84
|
def _snapshot_summary(snapshot: Mapping[str, Any]) -> dict[str, Any]:
|
|
85
85
|
remote = snapshot.get("remote") if isinstance(snapshot.get("remote"), dict) else {}
|
|
86
|
-
|
|
86
|
+
local_boards = (
|
|
87
|
+
snapshot.get("local_boards") if isinstance(snapshot.get("local_boards"), dict) else {}
|
|
88
|
+
)
|
|
87
89
|
local_processes = (
|
|
88
90
|
snapshot.get("local_processes") if isinstance(snapshot.get("local_processes"), dict) else {}
|
|
89
91
|
)
|
|
90
92
|
pull_requests = remote.get("pull_requests") if isinstance(remote.get("pull_requests"), list) else []
|
|
91
93
|
gate_health = remote.get("gate_health") if isinstance(remote.get("gate_health"), dict) else {}
|
|
92
94
|
gate_alerts = gate_health.get("alerts") if isinstance(gate_health.get("alerts"), list) else []
|
|
93
|
-
boards =
|
|
95
|
+
boards = local_boards.get("boards") if isinstance(local_boards.get("boards"), list) else []
|
|
94
96
|
processes = (
|
|
95
97
|
local_processes.get("processes")
|
|
96
98
|
if isinstance(local_processes.get("processes"), list)
|
|
@@ -71,7 +71,6 @@ from . import local_llm_calibration
|
|
|
71
71
|
from . import local_llm_profiles
|
|
72
72
|
from . import migration as code_mower_migration
|
|
73
73
|
from . import next_steps as code_mower_next_steps
|
|
74
|
-
from . import observe as code_mower_observe
|
|
75
74
|
from . import package as code_mower_package
|
|
76
75
|
from . import prompts as code_mower_prompts
|
|
77
76
|
from . import reviewer_metrics
|
|
@@ -456,7 +455,6 @@ COMMAND_DESCRIPTIONS: dict[str, str] = {
|
|
|
456
455
|
"migration": "Rehearse standalone package and wrapper migration paths.",
|
|
457
456
|
"merge-plan": "Inspect merge-readiness signals and lane labels.",
|
|
458
457
|
"next-steps": "Print the recommended next actions after setup.",
|
|
459
|
-
"observe": "Run legacy optional local observability companions.",
|
|
460
458
|
"package": "Build or inspect package extraction artifacts.",
|
|
461
459
|
"plan": "Create local issue-derived planning artifacts.",
|
|
462
460
|
"project-context": "Create editable local project-context doctrine docs.",
|
|
@@ -596,7 +594,6 @@ COMMAND_HANDLERS: dict[str, CommandHandler] = {
|
|
|
596
594
|
"migration": code_mower_migration.main,
|
|
597
595
|
"merge-plan": code_mower_merge.main,
|
|
598
596
|
"next-steps": code_mower_next_steps.main,
|
|
599
|
-
"observe": code_mower_observe.main,
|
|
600
597
|
"package": _package_main,
|
|
601
598
|
"plan": code_mower_work_orders.plan_main,
|
|
602
599
|
"project-context": code_mower_work_orders.project_context_main,
|
|
@@ -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 "
|
{code_mower-0.9.0b1 → code_mower-0.9.2b1}/src/code_mower/doctor_checks/github_human_token.py
RENAMED
|
@@ -173,11 +173,10 @@ def check_human_automation_token(
|
|
|
173
173
|
http_timeout=http_timeout,
|
|
174
174
|
)
|
|
175
175
|
if variable_payload is None:
|
|
176
|
-
status = _blocking_status_for_posture(adoption_posture)
|
|
177
176
|
return DoctorCheck(
|
|
178
177
|
name="github.human_automation_token",
|
|
179
|
-
status=
|
|
180
|
-
message=f"{slug} is missing the {expires_var} human token expiry
|
|
178
|
+
status=STATUS_WARN,
|
|
179
|
+
message=f"{slug} is missing the {expires_var} human token expiry metadata",
|
|
181
180
|
detail={
|
|
182
181
|
**detail,
|
|
183
182
|
"created_at": str(secret_payload.get("created_at") or ""),
|
|
@@ -219,10 +218,9 @@ def check_human_automation_token(
|
|
|
219
218
|
)
|
|
220
219
|
expiry = _parse_expiry(expiry_text)
|
|
221
220
|
if expiry is None:
|
|
222
|
-
status = _blocking_status_for_posture(adoption_posture)
|
|
223
221
|
return DoctorCheck(
|
|
224
222
|
name="github.human_automation_token",
|
|
225
|
-
status=
|
|
223
|
+
status=STATUS_WARN,
|
|
226
224
|
message=f"{slug} has an invalid {expires_var} value",
|
|
227
225
|
detail={**detail, "expires_at": expiry_text},
|
|
228
226
|
remediation=(
|
|
@@ -235,7 +233,7 @@ def check_human_automation_token(
|
|
|
235
233
|
days_remaining = (expiry - today).days
|
|
236
234
|
status = STATUS_PASS
|
|
237
235
|
if days_remaining < 0:
|
|
238
|
-
status =
|
|
236
|
+
status = STATUS_WARN
|
|
239
237
|
elif days_remaining <= EXPIRY_WARNING_DAYS:
|
|
240
238
|
status = STATUS_WARN
|
|
241
239
|
|
|
@@ -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",)
|