maintainability-agent 4.1.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.1.0/src/maintainability_agent.egg-info → maintainability_agent-4.3.0}/PKG-INFO +17 -4
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/README.md +16 -3
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0/src/maintainability_agent.egg-info}/PKG-INFO +17 -4
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/SOURCES.txt +7 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_adapters.py +46 -1
- {maintainability_agent-4.1.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.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_gates.py +2 -1
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_html_view.py +25 -4
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_audit.py +3 -1
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_metric_adapters.py +6 -4
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_operator_reads.py +3 -1
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ratio_adapters.py +4 -1
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/config.py +21 -2
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/renderers.py +25 -4
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/report.py +31 -8
- maintainability_agent-4.3.0/tests/test_a_rendered_docs_site_is_not_scored_as_source.py +61 -0
- 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.3.0/tests/test_exclude_additional_keeps_the_defaults.py +53 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_readme_claims.py +16 -0
- maintainability_agent-4.3.0/tests/test_regular_file_reads_work_without_o_nonblock.py +28 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/LICENSE +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/pyproject.toml +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/setup.cfg +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/requires.txt +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_analyzer_sections.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_anchor.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_banner.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_catalog.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_cognitive.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_coverage_notes.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_criteria_scope.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_delegated_pillar.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_evidence_reader.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_first_run.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_grammar.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_handoff.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_in_loop.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_in_loop_view.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_jvm_adapters.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_mcp_setup.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_oracle.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_precommit.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_precommit_install.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_precommit_view.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_prompt_sections.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_cobol.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_go.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_kotlin.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_php.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_ruby.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_rust.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_shell.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_running_version.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_security_delegate.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_security_work_order.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_setup_persist.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_verdict_adapters.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/cli.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/mcp_server.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/prompts.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_a_clone_names_every_copy.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_a_dangling_source_link_is_named_not_fatal.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_a_format_override_is_disclosed.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_a_matching_format_stays_silent.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_a_published_question_offers_what_it_accepts.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_a_setup_question_keeps_its_contract.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_adapters.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_added_lines.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_an_absent_work_order_renders_nothing.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_an_unmeasured_pillar_reports_no_number.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_file_lists_are_batched.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_anchor_and_mode.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_anchor_disclosure.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_architecture.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_attestation.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_audit_components.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_backfill.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_bands.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_behaviour_suites_are_tests.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_both_setup_paths_ask_the_same_stage.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_chat_leads_with_the_work_order.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_check_refuses_plus_only_fragments.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_child_sandbox.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_clean_sees_the_weakened_oracle.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_cli.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_code_scanning_gets_alerts_not_the_record.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_cohesion_with_nothing_to_read_is_not_applicable.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_config_shape.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_conformance_reads_the_operators_ask.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_consent_is_per_repository.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_consent_survives_setup_and_is_asked.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_consent_without_command_has_a_remedy.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_corpus_note_counts_come_from_the_corpus.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_corroborate.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_coverage_config_reaches_children.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_coverage_formats.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_criteria_completion.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_current_state_docs_name_every_parsed_language.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_dead_code.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_declaration_criteria_scope.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_declarative_parsers.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_declared_capabilities_match_the_delegate.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_delegated_security_pillar.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_demo_tree.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_determinism.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_discovery.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_docs_links.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_economic_context.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_every_built_presentation_is_offered.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_every_language_counts_its_own_loop.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_every_language_has_a_loop_fixture.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_every_pool_install_is_the_same_pool.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_every_question_can_be_answered.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_every_surface_says_what_the_run_found.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_example_config_opens_claimed_languages.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_exposure_never_outranks_band.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_first_run_elicitation.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_first_stage_setup_wording_holds.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_format_ask.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_git_argv.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_go_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_grammar_constructs.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_grammar_token_coverage.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_grok_audit_of_3_11.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_history.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_history_window.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_html_executive.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_in_loop_budgets.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_in_loop_check.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_java_scored.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_kotlin_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_kotlin_metrics.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_language_support_honesty.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_list_tools_publishes_the_answer_path.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_maintenance_signals.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_mcp_format_contract.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_mcp_start_failure_names_what_is_installed.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_missing_security_scanners_are_named_before_the_run.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_mutation_recorded.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_operator_named_paths.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_operator_named_reads.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_oracle_weakening_precision_bar.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_pairing_reads_imports.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_php_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_platform_claim.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_policy_claims.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_population_floors.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_precommit_staged.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_preflight_before_consent_runs_nothing_from_the_tree.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_previous_release_reached_pypi.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_promises.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_python_complexity.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_recurrence.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_release_needs_an_empty_ledger.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_release_plan.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_rendered_docs.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_root_grants.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_ruby_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_runner.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_rust_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_sarif.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_scan_history.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_scanner_fingerprint_covers_the_measurement_path.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_scanner_unsafe_direction.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_scanning.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_security_delegate_versions_agree.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_security_findings_keep_their_handoff.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_security_pillar_asserts_a_scanner_set.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_security_pillar_runs_and_shows.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_selection_covers_every_parsed_language.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_semantic_findings_stay_inside_the_audited_files.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_setup_answers_are_the_same_setup.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_setup_instruction_describes_its_own_reply.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_setup_writes_a_valid_config.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_shell_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_shell_metrics.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_skill_install.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_sonar_resolve.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_source_index.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_stamped_documents_stay_honest.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_stdout_outputs.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_terminal_asks_the_same_questions.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_test_commands.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_agent_knows_when_it_is_stale.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_changelog_covers_the_shipping_version.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_chat_payload_has_a_budget.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_condition_says_what_it_measured.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_handoff_rules_are_their_own_module.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_pillar_row_reads_cleanly.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_presentation_question_stays_answerable.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_previous_release_was_tagged.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_prompt_does_not_take_back_what_it_withheld.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_prompt_keeps_listing_what_it_did_not_withhold.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_release_process_describes_itself.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_release_record_stays_well_formed.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_report_is_saved_not_sent.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_security_run_has_a_configurable_limit.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_security_work_order_is_drawn.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_suite_names_the_program_it_ran.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_tree_cannot_redirect_a_read.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_the_version_has_one_source.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_tool_resolution.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_tree_chosen_spawn.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_tree_reads_use_the_primitive.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_trends.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_unanchored_set_matches_corpus.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_unread_code.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_version_claim.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_version_stamping.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_withheld_work_keeps_its_boundary.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_work_items_state_their_own_finding.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_work_order.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-4.1.0 → maintainability_agent-4.3.0}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-4.1.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
|
>
|
|
@@ -56,6 +56,11 @@ Version **4.1.0**.
|
|
|
56
56
|
> taste, each pinned to the exact commit it was measured at, so anyone can
|
|
57
57
|
> re-run the calibration and get the same numbers. The median of that corpus
|
|
58
58
|
> scores a **B**. [How the corpus is chosen and measured](docs/standard.md#the-reference-corpus).
|
|
59
|
+
>
|
|
60
|
+
> So your grade places your code against those 201: a **B** means you are at
|
|
61
|
+
> the median of mature, widely used open source. The corpus is re-measured
|
|
62
|
+
> whenever the instrument changes — in 4.1.0 every file of even the largest
|
|
63
|
+
> repositories was read, and the scale came back unchanged to four decimals.
|
|
59
64
|
|
|
60
65
|
**Languages parsed:** Python, Java, Kotlin, C, C++, C#, Go, Rust, PHP, Ruby,
|
|
61
66
|
Swift, Shell, COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -93,7 +98,10 @@ you what it could not measure.
|
|
|
93
98
|
**Install secure-code-agent for the security pillar.** Every audit runs it; it is
|
|
94
99
|
installed alongside rather than as a dependency, so the two tools release
|
|
95
100
|
independently. Without it the report says the security pillar was not measured
|
|
96
|
-
and gives this command.
|
|
101
|
+
and gives this command. A full security run can take several minutes on a
|
|
102
|
+
large repository; the audit waits up to 15 minutes for it, and
|
|
103
|
+
`security.timeout_seconds` in `maintainability-agent.json` changes that. Its
|
|
104
|
+
scanners decide what it can grade — see
|
|
97
105
|
[machine setup](docs/machine-setup.md#3-toolchain) for which to install, and
|
|
98
106
|
don't add its `[mcp]` extra to this environment (it pins `mcp<2`).
|
|
99
107
|
|
|
@@ -356,6 +364,11 @@ signals on:
|
|
|
356
364
|
- an ISO/IEC 25010-inspired 0–5 estimate per category, and a verified grade —
|
|
357
365
|
or a disclosed withholding when the evidence is thin.
|
|
358
366
|
|
|
367
|
+
**Large repositories are measured whole.** Every file is handed to the
|
|
368
|
+
analyzers, split across as many runs as the command line needs, so a big
|
|
369
|
+
codebase is read rather than sampled — FFmpeg's 4,687 files, not the first
|
|
370
|
+
1,543 that fitted on one command line before 4.1.0.
|
|
371
|
+
|
|
359
372
|
The analyzer is intentionally conservative and under-reports rather than
|
|
360
373
|
over-reports: an unrecognized declaration costs one missed finding, never a
|
|
361
374
|
cascade of false ones. Pair it with native tools (ESLint, Ruff, Radon, Semgrep,
|
|
@@ -496,7 +509,7 @@ instead of an invokable skill:
|
|
|
496
509
|
This repo ships `action.yml`, usable as a composite action:
|
|
497
510
|
|
|
498
511
|
```yaml
|
|
499
|
-
- uses: marshallguillory86/maintainability-agent@v4.
|
|
512
|
+
- uses: marshallguillory86/maintainability-agent@v4.3.0
|
|
500
513
|
with:
|
|
501
514
|
config: maintainability-agent.json
|
|
502
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
|
>
|
|
@@ -14,6 +14,11 @@ Version **4.1.0**.
|
|
|
14
14
|
> taste, each pinned to the exact commit it was measured at, so anyone can
|
|
15
15
|
> re-run the calibration and get the same numbers. The median of that corpus
|
|
16
16
|
> scores a **B**. [How the corpus is chosen and measured](docs/standard.md#the-reference-corpus).
|
|
17
|
+
>
|
|
18
|
+
> So your grade places your code against those 201: a **B** means you are at
|
|
19
|
+
> the median of mature, widely used open source. The corpus is re-measured
|
|
20
|
+
> whenever the instrument changes — in 4.1.0 every file of even the largest
|
|
21
|
+
> repositories was read, and the scale came back unchanged to four decimals.
|
|
17
22
|
|
|
18
23
|
**Languages parsed:** Python, Java, Kotlin, C, C++, C#, Go, Rust, PHP, Ruby,
|
|
19
24
|
Swift, Shell, COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -51,7 +56,10 @@ you what it could not measure.
|
|
|
51
56
|
**Install secure-code-agent for the security pillar.** Every audit runs it; it is
|
|
52
57
|
installed alongside rather than as a dependency, so the two tools release
|
|
53
58
|
independently. Without it the report says the security pillar was not measured
|
|
54
|
-
and gives this command.
|
|
59
|
+
and gives this command. A full security run can take several minutes on a
|
|
60
|
+
large repository; the audit waits up to 15 minutes for it, and
|
|
61
|
+
`security.timeout_seconds` in `maintainability-agent.json` changes that. Its
|
|
62
|
+
scanners decide what it can grade — see
|
|
55
63
|
[machine setup](docs/machine-setup.md#3-toolchain) for which to install, and
|
|
56
64
|
don't add its `[mcp]` extra to this environment (it pins `mcp<2`).
|
|
57
65
|
|
|
@@ -314,6 +322,11 @@ signals on:
|
|
|
314
322
|
- an ISO/IEC 25010-inspired 0–5 estimate per category, and a verified grade —
|
|
315
323
|
or a disclosed withholding when the evidence is thin.
|
|
316
324
|
|
|
325
|
+
**Large repositories are measured whole.** Every file is handed to the
|
|
326
|
+
analyzers, split across as many runs as the command line needs, so a big
|
|
327
|
+
codebase is read rather than sampled — FFmpeg's 4,687 files, not the first
|
|
328
|
+
1,543 that fitted on one command line before 4.1.0.
|
|
329
|
+
|
|
317
330
|
The analyzer is intentionally conservative and under-reports rather than
|
|
318
331
|
over-reports: an unrecognized declaration costs one missed finding, never a
|
|
319
332
|
cascade of false ones. Pair it with native tools (ESLint, Ruff, Radon, Semgrep,
|
|
@@ -454,7 +467,7 @@ instead of an invokable skill:
|
|
|
454
467
|
This repo ships `action.yml`, usable as a composite action:
|
|
455
468
|
|
|
456
469
|
```yaml
|
|
457
|
-
- uses: marshallguillory86/maintainability-agent@v4.
|
|
470
|
+
- uses: marshallguillory86/maintainability-agent@v4.3.0
|
|
458
471
|
with:
|
|
459
472
|
config: maintainability-agent.json
|
|
460
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
|
>
|
|
@@ -56,6 +56,11 @@ Version **4.1.0**.
|
|
|
56
56
|
> taste, each pinned to the exact commit it was measured at, so anyone can
|
|
57
57
|
> re-run the calibration and get the same numbers. The median of that corpus
|
|
58
58
|
> scores a **B**. [How the corpus is chosen and measured](docs/standard.md#the-reference-corpus).
|
|
59
|
+
>
|
|
60
|
+
> So your grade places your code against those 201: a **B** means you are at
|
|
61
|
+
> the median of mature, widely used open source. The corpus is re-measured
|
|
62
|
+
> whenever the instrument changes — in 4.1.0 every file of even the largest
|
|
63
|
+
> repositories was read, and the scale came back unchanged to four decimals.
|
|
59
64
|
|
|
60
65
|
**Languages parsed:** Python, Java, Kotlin, C, C++, C#, Go, Rust, PHP, Ruby,
|
|
61
66
|
Swift, Shell, COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -93,7 +98,10 @@ you what it could not measure.
|
|
|
93
98
|
**Install secure-code-agent for the security pillar.** Every audit runs it; it is
|
|
94
99
|
installed alongside rather than as a dependency, so the two tools release
|
|
95
100
|
independently. Without it the report says the security pillar was not measured
|
|
96
|
-
and gives this command.
|
|
101
|
+
and gives this command. A full security run can take several minutes on a
|
|
102
|
+
large repository; the audit waits up to 15 minutes for it, and
|
|
103
|
+
`security.timeout_seconds` in `maintainability-agent.json` changes that. Its
|
|
104
|
+
scanners decide what it can grade — see
|
|
97
105
|
[machine setup](docs/machine-setup.md#3-toolchain) for which to install, and
|
|
98
106
|
don't add its `[mcp]` extra to this environment (it pins `mcp<2`).
|
|
99
107
|
|
|
@@ -356,6 +364,11 @@ signals on:
|
|
|
356
364
|
- an ISO/IEC 25010-inspired 0–5 estimate per category, and a verified grade —
|
|
357
365
|
or a disclosed withholding when the evidence is thin.
|
|
358
366
|
|
|
367
|
+
**Large repositories are measured whole.** Every file is handed to the
|
|
368
|
+
analyzers, split across as many runs as the command line needs, so a big
|
|
369
|
+
codebase is read rather than sampled — FFmpeg's 4,687 files, not the first
|
|
370
|
+
1,543 that fitted on one command line before 4.1.0.
|
|
371
|
+
|
|
359
372
|
The analyzer is intentionally conservative and under-reports rather than
|
|
360
373
|
over-reports: an unrecognized declaration costs one missed finding, never a
|
|
361
374
|
cascade of false ones. Pair it with native tools (ESLint, Ruff, Radon, Semgrep,
|
|
@@ -496,7 +509,7 @@ instead of an invokable skill:
|
|
|
496
509
|
This repo ships `action.yml`, usable as a composite action:
|
|
497
510
|
|
|
498
511
|
```yaml
|
|
499
|
-
- uses: marshallguillory86/maintainability-agent@v4.
|
|
512
|
+
- uses: marshallguillory86/maintainability-agent@v4.3.0
|
|
500
513
|
with:
|
|
501
514
|
config: maintainability-agent.json
|
|
502
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
|
|
@@ -157,6 +158,7 @@ tests/test_a_dangling_source_link_is_named_not_fatal.py
|
|
|
157
158
|
tests/test_a_format_override_is_disclosed.py
|
|
158
159
|
tests/test_a_matching_format_stays_silent.py
|
|
159
160
|
tests/test_a_published_question_offers_what_it_accepts.py
|
|
161
|
+
tests/test_a_rendered_docs_site_is_not_scored_as_source.py
|
|
160
162
|
tests/test_a_setup_question_keeps_its_contract.py
|
|
161
163
|
tests/test_acquisition_trust.py
|
|
162
164
|
tests/test_adapter_docs.py
|
|
@@ -178,6 +180,8 @@ tests/test_analyzer_provenance_exclusions.py
|
|
|
178
180
|
tests/test_analyzer_scoring_path.py
|
|
179
181
|
tests/test_analyzer_spread_range.py
|
|
180
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
|
|
181
185
|
tests/test_anchor_and_mode.py
|
|
182
186
|
tests/test_anchor_caveat_and_counts_follow_the_run.py
|
|
183
187
|
tests/test_anchor_disclosure.py
|
|
@@ -207,6 +211,7 @@ tests/test_calibration_drift.py
|
|
|
207
211
|
tests/test_calibration_tooling.py
|
|
208
212
|
tests/test_catalog_selection.py
|
|
209
213
|
tests/test_catalog_tier_promise.py
|
|
214
|
+
tests/test_changed_code_policy.py
|
|
210
215
|
tests/test_chat_leads_with_the_work_order.py
|
|
211
216
|
tests/test_chat_primary_docs.py
|
|
212
217
|
tests/test_check_refuses_plus_only_fragments.py
|
|
@@ -276,6 +281,7 @@ tests/test_evidence_invariants.py
|
|
|
276
281
|
tests/test_evidence_normalization.py
|
|
277
282
|
tests/test_evidence_properties.py
|
|
278
283
|
tests/test_example_config_opens_claimed_languages.py
|
|
284
|
+
tests/test_exclude_additional_keeps_the_defaults.py
|
|
279
285
|
tests/test_exclusion_dialects.py
|
|
280
286
|
tests/test_exposure_never_outranks_band.py
|
|
281
287
|
tests/test_falsifier_standard.py
|
|
@@ -367,6 +373,7 @@ tests/test_python_declarations.py
|
|
|
367
373
|
tests/test_read_boundary.py
|
|
368
374
|
tests/test_readme_claims.py
|
|
369
375
|
tests/test_recurrence.py
|
|
376
|
+
tests/test_regular_file_reads_work_without_o_nonblock.py
|
|
370
377
|
tests/test_release_needs_an_empty_ledger.py
|
|
371
378
|
tests/test_release_plan.py
|
|
372
379
|
tests/test_release_plan_status.py
|
{maintainability_agent-4.1.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.1.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.1.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.1.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.1.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:
|
|
@@ -55,7 +55,9 @@ def open_regular_file(path: Path, why: str) -> int:
|
|
|
55
55
|
"""
|
|
56
56
|
import stat as stat_module
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
# Windows has no `O_NONBLOCK` and no POSIX FIFO in the tree to guard
|
|
59
|
+
# against; using the flag unconditionally killed every read there.
|
|
60
|
+
handle = os.open(path, os.O_RDONLY | getattr(os, "O_NONBLOCK", 0))
|
|
59
61
|
if not stat_module.S_ISREG(os.fstat(handle).st_mode):
|
|
60
62
|
os.close(handle)
|
|
61
63
|
raise PathNotAllowed(f"{path} is not a regular file. {why}")
|
|
@@ -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.1.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,
|
|
@@ -161,12 +162,30 @@ def load_config(path: str | None) -> dict[str, Any]:
|
|
|
161
162
|
return config
|
|
162
163
|
config["analyzers"]["run"] = True
|
|
163
164
|
if user_tier is not None:
|
|
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
|
|
|
172
|
+
def _merge_tier(config: dict[str, Any], tier: dict[str, Any]) -> None:
|
|
173
|
+
"""One tier over the ones before it, with `exclude_additional` appended.
|
|
174
|
+
|
|
175
|
+
`deep_update` replaces lists, so setting `paths.exclude_patterns` to add
|
|
176
|
+
one directory discarded every default exclusion and froze a copy that
|
|
177
|
+
drifts on the next release (#292). `exclude_additional` adds to whatever
|
|
178
|
+
the earlier tiers produced instead, so a repository can add without
|
|
179
|
+
restating.
|
|
180
|
+
"""
|
|
181
|
+
added = list((tier.get("paths") or {}).get("exclude_additional") or [])
|
|
182
|
+
deep_update(config, tier)
|
|
183
|
+
paths = config["paths"]
|
|
184
|
+
paths.pop("exclude_additional", None)
|
|
185
|
+
paths["exclude_patterns"] = [*paths["exclude_patterns"],
|
|
186
|
+
*(p for p in added if p not in paths["exclude_patterns"])]
|
|
187
|
+
|
|
188
|
+
|
|
170
189
|
#: The one key a repository may state and this tool will not act on,
|
|
171
190
|
#: because acting on it runs a program of the tree's choosing on the host.
|
|
172
191
|
#: The whole leaf is dropped, not merged.
|
{maintainability_agent-4.1.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]:
|