maintainability-agent 4.2.0__tar.gz → 4.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {maintainability_agent-4.2.0/src/maintainability_agent.egg-info → maintainability_agent-4.3.0}/PKG-INFO +3 -3
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/README.md +2 -2
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0/src/maintainability_agent.egg-info}/PKG-INFO +3 -3
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/SOURCES.txt +4 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_adapters.py +46 -1
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_analysis.py +19 -0
- maintainability_agent-4.3.0/src/maintainability_audit/_changed_code_policy.py +98 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_gates.py +2 -1
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_html_view.py +25 -4
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_audit.py +3 -1
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_metric_adapters.py +6 -4
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ratio_adapters.py +4 -1
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/config.py +2 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/renderers.py +25 -4
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/report.py +31 -8
- maintainability_agent-4.3.0/tests/test_analyzers_against_the_real_tools.py +42 -0
- maintainability_agent-4.3.0/tests/test_analyzers_report_what_actually_failed.py +108 -0
- maintainability_agent-4.3.0/tests/test_changed_code_policy.py +137 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/LICENSE +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/pyproject.toml +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/setup.cfg +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/requires.txt +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_analyzer_sections.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_anchor.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_banner.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_catalog.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_cognitive.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_coverage_notes.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_criteria_scope.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_delegated_pillar.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_evidence_reader.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_first_run.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_grammar.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_handoff.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_in_loop.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_in_loop_view.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_jvm_adapters.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_setup.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_operator_reads.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_oracle.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_precommit.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_precommit_install.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_precommit_view.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_prompt_sections.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_cobol.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_go.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_kotlin.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_php.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_ruby.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_rust.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_shell.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_running_version.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_security_delegate.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_security_work_order.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_setup_persist.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_verdict_adapters.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/cli.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/mcp_server.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/prompts.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_a_clone_names_every_copy.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_a_dangling_source_link_is_named_not_fatal.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_a_format_override_is_disclosed.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_a_matching_format_stays_silent.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_a_published_question_offers_what_it_accepts.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_a_rendered_docs_site_is_not_scored_as_source.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_a_setup_question_keeps_its_contract.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_adapters.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_added_lines.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_an_absent_work_order_renders_nothing.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_an_unmeasured_pillar_reports_no_number.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_file_lists_are_batched.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_anchor_and_mode.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_anchor_disclosure.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_architecture.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_attestation.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_audit_components.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_backfill.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_bands.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_behaviour_suites_are_tests.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_both_setup_paths_ask_the_same_stage.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_chat_leads_with_the_work_order.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_check_refuses_plus_only_fragments.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_child_sandbox.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_clean_sees_the_weakened_oracle.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_cli.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_code_scanning_gets_alerts_not_the_record.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_cohesion_with_nothing_to_read_is_not_applicable.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_config_shape.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_conformance_reads_the_operators_ask.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_consent_is_per_repository.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_consent_survives_setup_and_is_asked.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_consent_without_command_has_a_remedy.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_corpus_note_counts_come_from_the_corpus.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_corroborate.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_coverage_config_reaches_children.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_coverage_formats.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_criteria_completion.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_current_state_docs_name_every_parsed_language.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_dead_code.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_declaration_criteria_scope.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_declarative_parsers.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_declared_capabilities_match_the_delegate.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_delegated_security_pillar.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_demo_tree.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_determinism.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_discovery.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_docs_links.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_economic_context.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_every_built_presentation_is_offered.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_every_language_counts_its_own_loop.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_every_language_has_a_loop_fixture.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_every_pool_install_is_the_same_pool.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_every_question_can_be_answered.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_every_surface_says_what_the_run_found.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_example_config_opens_claimed_languages.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_exclude_additional_keeps_the_defaults.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_exposure_never_outranks_band.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_first_run_elicitation.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_first_stage_setup_wording_holds.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_format_ask.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_git_argv.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_go_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_grammar_constructs.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_grammar_token_coverage.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_grok_audit_of_3_11.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_history.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_history_window.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_html_executive.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_in_loop_budgets.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_in_loop_check.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_java_scored.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_kotlin_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_kotlin_metrics.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_language_support_honesty.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_list_tools_publishes_the_answer_path.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_maintenance_signals.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_mcp_format_contract.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_mcp_start_failure_names_what_is_installed.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_missing_security_scanners_are_named_before_the_run.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_mutation_recorded.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_operator_named_paths.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_operator_named_reads.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_oracle_weakening_precision_bar.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_pairing_reads_imports.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_php_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_platform_claim.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_policy_claims.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_population_floors.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_precommit_staged.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_preflight_before_consent_runs_nothing_from_the_tree.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_previous_release_reached_pypi.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_promises.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_python_complexity.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_readme_claims.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_recurrence.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_regular_file_reads_work_without_o_nonblock.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_release_needs_an_empty_ledger.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_release_plan.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_rendered_docs.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_root_grants.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_ruby_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_runner.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_rust_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_sarif.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_scan_history.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_scanner_fingerprint_covers_the_measurement_path.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_scanner_unsafe_direction.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_scanning.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_security_delegate_versions_agree.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_security_findings_keep_their_handoff.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_security_pillar_asserts_a_scanner_set.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_security_pillar_runs_and_shows.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_selection_covers_every_parsed_language.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_semantic_findings_stay_inside_the_audited_files.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_setup_answers_are_the_same_setup.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_setup_instruction_describes_its_own_reply.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_setup_writes_a_valid_config.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_shell_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_shell_metrics.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_skill_install.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_sonar_resolve.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_source_index.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_stamped_documents_stay_honest.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_stdout_outputs.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_terminal_asks_the_same_questions.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_test_commands.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_agent_knows_when_it_is_stale.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_changelog_covers_the_shipping_version.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_chat_payload_has_a_budget.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_condition_says_what_it_measured.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_handoff_rules_are_their_own_module.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_pillar_row_reads_cleanly.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_presentation_question_stays_answerable.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_previous_release_was_tagged.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_prompt_does_not_take_back_what_it_withheld.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_prompt_keeps_listing_what_it_did_not_withhold.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_release_process_describes_itself.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_release_record_stays_well_formed.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_report_is_saved_not_sent.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_security_run_has_a_configurable_limit.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_security_work_order_is_drawn.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_suite_names_the_program_it_ran.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_tree_cannot_redirect_a_read.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_the_version_has_one_source.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_tool_resolution.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_tree_chosen_spawn.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_tree_reads_use_the_primitive.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_trends.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_unanchored_set_matches_corpus.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_unread_code.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_version_claim.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_version_stamping.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_withheld_work_keeps_its_boundary.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_work_items_state_their_own_finding.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_work_order.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/tests/test_written_record.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -47,7 +47,7 @@ Dynamic: license-file
|
|
|
47
47
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
48
48
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
49
49
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
50
|
-
Version **4.
|
|
50
|
+
Version **4.3.0**.
|
|
51
51
|
|
|
52
52
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
53
53
|
>
|
|
@@ -509,7 +509,7 @@ instead of an invokable skill:
|
|
|
509
509
|
This repo ships `action.yml`, usable as a composite action:
|
|
510
510
|
|
|
511
511
|
```yaml
|
|
512
|
-
- uses: marshallguillory86/maintainability-agent@v4.
|
|
512
|
+
- uses: marshallguillory86/maintainability-agent@v4.3.0
|
|
513
513
|
with:
|
|
514
514
|
config: maintainability-agent.json
|
|
515
515
|
changed-only: main...HEAD
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
6
6
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
7
7
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
8
|
-
Version **4.
|
|
8
|
+
Version **4.3.0**.
|
|
9
9
|
|
|
10
10
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
11
11
|
>
|
|
@@ -467,7 +467,7 @@ instead of an invokable skill:
|
|
|
467
467
|
This repo ships `action.yml`, usable as a composite action:
|
|
468
468
|
|
|
469
469
|
```yaml
|
|
470
|
-
- uses: marshallguillory86/maintainability-agent@v4.
|
|
470
|
+
- uses: marshallguillory86/maintainability-agent@v4.3.0
|
|
471
471
|
with:
|
|
472
472
|
config: maintainability-agent.json
|
|
473
473
|
changed-only: main...HEAD
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.3.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -47,7 +47,7 @@ Dynamic: license-file
|
|
|
47
47
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
48
48
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
49
49
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
50
|
-
Version **4.
|
|
50
|
+
Version **4.3.0**.
|
|
51
51
|
|
|
52
52
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
53
53
|
>
|
|
@@ -509,7 +509,7 @@ instead of an invokable skill:
|
|
|
509
509
|
This repo ships `action.yml`, usable as a composite action:
|
|
510
510
|
|
|
511
511
|
```yaml
|
|
512
|
-
- uses: marshallguillory86/maintainability-agent@v4.
|
|
512
|
+
- uses: marshallguillory86/maintainability-agent@v4.3.0
|
|
513
513
|
with:
|
|
514
514
|
config: maintainability-agent.json
|
|
515
515
|
changed-only: main...HEAD
|
|
@@ -22,6 +22,7 @@ src/maintainability_audit/_banner.py
|
|
|
22
22
|
src/maintainability_audit/_built_ins.py
|
|
23
23
|
src/maintainability_audit/_calibration.py
|
|
24
24
|
src/maintainability_audit/_catalog.py
|
|
25
|
+
src/maintainability_audit/_changed_code_policy.py
|
|
25
26
|
src/maintainability_audit/_charts.py
|
|
26
27
|
src/maintainability_audit/_cognitive.py
|
|
27
28
|
src/maintainability_audit/_config_defaults.py
|
|
@@ -179,6 +180,8 @@ tests/test_analyzer_provenance_exclusions.py
|
|
|
179
180
|
tests/test_analyzer_scoring_path.py
|
|
180
181
|
tests/test_analyzer_spread_range.py
|
|
181
182
|
tests/test_analyzer_xml_bounds.py
|
|
183
|
+
tests/test_analyzers_against_the_real_tools.py
|
|
184
|
+
tests/test_analyzers_report_what_actually_failed.py
|
|
182
185
|
tests/test_anchor_and_mode.py
|
|
183
186
|
tests/test_anchor_caveat_and_counts_follow_the_run.py
|
|
184
187
|
tests/test_anchor_disclosure.py
|
|
@@ -208,6 +211,7 @@ tests/test_calibration_drift.py
|
|
|
208
211
|
tests/test_calibration_tooling.py
|
|
209
212
|
tests/test_catalog_selection.py
|
|
210
213
|
tests/test_catalog_tier_promise.py
|
|
214
|
+
tests/test_changed_code_policy.py
|
|
211
215
|
tests/test_chat_leads_with_the_work_order.py
|
|
212
216
|
tests/test_chat_primary_docs.py
|
|
213
217
|
tests/test_check_refuses_plus_only_fragments.py
|
{maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_adapters.py
RENAMED
|
@@ -118,6 +118,36 @@ def _format_default(_base: Path, tree: str) -> tuple[str, ...]:
|
|
|
118
118
|
return (tree, f"{tree}/**")
|
|
119
119
|
|
|
120
120
|
|
|
121
|
+
_REGEX_DIALECTS = frozenset({"regex", "rel_regex"})
|
|
122
|
+
|
|
123
|
+
|
|
124
|
+
def _name_as_regex(pattern: str) -> str:
|
|
125
|
+
"""A shell-style name as a regex that finds it as a path component anywhere.
|
|
126
|
+
|
|
127
|
+
`*` and `?` stay inside one component, as they do for the built-in
|
|
128
|
+
scan's own matcher; the name matches at the start of the path or after
|
|
129
|
+
a `/`, and ends at a `/` or the end, so `.venv/` is not `venv_tools.py`.
|
|
130
|
+
Works for `re.match` on an absolute path (pylint) and `re.search` on a
|
|
131
|
+
relative one (mypy) alike.
|
|
132
|
+
"""
|
|
133
|
+
body = "".join("[^/]*" if ch == "*" else "[^/]" if ch == "?" else re.escape(ch)
|
|
134
|
+
for ch in pattern.strip("/"))
|
|
135
|
+
return f"(?:^|.*/){body}(?:/|$)"
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
def _names_as_paths(excludes: Sequence[str], root: Path) -> tuple[str, ...]:
|
|
139
|
+
"""Plain path names as absolute paths under the root; wildcards dropped.
|
|
140
|
+
|
|
141
|
+
A path dialect (interrogate's `--exclude`) names locations, so
|
|
142
|
+
`calibration/.corpus/` becomes `<root>/calibration/.corpus`. A wildcard
|
|
143
|
+
such as `*.min.js` names no location and cannot be spelled here; it is
|
|
144
|
+
left out, which can only under-exclude — the scan's own filter still
|
|
145
|
+
applies it to what the tool reports.
|
|
146
|
+
"""
|
|
147
|
+
return tuple(str(root / pattern.strip("/")) for pattern in excludes
|
|
148
|
+
if not any(ch in pattern for ch in "*?["))
|
|
149
|
+
|
|
150
|
+
|
|
121
151
|
_TREE_FORMATTERS = {
|
|
122
152
|
"fnmatch": _format_fnmatch,
|
|
123
153
|
"regex": _format_regex,
|
|
@@ -267,7 +297,7 @@ class BaseAdapter:
|
|
|
267
297
|
"""
|
|
268
298
|
if not self.exclude_flag:
|
|
269
299
|
return ()
|
|
270
|
-
entries =
|
|
300
|
+
entries = self.operator_patterns(excludes, root) + self.tree_patterns(
|
|
271
301
|
getattr(excludes, "trees", ()), root
|
|
272
302
|
)
|
|
273
303
|
if not entries:
|
|
@@ -279,6 +309,21 @@ class BaseAdapter:
|
|
|
279
309
|
return tuple(repeated)
|
|
280
310
|
return (self.exclude_flag, self.exclude_separator.join(entries))
|
|
281
311
|
|
|
312
|
+
def operator_patterns(self, excludes: Sequence[str], root: Path | None = None) -> tuple[str, ...]:
|
|
313
|
+
"""The operator's exclude names, spelled for this tool's matcher.
|
|
314
|
+
|
|
315
|
+
They are shell-style names — `.venv/`, `*.egg-info/` — and for most
|
|
316
|
+
dialects they pass through as written. A regex dialect compiles
|
|
317
|
+
them: pylint's `--ignore-paths` refused `*.egg-info` ("nothing to
|
|
318
|
+
repeat"), exited with an argument error, and analysed nothing, on
|
|
319
|
+
every repository whose config carried a glob (the default does).
|
|
320
|
+
"""
|
|
321
|
+
if self.exclude_dialect == "abspath":
|
|
322
|
+
return _names_as_paths(excludes, Path(root) if root is not None else Path("."))
|
|
323
|
+
if self.exclude_dialect not in _REGEX_DIALECTS:
|
|
324
|
+
return tuple(excludes)
|
|
325
|
+
return tuple(_name_as_regex(pattern) for pattern in excludes)
|
|
326
|
+
|
|
282
327
|
def tree_patterns(
|
|
283
328
|
self, trees: Sequence[str], root: Path | None = None
|
|
284
329
|
) -> tuple[str, ...]:
|
{maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_analysis.py
RENAMED
|
@@ -447,6 +447,7 @@ def _attempt(root: Path, adapter: Any, probe: Probe, timeout: int,
|
|
|
447
447
|
)
|
|
448
448
|
|
|
449
449
|
result, parsed = _run_batches(adapter, root, excludes, timeout)
|
|
450
|
+
result = _silent_failure(adapter.slug, result, parsed)
|
|
450
451
|
# Filtered before the counts are taken, not after. Recording 48
|
|
451
452
|
# measurements and reporting 6 describes an activity rather than a
|
|
452
453
|
# result, which is the defect this project keeps finding.
|
|
@@ -500,6 +501,24 @@ def _run_batches(adapter: Any, root: Path, excludes: Sequence[str],
|
|
|
500
501
|
return _merged_result(results, len(invocations)), _merged_extraction(parsed)
|
|
501
502
|
|
|
502
503
|
|
|
504
|
+
def _silent_failure(slug: str, result: ToolResult, parsed: Extraction) -> ToolResult:
|
|
505
|
+
"""A tool that wrote nothing failed, whatever its exit code says.
|
|
506
|
+
|
|
507
|
+
pylint's argument error exits 2, which is also its "error messages
|
|
508
|
+
issued" bit, so a run that analysed nothing counted as one that worked
|
|
509
|
+
and its empty output was reported as unreadable JSON while stderr held
|
|
510
|
+
the reason. secure-code-agent recorded the same class as its D30: let
|
|
511
|
+
the output decide, and let the failure carry what the tool said.
|
|
512
|
+
"""
|
|
513
|
+
if not (parsed.parse_error and result.usable and not (result.stdout or "").strip()):
|
|
514
|
+
return result
|
|
515
|
+
said = " ".join((result.stderr or "").split())[:400]
|
|
516
|
+
if not said:
|
|
517
|
+
return result
|
|
518
|
+
return replace(result, outcome=Outcome.FAILED,
|
|
519
|
+
detail=f"{slug} exited {result.exit_code} and wrote no output; it said: {said}")
|
|
520
|
+
|
|
521
|
+
|
|
503
522
|
def _merged_result(results: list[ToolResult], planned: int) -> ToolResult:
|
|
504
523
|
failed = next((r for r in results if not r.usable), None)
|
|
505
524
|
basis = failed or results[0]
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"""Code a change touches is held to a stricter bar (Decision 15).
|
|
2
|
+
|
|
3
|
+
A repository adopting a quality gate cannot fix every old long function
|
|
4
|
+
first, and a gate that fails on all of them is a gate nobody turns on.
|
|
5
|
+
`policy.changed_code` sets stricter function limits, and on a run against a
|
|
6
|
+
change only the functions that change touched are held to them; untouched
|
|
7
|
+
code is judged by the standard as before.
|
|
8
|
+
|
|
9
|
+
A function is *touched* when the change added or altered a line inside it —
|
|
10
|
+
`git diff --unified=0` lines, so context does not count and a pure deletion
|
|
11
|
+
touches nothing. Classes are not held to it: their budget is a container's,
|
|
12
|
+
and their methods are functions in their own right.
|
|
13
|
+
|
|
14
|
+
Two rules from the decision, enforced here rather than trusted:
|
|
15
|
+
|
|
16
|
+
- **A policy only tightens.** A limit looser than the standard threshold is
|
|
17
|
+
refused when the configuration loads, by name, as `PolicyError` — the
|
|
18
|
+
refusal both doors already turn into a message.
|
|
19
|
+
- **It never moves the grade.** Its result is `report["policy"]`, beside the
|
|
20
|
+
score rather than inside `hard_gate_failures`, which the scorer reads.
|
|
21
|
+
`--fail-on-gate` reads both.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
from typing import Any
|
|
27
|
+
|
|
28
|
+
from ._catalog import PolicyError
|
|
29
|
+
|
|
30
|
+
#: Each policy key: the standard threshold it may only tighten, the
|
|
31
|
+
#: function-metric field it reads, and the name a failure reports.
|
|
32
|
+
LIMITS: dict[str, tuple[str, str, str]] = {
|
|
33
|
+
"max_function_lines": ("max_function_lines", "lines", "function_lines"),
|
|
34
|
+
"max_complexity": ("max_complexity", "complexity", "complexity"),
|
|
35
|
+
"max_cognitive_complexity": ("max_cognitive_complexity", "cognitive", "cognitive_complexity"),
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def changed_code_limits(config: dict[str, Any]) -> dict[str, int]:
|
|
40
|
+
"""The configured limits, or empty when the repository sets none."""
|
|
41
|
+
return dict((config.get("policy") or {}).get("changed_code") or {})
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def validate(config: dict[str, Any]) -> None:
|
|
45
|
+
"""Refuse a limit that is unknown, not a positive integer, or looser than the standard."""
|
|
46
|
+
thresholds = config.get("thresholds") or {}
|
|
47
|
+
for key, value in changed_code_limits(config).items():
|
|
48
|
+
if key not in LIMITS:
|
|
49
|
+
raise PolicyError(
|
|
50
|
+
f"unknown policy.changed_code key {key!r}; expected one of {sorted(LIMITS)}")
|
|
51
|
+
if isinstance(value, bool) or not isinstance(value, int) or value < 1:
|
|
52
|
+
raise PolicyError(f"policy.changed_code.{key} must be a positive integer, not {value!r}")
|
|
53
|
+
standard = thresholds.get(LIMITS[key][0])
|
|
54
|
+
if isinstance(standard, int) and value > standard:
|
|
55
|
+
raise PolicyError(
|
|
56
|
+
f"policy.changed_code.{key} is {value}, looser than the standard "
|
|
57
|
+
f"thresholds.{LIMITS[key][0]} of {standard}; a policy may only tighten")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def evaluate(function_metrics: list[Any], touched_lines: dict[str, set[int]],
|
|
61
|
+
config: dict[str, Any], revspec: str) -> dict[str, Any] | None:
|
|
62
|
+
"""Every touched function's breaches of the policy, or None without a policy."""
|
|
63
|
+
limits = changed_code_limits(config)
|
|
64
|
+
if not limits:
|
|
65
|
+
return None
|
|
66
|
+
touched = [metric for metric in function_metrics if _touched(metric, touched_lines)]
|
|
67
|
+
return {
|
|
68
|
+
"revspec": revspec,
|
|
69
|
+
"limits": limits,
|
|
70
|
+
"touched_functions": len(touched),
|
|
71
|
+
"failures": [failure for metric in touched for failure in _breaches(metric, limits)],
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
def failures(report: dict[str, Any]) -> list[dict[str, Any]]:
|
|
76
|
+
"""The policy's failures in a finished report; empty when no policy ran."""
|
|
77
|
+
return list((report.get("policy") or {}).get("failures") or [])
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def _touched(metric: Any, touched_lines: dict[str, set[int]]) -> bool:
|
|
81
|
+
if getattr(metric, "kind", "function") == "class":
|
|
82
|
+
return False
|
|
83
|
+
lines = touched_lines.get(metric.path)
|
|
84
|
+
if not lines:
|
|
85
|
+
return False
|
|
86
|
+
end = metric.start_line + metric.lines
|
|
87
|
+
return any(metric.start_line <= line < end for line in lines)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _breaches(metric: Any, limits: dict[str, int]) -> list[dict[str, Any]]:
|
|
91
|
+
found = []
|
|
92
|
+
for key, limit in limits.items():
|
|
93
|
+
_standard, field, measure = LIMITS[key]
|
|
94
|
+
value = getattr(metric, field, None)
|
|
95
|
+
if isinstance(value, int) and value > limit:
|
|
96
|
+
found.append({"path": metric.path, "name": metric.name, "start_line": metric.start_line,
|
|
97
|
+
"measure": measure, "value": value, "limit": limit})
|
|
98
|
+
return found
|
{maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_gates.py
RENAMED
|
@@ -18,6 +18,7 @@ import argparse
|
|
|
18
18
|
import sys
|
|
19
19
|
from pathlib import Path
|
|
20
20
|
|
|
21
|
+
from ._changed_code_policy import failures as policy_failures
|
|
21
22
|
from .baseline import findings_not_in_baseline
|
|
22
23
|
from .git_tools import added_lines, changed_paths, removed_lines
|
|
23
24
|
|
|
@@ -147,7 +148,7 @@ def audit_exit_code(args: argparse.Namespace, report: dict) -> int:
|
|
|
147
148
|
root = Path(report["root"])
|
|
148
149
|
if findings_not_in_baseline(report, args.baseline, root):
|
|
149
150
|
return 1
|
|
150
|
-
if args.fail_on_gate and report["hard_gate_failures"]:
|
|
151
|
+
if args.fail_on_gate and (report["hard_gate_failures"] or policy_failures(report)):
|
|
151
152
|
return 1
|
|
152
153
|
conformance = _conformance_exit(args, report)
|
|
153
154
|
if conformance:
|
{maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_html_view.py
RENAMED
|
@@ -318,15 +318,36 @@ def _work_order_section(report: dict[str, Any]) -> list[str]:
|
|
|
318
318
|
|
|
319
319
|
def _hard_gate_section(report: dict[str, Any]) -> list[str]:
|
|
320
320
|
failures = report.get("hard_gate_failures") or []
|
|
321
|
+
rows: list[str] = []
|
|
322
|
+
if failures:
|
|
323
|
+
rows = [
|
|
324
|
+
"<h2>Hard gates</h2>",
|
|
325
|
+
"<table><tr><th>Severity</th><th>Gate</th></tr>",
|
|
326
|
+
]
|
|
327
|
+
rows.extend(
|
|
328
|
+
f"<tr><td class='sev-Severe'>Severe</td><td>{escape(str(gate))}</td></tr>"
|
|
329
|
+
for gate in failures
|
|
330
|
+
)
|
|
331
|
+
rows.append("</table>")
|
|
332
|
+
return rows + _policy_section(report)
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
def _policy_section(report: dict[str, Any]) -> list[str]:
|
|
336
|
+
"""The changed-code policy beside the gates, as the markdown prints it (Decision 15)."""
|
|
337
|
+
policy = report.get("policy")
|
|
338
|
+
failures = (policy or {}).get("failures") or []
|
|
321
339
|
if not failures:
|
|
322
340
|
return []
|
|
323
341
|
rows = [
|
|
324
|
-
"<h2>
|
|
325
|
-
"<
|
|
342
|
+
"<h2>Changed-code policy</h2>",
|
|
343
|
+
f"<p class='muted'>Functions touched by {escape(str(policy.get('revspec')))} are held to "
|
|
344
|
+
"this repository's stricter limits. The grade is unaffected.</p>",
|
|
345
|
+
"<table><tr><th>Location</th><th>Function</th><th>Measure</th><th>Value</th><th>Limit</th></tr>",
|
|
326
346
|
]
|
|
327
347
|
rows.extend(
|
|
328
|
-
f"<tr><td
|
|
329
|
-
|
|
348
|
+
f"<tr><td>{escape(str(f['path']))}:{f['start_line']}</td><td>{escape(str(f['name']))}</td>"
|
|
349
|
+
f"<td>{escape(str(f['measure']))}</td><td>{f['value']}</td><td>{f['limit']}</td></tr>"
|
|
350
|
+
for f in failures
|
|
330
351
|
)
|
|
331
352
|
rows.append("</table>")
|
|
332
353
|
return rows
|
{maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_audit.py
RENAMED
|
@@ -21,6 +21,7 @@ from typing import Any
|
|
|
21
21
|
|
|
22
22
|
from ._calibration import CALIBRATION_C
|
|
23
23
|
from ._catalog import PRESENTATIONS
|
|
24
|
+
from ._changed_code_policy import failures as policy_failures
|
|
24
25
|
from ._grant_ledger import (
|
|
25
26
|
ALLOWED_ROOTS_ENV as ALLOWED_ROOTS_ENV, # noqa: PLC0414 - re-export
|
|
26
27
|
)
|
|
@@ -396,7 +397,8 @@ def _top_level_result(report: dict[str, Any], root: Path, status: str,
|
|
|
396
397
|
"audit_ran": True,
|
|
397
398
|
"source_commit": probe_git(["rev-parse", "HEAD"], root) or None,
|
|
398
399
|
"worktree_dirty": bool(status),
|
|
399
|
-
|
|
400
|
+
# The changed-code policy is a gate too (Decision 15); the CLI reads both.
|
|
401
|
+
"gate_passed": not (report["hard_gate_failures"] or policy_failures(report)),
|
|
400
402
|
# Stated at the top level so a caller cannot mistake an audit that
|
|
401
403
|
# ran six built-in detectors for one that ran ten tools. Two
|
|
402
404
|
# reports with different coverage are not comparable (P8).
|
|
@@ -321,10 +321,12 @@ class CohesionAdapter(BaseAdapter):
|
|
|
321
321
|
super().__init__(
|
|
322
322
|
slug="cohesion", emits="metric", executable="cohesion",
|
|
323
323
|
concepts=("cohesion",), exclude_dialect="files",
|
|
324
|
-
# Its CLI takes files or a directory and has no version flag,
|
|
325
|
-
#
|
|
326
|
-
# arrangement multimetric
|
|
327
|
-
|
|
324
|
+
# Its CLI takes files or a directory and has no version flag, so
|
|
325
|
+
# the version comes from package metadata — and availability
|
|
326
|
+
# from `--help`, the arrangement multimetric uses. The probe was
|
|
327
|
+
# `--version`, which argparse rejects with exit 2, so cohesion
|
|
328
|
+
# was recorded as failed without ever being asked to run.
|
|
329
|
+
version_flag="--help", distribution="cohesion",
|
|
328
330
|
)
|
|
329
331
|
|
|
330
332
|
def has_targets(self, root: Path, excludes: Sequence[str] = ()) -> bool:
|
|
@@ -134,7 +134,10 @@ class InterrogateAdapter(BaseAdapter):
|
|
|
134
134
|
super().__init__(
|
|
135
135
|
slug="interrogate", emits="metric", executable="interrogate",
|
|
136
136
|
concepts=("documentation",), findings_exit_codes=(0, 1),
|
|
137
|
-
|
|
137
|
+
# One `--exclude` per path: interrogate names one location per
|
|
138
|
+
# flag, and a space-joined list named none, so excluded trees
|
|
139
|
+
# were analysed and one unparseable file in them crashed it.
|
|
140
|
+
exclude_flag="--exclude", exclude_repeat=True,
|
|
138
141
|
exclude_dialect="abspath",
|
|
139
142
|
)
|
|
140
143
|
|
{maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/config.py
RENAMED
|
@@ -7,6 +7,7 @@ from typing import Any
|
|
|
7
7
|
# Re-exported: the defaults live in `_config_defaults`, this module is
|
|
8
8
|
# still the door every caller comes through.
|
|
9
9
|
from . import __version__ as _package_version
|
|
10
|
+
from ._changed_code_policy import validate as validate_changed_code_policy
|
|
10
11
|
from ._config_defaults import DEFAULT_CONFIG, DEFAULT_IDIOM_GROUPS
|
|
11
12
|
from ._operator_reads import (
|
|
12
13
|
MAX_OPERATOR_FILE_BYTES as MAX_OPERATOR_FILE_BYTES,
|
|
@@ -164,6 +165,7 @@ def load_config(path: str | None) -> dict[str, Any]:
|
|
|
164
165
|
_merge_tier(config, user_tier)
|
|
165
166
|
if path:
|
|
166
167
|
_merge_tier(config, _host_authority_stripped(_configured(Path(path))))
|
|
168
|
+
validate_changed_code_policy(config)
|
|
167
169
|
return config
|
|
168
170
|
|
|
169
171
|
|
{maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/renderers.py
RENAMED
|
@@ -178,11 +178,32 @@ def render_markdown(report: dict[str, Any], *, complete: bool = True) -> str:
|
|
|
178
178
|
|
|
179
179
|
|
|
180
180
|
def _hard_gate_lines(report: dict[str, Any]) -> list[str]:
|
|
181
|
-
"""The hard-gate list, printed the same way wherever it appears.
|
|
182
|
-
|
|
181
|
+
"""The hard-gate list, printed the same way wherever it appears.
|
|
182
|
+
|
|
183
|
+
The changed-code policy follows it: also a gate, never a grade
|
|
184
|
+
(Decision 15), so it is printed wherever the gates are.
|
|
185
|
+
"""
|
|
186
|
+
lines: list[str] = []
|
|
187
|
+
if report["hard_gate_failures"]:
|
|
188
|
+
lines += ["## Hard Gate Failures", "",
|
|
189
|
+
*(f"- {gate}" for gate in report["hard_gate_failures"]), ""]
|
|
190
|
+
return lines + _policy_lines(report)
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
def _policy_lines(report: dict[str, Any]) -> list[str]:
|
|
194
|
+
policy = report.get("policy")
|
|
195
|
+
if not policy:
|
|
183
196
|
return []
|
|
184
|
-
|
|
185
|
-
|
|
197
|
+
failures = policy.get("failures") or []
|
|
198
|
+
head = (f"{policy.get('touched_functions', 0)} function(s) touched by "
|
|
199
|
+
f"`{policy.get('revspec')}` are held to this repository's stricter limits; "
|
|
200
|
+
"the grade is unaffected.")
|
|
201
|
+
if not failures:
|
|
202
|
+
return ["## Changed-code policy", "", head + " All of them meet it.", ""]
|
|
203
|
+
rows = [f"| `{f['path']}:{f['start_line']}` | `{f['name']}` | {f['measure']} | {f['value']} | {f['limit']} |"
|
|
204
|
+
for f in failures]
|
|
205
|
+
return ["## Changed-code policy", "", head, "",
|
|
206
|
+
"| Location | Function | Measure | Value | Limit |", "|---|---|---|---|---|", *rows, ""]
|
|
186
207
|
|
|
187
208
|
|
|
188
209
|
def _no_work_order_lines() -> list[str]:
|
{maintainability_agent-4.2.0 → maintainability_agent-4.3.0}/src/maintainability_audit/report.py
RENAMED
|
@@ -16,6 +16,8 @@ from typing import Any
|
|
|
16
16
|
|
|
17
17
|
from ._analyzer_sections import analyzer_sections
|
|
18
18
|
from ._built_ins import record_built_in_counts
|
|
19
|
+
from ._changed_code_policy import changed_code_limits
|
|
20
|
+
from ._changed_code_policy import evaluate as evaluate_changed_code_policy
|
|
19
21
|
from ._delegated_pillar import read_delegated
|
|
20
22
|
from ._discovery import Provenance, discover
|
|
21
23
|
from ._economics import economic_context_from, economic_impact, reorder_by_exposure
|
|
@@ -36,7 +38,7 @@ from .deadcode import dead_declarations
|
|
|
36
38
|
from .declarations import DECLARATION_SUFFIXES
|
|
37
39
|
from .duplication import duplicate_blocks, risk_findings
|
|
38
40
|
from .evidence import REPORT_SCHEMA_VERSION, SCHEMA_VERSION_KEY
|
|
39
|
-
from .git_tools import probe_git, worktree_status
|
|
41
|
+
from .git_tools import added_lines, probe_git, worktree_status
|
|
40
42
|
from .history import history_section
|
|
41
43
|
from .idioms import divergent_idioms
|
|
42
44
|
from .metrics import (
|
|
@@ -463,6 +465,32 @@ def _pillars_with_delegation(
|
|
|
463
465
|
return pillars
|
|
464
466
|
|
|
465
467
|
|
|
468
|
+
def _attach_economics(report: dict[str, Any], config: dict[str, Any]) -> None:
|
|
469
|
+
"""ADR 004 v1, after scoring on purpose.
|
|
470
|
+
|
|
471
|
+
Nothing money-shaped exists until the score document is final, so no
|
|
472
|
+
path from these numbers into the estimate or the grade can exist to be
|
|
473
|
+
misused.
|
|
474
|
+
"""
|
|
475
|
+
context = economic_context_from(config)
|
|
476
|
+
if context is not None:
|
|
477
|
+
report["economic_impact"] = economic_impact(report, context)
|
|
478
|
+
reorder_by_exposure(report)
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
def _attach_policy(report: dict[str, Any], root: Path, config: dict[str, Any],
|
|
482
|
+
function_metrics: list[FunctionMetric], changed_revspec: str | None) -> None:
|
|
483
|
+
"""The changed-code policy, beside the score and never inside it (Decision 15).
|
|
484
|
+
|
|
485
|
+
Only a repository that set a policy pays for the diff; without one
|
|
486
|
+
nothing new runs.
|
|
487
|
+
"""
|
|
488
|
+
if not (changed_revspec and changed_code_limits(config)):
|
|
489
|
+
return
|
|
490
|
+
touched = {path: {n for n, _ in rows} for path, rows in added_lines(root, changed_revspec).items()}
|
|
491
|
+
report["policy"] = evaluate_changed_code_policy(function_metrics, touched, config, changed_revspec)
|
|
492
|
+
|
|
493
|
+
|
|
466
494
|
def build_report(
|
|
467
495
|
root: Path,
|
|
468
496
|
config: dict[str, Any],
|
|
@@ -528,6 +556,7 @@ def build_report(
|
|
|
528
556
|
report["tdd_structure"] = describe_tdd(root, file_metrics, function_metrics, source)
|
|
529
557
|
_attach_test_suite(report, root, config)
|
|
530
558
|
report["score"] = score_report(report, analyzer["pressures"])
|
|
559
|
+
_attach_policy(report, root, config, function_metrics, changed_revspec)
|
|
531
560
|
# Condition rolls up aspects; practice stays a separate axis (ADR 007).
|
|
532
561
|
report["practice"] = practice_level(root, config).as_dict()
|
|
533
562
|
report["pillars"] = _pillars_with_delegation(report, root, security_pillar, changed_revspec, config)
|
|
@@ -535,11 +564,5 @@ def build_report(
|
|
|
535
564
|
# Last, because every item's delta is a rubric recomputation and the
|
|
536
565
|
# rubric needs the scored report to recompute against.
|
|
537
566
|
report["work_order"] = work_order(report, thresholds=config["thresholds"])
|
|
538
|
-
|
|
539
|
-
# until the score document is final, so no path from these numbers
|
|
540
|
-
# into the estimate or the grade can exist to be misused.
|
|
541
|
-
context = economic_context_from(config)
|
|
542
|
-
if context is not None:
|
|
543
|
-
report["economic_impact"] = economic_impact(report, context)
|
|
544
|
-
reorder_by_exposure(report)
|
|
567
|
+
_attach_economics(report, config)
|
|
545
568
|
return report
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""D226's fixes, against the installed tools.
|
|
2
|
+
|
|
3
|
+
Covers existing behaviour: these run the real interrogate and cohesion and
|
|
4
|
+
skip where a tool is not installed, so in an environment without them they
|
|
5
|
+
pass without proving anything. The falsifiers for the same changes are in
|
|
6
|
+
`test_analyzers_report_what_actually_failed.py` and need no tool; these
|
|
7
|
+
check that the fixes hold against the tools themselves.
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
import shutil
|
|
13
|
+
import subprocess
|
|
14
|
+
from pathlib import Path
|
|
15
|
+
from types import SimpleNamespace
|
|
16
|
+
|
|
17
|
+
import pytest
|
|
18
|
+
|
|
19
|
+
from maintainability_audit import _analysis
|
|
20
|
+
from maintainability_audit._runner import Outcome
|
|
21
|
+
from maintainability_audit._tool_adapters import ADAPTERS
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@pytest.mark.skipif(shutil.which("cohesion") is None, reason="cohesion is not installed here")
|
|
25
|
+
def test_cohesions_availability_probe_is_a_flag_it_has() -> None:
|
|
26
|
+
probe = subprocess.run(list(ADAPTERS["cohesion"]().version_argv()), capture_output=True, text=True)
|
|
27
|
+
|
|
28
|
+
assert probe.returncode == 0, probe.stderr
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.mark.skipif(shutil.which("interrogate") is None, reason="interrogate is not installed here")
|
|
32
|
+
def test_an_excluded_unparseable_file_no_longer_hides_the_percentage(tmp_path: Path) -> None:
|
|
33
|
+
(tmp_path / "app.py").write_text('"""Documented."""\n\n\ndef f():\n """Yes."""\n', encoding="utf-8")
|
|
34
|
+
(tmp_path / "vendor_corpus").mkdir()
|
|
35
|
+
(tmp_path / "vendor_corpus" / "old.py").write_text('print "python 2"\n', encoding="utf-8")
|
|
36
|
+
probe = SimpleNamespace(check=lambda slug, argv: SimpleNamespace(
|
|
37
|
+
usable=True, version="interrogate", outcome=Outcome.RAN, detail=""))
|
|
38
|
+
|
|
39
|
+
coverage = _analysis._attempt(tmp_path, ADAPTERS["interrogate"](), probe, 60, _analysis.Analysis(),
|
|
40
|
+
("vendor_corpus/",))
|
|
41
|
+
|
|
42
|
+
assert coverage.outcome == "ran" and coverage.measurements == 1, coverage.detail or coverage.parse_error
|