maintainability-agent 3.3.0__tar.gz → 3.5.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-3.3.0/src/maintainability_agent.egg-info → maintainability_agent-3.5.0}/PKG-INFO +59 -25
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/README.md +57 -24
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/pyproject.toml +2 -2
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0/src/maintainability_agent.egg-info}/PKG-INFO +59 -25
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_agent.egg-info/SOURCES.txt +3 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_agent.egg-info/requires.txt +1 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_prompt_sections.py +15 -1
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_scan_history.py +37 -14
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_work_order.py +74 -2
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/cli.py +71 -10
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/config.py +1 -1
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/mcp_server.py +7 -3
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/metrics.py +60 -2
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/renderers.py +49 -13
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_backfill.py +1 -1
- maintainability_agent-3.5.0/tests/test_chat_leads_with_the_work_order.py +171 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_child_sandbox.py +1 -1
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_ci_installs_the_analyzer_pool.py +48 -0
- maintainability_agent-3.5.0/tests/test_demo_tree.py +172 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_determinism.py +1 -1
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_dimension_ratchet.py +1 -1
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_finding_identity.py +56 -0
- maintainability_agent-3.5.0/tests/test_mcp_format_contract.py +81 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_operator_named_reads.py +143 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_platform_claim.py +9 -1
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_prove_falsifiers.py +59 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_recurrence.py +1 -1
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_run_comparison.py +9 -3
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_scan_history.py +54 -4
- maintainability_agent-3.5.0/tests/test_stdout_outputs.py +130 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_trends.py +1 -1
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_write_boundary.py +1 -1
- maintainability_agent-3.3.0/tests/test_mcp_format_contract.py +0 -22
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/LICENSE +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/setup.cfg +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_adapters.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_analysis.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_analyzer_sections.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_anchor.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_banner.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_catalog.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_cognitive.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_coverage_notes.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_criteria_scope.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_delegated_pillar.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_evidence_reader.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_first_run.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_gates.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_grammar.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_html_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_in_loop.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_in_loop_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_jvm_adapters.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_mcp_audit.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_mcp_setup.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_metric_adapters.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_operator_reads.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_precommit.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_precommit_install.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_precommit_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_cobol.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_go.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_php.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_ruby.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_rust.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_ratio_adapters.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_setup_persist.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_verdict_adapters.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/prompts.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/report.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_adapters.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_added_lines.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_anchor_and_mode.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_anchor_disclosure.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_architecture.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_attestation.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_audit_components.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_bands.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_check_refuses_plus_only_fragments.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_cli.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_config_shape.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_corroborate.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_criteria_completion.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_dead_code.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_declaration_criteria_scope.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_declarative_parsers.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_declared_authorship.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_delegated_security_pillar.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_discovery.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_docs_links.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_economic_context.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_first_run_elicitation.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_format_ask.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_git_argv.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_go_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_grammar_constructs.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_grammar_token_coverage.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_history.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_history_window.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_html_executive.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_in_loop_budgets.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_in_loop_check.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_java_scored.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_language_support_honesty.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_operator_named_paths.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_pairing_reads_imports.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_php_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_policy_claims.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_population_floors.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_precommit_staged.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_promises.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_python_complexity.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_readme_claims.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_release_needs_an_empty_ledger.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_release_plan.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_roles_recorded.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_root_grants.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_ruby_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_runner.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_rust_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_sarif.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_scanner_unsafe_direction.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_scanning.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_skill_install.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_sonar_resolve.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_source_index.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_terminal_asks_the_same_questions.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_test_commands.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_tool_resolution.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_tree_chosen_spawn.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_tree_reads_use_the_primitive.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_unanchored_set_matches_corpus.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_unread_code.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_version_claim.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_work_order.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-3.3.0 → maintainability_agent-3.5.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: 3.
|
|
3
|
+
Version: 3.5.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -29,6 +29,7 @@ Requires-Dist: mcp<3,>=2; extra == "mcp"
|
|
|
29
29
|
Provides-Extra: dev
|
|
30
30
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
31
|
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-xdist>=3.6; extra == "dev"
|
|
32
33
|
Requires-Dist: jsonschema>=4; extra == "dev"
|
|
33
34
|
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
34
35
|
Requires-Dist: pip-audit>=2.7; extra == "dev"
|
|
@@ -45,12 +46,7 @@ Dynamic: license-file
|
|
|
45
46
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
46
47
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
47
48
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
48
|
-
Version **3.
|
|
49
|
-
|
|
50
|
-
**Planned, not shipped:** the audit tool will become `maintainability-audit`;
|
|
51
|
-
a new `maintainability-agent` companion will run it and automate human-selected
|
|
52
|
-
work orders within the user's agent chat. The installation commands below
|
|
53
|
-
still describe the current product. See the [planned split](docs/product-intent.md#planned-product-split-and-companion-workflow).
|
|
49
|
+
Version **3.5.0**.
|
|
54
50
|
|
|
55
51
|
**Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
|
|
56
52
|
COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -65,6 +61,51 @@ pip install "maintainability-agent[mcp]" # optional local MCP server for chat
|
|
|
65
61
|
cp -r skills/maintainability-agent ~/.claude/skills/ # Claude Code slash command
|
|
66
62
|
```
|
|
67
63
|
|
|
64
|
+
**Install the analyzer pool too, or you get the built-in tier.** This tool
|
|
65
|
+
prefers established analyzers and falls back to its own detectors when none is
|
|
66
|
+
present. The fallback is honest — the report says `Estimate source: built-in
|
|
67
|
+
detectors` and the coverage section names what nothing examined — but it is a
|
|
68
|
+
weaker reading than the tool is capable of, and a first run without these is
|
|
69
|
+
the commonest reason it looks thin.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install cohesion complexipy flake8 fortitude-lint interrogate lizard \
|
|
73
|
+
multimetric mypy pydocstyle pylint radon ruff vulture
|
|
74
|
+
npm install -g jscpd eslint # duplication + JavaScript/TypeScript
|
|
75
|
+
brew install pmd checkstyle spotbugs # JVM languages, optional
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Unpinned on purpose: this is the exact set CI installs and calibrates against,
|
|
79
|
+
and `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
|
|
80
|
+
disagree. Nothing here is required — the audit runs without any of it and tells
|
|
81
|
+
you what it could not measure.
|
|
82
|
+
|
|
83
|
+
**One command to a work order.** A config file is the whole setup — with one
|
|
84
|
+
present, nothing is asked and nothing is written into your tree:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
curl -O https://raw.githubusercontent.com/marshallguillory86/maintainability-agent/main/maintainability-audit.example.json
|
|
88
|
+
maintainability-audit --config maintainability-audit.example.json \
|
|
89
|
+
--output report.md --prompt-output prompt.md
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`prompt.md` is the bounded work order: the findings worth fixing, in order,
|
|
93
|
+
each with its location, why it matters and the command that verifies it — and
|
|
94
|
+
the standing rule that nothing else gets refactored. Paste it into your agent.
|
|
95
|
+
`report.md` is the evidence behind it. The prompt is the product.
|
|
96
|
+
|
|
97
|
+
**Want to see the output before pointing it at your own code?**
|
|
98
|
+
[`examples/demo`](examples/demo/) is a two-module order system with real
|
|
99
|
+
problems in it — an overgrown pricing function, a money path nothing tests, and
|
|
100
|
+
a block duplicated between billing and invoicing. Four items, three finding
|
|
101
|
+
classes, a copy-paste prompt each, and it reads in under a minute. The work
|
|
102
|
+
order it produces is checked in at
|
|
103
|
+
[`expected-prompt.md`](examples/demo/expected-prompt.md).
|
|
104
|
+
|
|
105
|
+
Without `--config`, an interactive run asks the first-run questions instead —
|
|
106
|
+
analyzer pool, depth, licence policy, whether to run your suite — because those
|
|
107
|
+
are choices this tool will not make on your behalf.
|
|
108
|
+
|
|
68
109
|
---
|
|
69
110
|
|
|
70
111
|
## Executive summary
|
|
@@ -128,15 +169,6 @@ The full argument, including what this deliberately does not compete on:
|
|
|
128
169
|
[why this exists](docs/why-this-exists.md) and
|
|
129
170
|
[philosophy](docs/philosophy.md).
|
|
130
171
|
|
|
131
|
-
## The road to 1.0
|
|
132
|
-
|
|
133
|
-
1.0 was the line drawn under a long arc of **subtraction** — what remained after
|
|
134
|
-
every claim the project could not stand behind was removed. A scoring engine
|
|
135
|
-
rebuilt after it was found to grade repo *size*; a headline claim about AI
|
|
136
|
-
authorship retracted against a matched control; a score that is withheld rather
|
|
137
|
-
than guessed. That arc is the credibility, and it is recorded in full, with the
|
|
138
|
-
figures quoted from their approved summaries, in [the track record](docs/track-record.md).
|
|
139
|
-
|
|
140
172
|
## Install
|
|
141
173
|
|
|
142
174
|
```bash
|
|
@@ -380,19 +412,21 @@ it was generated against — a provenance record, not a claim about HEAD.
|
|
|
380
412
|
|
|
381
413
|
| Metric | Value |
|
|
382
414
|
|---|---:|
|
|
383
|
-
| Maintainability estimate | 4.
|
|
415
|
+
| Maintainability estimate | 4.5 / 5 |
|
|
384
416
|
| Verified grade | B |
|
|
385
|
-
| Files scanned |
|
|
417
|
+
| Files scanned | 511 |
|
|
386
418
|
| Hard gate failures | 0 |
|
|
387
419
|
|
|
388
420
|
A **B**, and the report says why: the grade is verified against the evidence
|
|
389
|
-
*floor* of 4.
|
|
390
|
-
prices at 0 when a grade has to be defended
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
421
|
+
*floor* of 4.2 rather than the 4.5 point estimate, because an unmeasured aspect
|
|
422
|
+
prices at 0 when a grade has to be defended. Every threshold gate is opted
|
|
423
|
+
**on** for this repository's own CI, so drifting below the bar fails the build
|
|
424
|
+
rather than the README.
|
|
425
|
+
|
|
426
|
+
The tool reports warn-band declarations here and they are not treated as
|
|
427
|
+
defects — see [what counts as a defect](docs/product-intent.md#what-counts-as-a-defect-and-what-does-not).
|
|
428
|
+
Restyling this codebase to raise its own grade is explicitly not work: a tool
|
|
429
|
+
that games its own metric has broken the only promise that matters.
|
|
396
430
|
|
|
397
431
|
## Platform support
|
|
398
432
|
|
|
@@ -5,12 +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 **3.
|
|
9
|
-
|
|
10
|
-
**Planned, not shipped:** the audit tool will become `maintainability-audit`;
|
|
11
|
-
a new `maintainability-agent` companion will run it and automate human-selected
|
|
12
|
-
work orders within the user's agent chat. The installation commands below
|
|
13
|
-
still describe the current product. See the [planned split](docs/product-intent.md#planned-product-split-and-companion-workflow).
|
|
8
|
+
Version **3.5.0**.
|
|
14
9
|
|
|
15
10
|
**Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
|
|
16
11
|
COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -25,6 +20,51 @@ pip install "maintainability-agent[mcp]" # optional local MCP server for chat
|
|
|
25
20
|
cp -r skills/maintainability-agent ~/.claude/skills/ # Claude Code slash command
|
|
26
21
|
```
|
|
27
22
|
|
|
23
|
+
**Install the analyzer pool too, or you get the built-in tier.** This tool
|
|
24
|
+
prefers established analyzers and falls back to its own detectors when none is
|
|
25
|
+
present. The fallback is honest — the report says `Estimate source: built-in
|
|
26
|
+
detectors` and the coverage section names what nothing examined — but it is a
|
|
27
|
+
weaker reading than the tool is capable of, and a first run without these is
|
|
28
|
+
the commonest reason it looks thin.
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install cohesion complexipy flake8 fortitude-lint interrogate lizard \
|
|
32
|
+
multimetric mypy pydocstyle pylint radon ruff vulture
|
|
33
|
+
npm install -g jscpd eslint # duplication + JavaScript/TypeScript
|
|
34
|
+
brew install pmd checkstyle spotbugs # JVM languages, optional
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Unpinned on purpose: this is the exact set CI installs and calibrates against,
|
|
38
|
+
and `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
|
|
39
|
+
disagree. Nothing here is required — the audit runs without any of it and tells
|
|
40
|
+
you what it could not measure.
|
|
41
|
+
|
|
42
|
+
**One command to a work order.** A config file is the whole setup — with one
|
|
43
|
+
present, nothing is asked and nothing is written into your tree:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
curl -O https://raw.githubusercontent.com/marshallguillory86/maintainability-agent/main/maintainability-audit.example.json
|
|
47
|
+
maintainability-audit --config maintainability-audit.example.json \
|
|
48
|
+
--output report.md --prompt-output prompt.md
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
`prompt.md` is the bounded work order: the findings worth fixing, in order,
|
|
52
|
+
each with its location, why it matters and the command that verifies it — and
|
|
53
|
+
the standing rule that nothing else gets refactored. Paste it into your agent.
|
|
54
|
+
`report.md` is the evidence behind it. The prompt is the product.
|
|
55
|
+
|
|
56
|
+
**Want to see the output before pointing it at your own code?**
|
|
57
|
+
[`examples/demo`](examples/demo/) is a two-module order system with real
|
|
58
|
+
problems in it — an overgrown pricing function, a money path nothing tests, and
|
|
59
|
+
a block duplicated between billing and invoicing. Four items, three finding
|
|
60
|
+
classes, a copy-paste prompt each, and it reads in under a minute. The work
|
|
61
|
+
order it produces is checked in at
|
|
62
|
+
[`expected-prompt.md`](examples/demo/expected-prompt.md).
|
|
63
|
+
|
|
64
|
+
Without `--config`, an interactive run asks the first-run questions instead —
|
|
65
|
+
analyzer pool, depth, licence policy, whether to run your suite — because those
|
|
66
|
+
are choices this tool will not make on your behalf.
|
|
67
|
+
|
|
28
68
|
---
|
|
29
69
|
|
|
30
70
|
## Executive summary
|
|
@@ -88,15 +128,6 @@ The full argument, including what this deliberately does not compete on:
|
|
|
88
128
|
[why this exists](docs/why-this-exists.md) and
|
|
89
129
|
[philosophy](docs/philosophy.md).
|
|
90
130
|
|
|
91
|
-
## The road to 1.0
|
|
92
|
-
|
|
93
|
-
1.0 was the line drawn under a long arc of **subtraction** — what remained after
|
|
94
|
-
every claim the project could not stand behind was removed. A scoring engine
|
|
95
|
-
rebuilt after it was found to grade repo *size*; a headline claim about AI
|
|
96
|
-
authorship retracted against a matched control; a score that is withheld rather
|
|
97
|
-
than guessed. That arc is the credibility, and it is recorded in full, with the
|
|
98
|
-
figures quoted from their approved summaries, in [the track record](docs/track-record.md).
|
|
99
|
-
|
|
100
131
|
## Install
|
|
101
132
|
|
|
102
133
|
```bash
|
|
@@ -340,19 +371,21 @@ it was generated against — a provenance record, not a claim about HEAD.
|
|
|
340
371
|
|
|
341
372
|
| Metric | Value |
|
|
342
373
|
|---|---:|
|
|
343
|
-
| Maintainability estimate | 4.
|
|
374
|
+
| Maintainability estimate | 4.5 / 5 |
|
|
344
375
|
| Verified grade | B |
|
|
345
|
-
| Files scanned |
|
|
376
|
+
| Files scanned | 511 |
|
|
346
377
|
| Hard gate failures | 0 |
|
|
347
378
|
|
|
348
379
|
A **B**, and the report says why: the grade is verified against the evidence
|
|
349
|
-
*floor* of 4.
|
|
350
|
-
prices at 0 when a grade has to be defended
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
380
|
+
*floor* of 4.2 rather than the 4.5 point estimate, because an unmeasured aspect
|
|
381
|
+
prices at 0 when a grade has to be defended. Every threshold gate is opted
|
|
382
|
+
**on** for this repository's own CI, so drifting below the bar fails the build
|
|
383
|
+
rather than the README.
|
|
384
|
+
|
|
385
|
+
The tool reports warn-band declarations here and they are not treated as
|
|
386
|
+
defects — see [what counts as a defect](docs/product-intent.md#what-counts-as-a-defect-and-what-does-not).
|
|
387
|
+
Restyling this codebase to raise its own grade is explicitly not work: a tool
|
|
388
|
+
that games its own metric has broken the only promise that matters.
|
|
356
389
|
|
|
357
390
|
## Platform support
|
|
358
391
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "maintainability-agent"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.5.0"
|
|
8
8
|
description = "Maintainability gate and AI remediation prompt generator for CI."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
# 3.11, not 3.10. `_discovery`, `_pillars` and `_runner` all import
|
|
@@ -58,7 +58,7 @@ mcp = ["mcp>=2,<3"]
|
|
|
58
58
|
# development dependency, never a runtime one: nothing the product
|
|
59
59
|
# ships imports it, and the oracle exists so a measurement can be
|
|
60
60
|
# checked against something other than its author.
|
|
61
|
-
dev = ["pytest>=8", "pytest-cov>=5", "jsonschema>=4", "ruff>=0.5", "pip-audit>=2.7", "mcp>=2,<3", "PyYAML>=6", "setuptools>=70", "lizard>=1.17"]
|
|
61
|
+
dev = ["pytest>=8", "pytest-cov>=5", "pytest-xdist>=3.6", "jsonschema>=4", "ruff>=0.5", "pip-audit>=2.7", "mcp>=2,<3", "PyYAML>=6", "setuptools>=70", "lizard>=1.17"]
|
|
62
62
|
|
|
63
63
|
[tool.setuptools.package-data]
|
|
64
64
|
# `_assets` carries the runtime data the code cannot work without: the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -29,6 +29,7 @@ Requires-Dist: mcp<3,>=2; extra == "mcp"
|
|
|
29
29
|
Provides-Extra: dev
|
|
30
30
|
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
31
|
Requires-Dist: pytest-cov>=5; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest-xdist>=3.6; extra == "dev"
|
|
32
33
|
Requires-Dist: jsonschema>=4; extra == "dev"
|
|
33
34
|
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
34
35
|
Requires-Dist: pip-audit>=2.7; extra == "dev"
|
|
@@ -45,12 +46,7 @@ Dynamic: license-file
|
|
|
45
46
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
46
47
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
47
48
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
48
|
-
Version **3.
|
|
49
|
-
|
|
50
|
-
**Planned, not shipped:** the audit tool will become `maintainability-audit`;
|
|
51
|
-
a new `maintainability-agent` companion will run it and automate human-selected
|
|
52
|
-
work orders within the user's agent chat. The installation commands below
|
|
53
|
-
still describe the current product. See the [planned split](docs/product-intent.md#planned-product-split-and-companion-workflow).
|
|
49
|
+
Version **3.5.0**.
|
|
54
50
|
|
|
55
51
|
**Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
|
|
56
52
|
COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -65,6 +61,51 @@ pip install "maintainability-agent[mcp]" # optional local MCP server for chat
|
|
|
65
61
|
cp -r skills/maintainability-agent ~/.claude/skills/ # Claude Code slash command
|
|
66
62
|
```
|
|
67
63
|
|
|
64
|
+
**Install the analyzer pool too, or you get the built-in tier.** This tool
|
|
65
|
+
prefers established analyzers and falls back to its own detectors when none is
|
|
66
|
+
present. The fallback is honest — the report says `Estimate source: built-in
|
|
67
|
+
detectors` and the coverage section names what nothing examined — but it is a
|
|
68
|
+
weaker reading than the tool is capable of, and a first run without these is
|
|
69
|
+
the commonest reason it looks thin.
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
pip install cohesion complexipy flake8 fortitude-lint interrogate lizard \
|
|
73
|
+
multimetric mypy pydocstyle pylint radon ruff vulture
|
|
74
|
+
npm install -g jscpd eslint # duplication + JavaScript/TypeScript
|
|
75
|
+
brew install pmd checkstyle spotbugs # JVM languages, optional
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Unpinned on purpose: this is the exact set CI installs and calibrates against,
|
|
79
|
+
and `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
|
|
80
|
+
disagree. Nothing here is required — the audit runs without any of it and tells
|
|
81
|
+
you what it could not measure.
|
|
82
|
+
|
|
83
|
+
**One command to a work order.** A config file is the whole setup — with one
|
|
84
|
+
present, nothing is asked and nothing is written into your tree:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
curl -O https://raw.githubusercontent.com/marshallguillory86/maintainability-agent/main/maintainability-audit.example.json
|
|
88
|
+
maintainability-audit --config maintainability-audit.example.json \
|
|
89
|
+
--output report.md --prompt-output prompt.md
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
`prompt.md` is the bounded work order: the findings worth fixing, in order,
|
|
93
|
+
each with its location, why it matters and the command that verifies it — and
|
|
94
|
+
the standing rule that nothing else gets refactored. Paste it into your agent.
|
|
95
|
+
`report.md` is the evidence behind it. The prompt is the product.
|
|
96
|
+
|
|
97
|
+
**Want to see the output before pointing it at your own code?**
|
|
98
|
+
[`examples/demo`](examples/demo/) is a two-module order system with real
|
|
99
|
+
problems in it — an overgrown pricing function, a money path nothing tests, and
|
|
100
|
+
a block duplicated between billing and invoicing. Four items, three finding
|
|
101
|
+
classes, a copy-paste prompt each, and it reads in under a minute. The work
|
|
102
|
+
order it produces is checked in at
|
|
103
|
+
[`expected-prompt.md`](examples/demo/expected-prompt.md).
|
|
104
|
+
|
|
105
|
+
Without `--config`, an interactive run asks the first-run questions instead —
|
|
106
|
+
analyzer pool, depth, licence policy, whether to run your suite — because those
|
|
107
|
+
are choices this tool will not make on your behalf.
|
|
108
|
+
|
|
68
109
|
---
|
|
69
110
|
|
|
70
111
|
## Executive summary
|
|
@@ -128,15 +169,6 @@ The full argument, including what this deliberately does not compete on:
|
|
|
128
169
|
[why this exists](docs/why-this-exists.md) and
|
|
129
170
|
[philosophy](docs/philosophy.md).
|
|
130
171
|
|
|
131
|
-
## The road to 1.0
|
|
132
|
-
|
|
133
|
-
1.0 was the line drawn under a long arc of **subtraction** — what remained after
|
|
134
|
-
every claim the project could not stand behind was removed. A scoring engine
|
|
135
|
-
rebuilt after it was found to grade repo *size*; a headline claim about AI
|
|
136
|
-
authorship retracted against a matched control; a score that is withheld rather
|
|
137
|
-
than guessed. That arc is the credibility, and it is recorded in full, with the
|
|
138
|
-
figures quoted from their approved summaries, in [the track record](docs/track-record.md).
|
|
139
|
-
|
|
140
172
|
## Install
|
|
141
173
|
|
|
142
174
|
```bash
|
|
@@ -380,19 +412,21 @@ it was generated against — a provenance record, not a claim about HEAD.
|
|
|
380
412
|
|
|
381
413
|
| Metric | Value |
|
|
382
414
|
|---|---:|
|
|
383
|
-
| Maintainability estimate | 4.
|
|
415
|
+
| Maintainability estimate | 4.5 / 5 |
|
|
384
416
|
| Verified grade | B |
|
|
385
|
-
| Files scanned |
|
|
417
|
+
| Files scanned | 511 |
|
|
386
418
|
| Hard gate failures | 0 |
|
|
387
419
|
|
|
388
420
|
A **B**, and the report says why: the grade is verified against the evidence
|
|
389
|
-
*floor* of 4.
|
|
390
|
-
prices at 0 when a grade has to be defended
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
421
|
+
*floor* of 4.2 rather than the 4.5 point estimate, because an unmeasured aspect
|
|
422
|
+
prices at 0 when a grade has to be defended. Every threshold gate is opted
|
|
423
|
+
**on** for this repository's own CI, so drifting below the bar fails the build
|
|
424
|
+
rather than the README.
|
|
425
|
+
|
|
426
|
+
The tool reports warn-band declarations here and they are not treated as
|
|
427
|
+
defects — see [what counts as a defect](docs/product-intent.md#what-counts-as-a-defect-and-what-does-not).
|
|
428
|
+
Restyling this codebase to raise its own grade is explicitly not work: a tool
|
|
429
|
+
that games its own metric has broken the only promise that matters.
|
|
396
430
|
|
|
397
431
|
## Platform support
|
|
398
432
|
|
|
@@ -187,6 +187,7 @@ tests/test_calibration_drift.py
|
|
|
187
187
|
tests/test_calibration_tooling.py
|
|
188
188
|
tests/test_catalog_selection.py
|
|
189
189
|
tests/test_catalog_tier_promise.py
|
|
190
|
+
tests/test_chat_leads_with_the_work_order.py
|
|
190
191
|
tests/test_chat_primary_docs.py
|
|
191
192
|
tests/test_check_refuses_plus_only_fragments.py
|
|
192
193
|
tests/test_checkstyle_adapter.py
|
|
@@ -222,6 +223,7 @@ tests/test_declarative_parsers.py
|
|
|
222
223
|
tests/test_declared_authorship.py
|
|
223
224
|
tests/test_declared_imports.py
|
|
224
225
|
tests/test_delegated_security_pillar.py
|
|
226
|
+
tests/test_demo_tree.py
|
|
225
227
|
tests/test_derivation_mix.py
|
|
226
228
|
tests/test_determinism.py
|
|
227
229
|
tests/test_dimension_ratchet.py
|
|
@@ -342,6 +344,7 @@ tests/test_source_index.py
|
|
|
342
344
|
tests/test_spotbugs_adapter.py
|
|
343
345
|
tests/test_spotbugs_catalog.py
|
|
344
346
|
tests/test_stage8_contract.py
|
|
347
|
+
tests/test_stdout_outputs.py
|
|
345
348
|
tests/test_suite_isolation.py
|
|
346
349
|
tests/test_swift_declarations.py
|
|
347
350
|
tests/test_tdd_structure.py
|
|
@@ -178,13 +178,27 @@ def prompt_work_order(report: dict[str, Any]) -> list[str]:
|
|
|
178
178
|
for index, item in enumerate(items, start=1):
|
|
179
179
|
location = item["path"] + (f":{item['line']}" if item.get("line") else "")
|
|
180
180
|
lines.append(f"{index}. **{item['title']}** — {item['target']}")
|
|
181
|
-
|
|
181
|
+
# One row now stands for its whole class (D159), so a count
|
|
182
|
+
# above one says where the rest are rather than leaving the
|
|
183
|
+
# single location reading as the only instance.
|
|
184
|
+
count = item.get("class_count") or 1
|
|
185
|
+
files = item.get("class_paths") or 1
|
|
186
|
+
if count > 1:
|
|
187
|
+
where = f"across {files} files, " if files > 1 else ""
|
|
188
|
+
lines.append(f" - First of {count} {where}starting at: `{location}`")
|
|
189
|
+
else:
|
|
190
|
+
lines.append(f" - Location: `{location}`")
|
|
182
191
|
lines.append(f" - Why it matters: {item['rationale']}")
|
|
183
192
|
if item["class_delta"]:
|
|
184
193
|
lines.append(
|
|
185
194
|
f" - Clearing all {item['class_count']} of these is worth "
|
|
186
195
|
f"+{item['class_delta']:.2f} to the maintainability estimate."
|
|
187
196
|
)
|
|
197
|
+
elif count > 1:
|
|
198
|
+
lines.append(
|
|
199
|
+
f" - The other {count - 1} are listed in the report; the "
|
|
200
|
+
"score does not move until the class is cleared."
|
|
201
|
+
)
|
|
188
202
|
lines.extend([
|
|
189
203
|
"",
|
|
190
204
|
f"Verify with: `{items[0]['verification']}`",
|
|
@@ -57,7 +57,7 @@ from .config import PathNotAllowed, read_operator_file
|
|
|
57
57
|
# followed. A schema-4 line read by an older build fails that one line's
|
|
58
58
|
# parse and costs that scan, which is the tolerance `read_history` was
|
|
59
59
|
# built with rather than a new risk.
|
|
60
|
-
HISTORY_SCHEMA_VERSION =
|
|
60
|
+
HISTORY_SCHEMA_VERSION = 5
|
|
61
61
|
|
|
62
62
|
DEFAULT_HISTORY_PATH = ".maintainability/history.jsonl"
|
|
63
63
|
|
|
@@ -70,7 +70,7 @@ DEFAULT_HISTORY_PATH = ".maintainability/history.jsonl"
|
|
|
70
70
|
# score being added and not added here, after which trends silently span
|
|
71
71
|
# a change in the instrument.
|
|
72
72
|
COMPARABILITY_FIELDS: tuple[str, ...] = (
|
|
73
|
-
"
|
|
73
|
+
"tool_version",
|
|
74
74
|
"calibration",
|
|
75
75
|
"thresholds_digest",
|
|
76
76
|
"analyzers",
|
|
@@ -102,7 +102,14 @@ class ScanRecord:
|
|
|
102
102
|
commit: str
|
|
103
103
|
branch: str
|
|
104
104
|
scope: str
|
|
105
|
-
|
|
105
|
+
#: The version of *this tool* that produced the scan. Named
|
|
106
|
+
#: `rubric_version` until 3.5.0, which is what it was never: a
|
|
107
|
+
#: rubric version would move when the rubric moved, and this moves
|
|
108
|
+
#: on every release. A reader of a stored line saw
|
|
109
|
+
#: `"rubric_version": "3.4.0"` and concluded the rubric had changed
|
|
110
|
+
#: when a patch release was all that happened — on 38 of this
|
|
111
|
+
#: repository's 49 series breaks (D158).
|
|
112
|
+
tool_version: str
|
|
106
113
|
calibration: float
|
|
107
114
|
# A digest of the thresholds in force. Stored rather than the
|
|
108
115
|
# thresholds themselves: the comparison is equality, and a digest
|
|
@@ -210,21 +217,28 @@ def comparability_key(record: ScanRecord) -> tuple[Any, ...]:
|
|
|
210
217
|
|
|
211
218
|
|
|
212
219
|
# What each comparability field is, in words a reader can act on. The
|
|
213
|
-
# stored names are terse and
|
|
214
|
-
#
|
|
215
|
-
#
|
|
216
|
-
#
|
|
217
|
-
#
|
|
218
|
-
#
|
|
219
|
-
#
|
|
220
|
+
# stored names are terse and prose is what a report should print: a
|
|
221
|
+
# break that names `thresholds_digest` tells a reader less than one
|
|
222
|
+
# saying the configured thresholds changed.
|
|
223
|
+
#
|
|
224
|
+
# `tool_version` was `rubric_version` until 3.5.0 and this map was
|
|
225
|
+
# where that lie was first corrected — the display said "the tool
|
|
226
|
+
# version" while the stored field still said otherwise. D158 finished
|
|
227
|
+
# it by renaming the field, so the map and the record now agree instead
|
|
228
|
+
# of one translating the other.
|
|
220
229
|
FIELD_NAMES: dict[str, str] = {
|
|
221
|
-
"
|
|
230
|
+
"tool_version": "the tool version",
|
|
222
231
|
"calibration": "the calibration constant",
|
|
223
232
|
"thresholds_digest": "the configured thresholds",
|
|
224
233
|
"analyzers": "which analyzers contributed",
|
|
225
234
|
"scored_languages": "the scored languages",
|
|
226
235
|
"scope": "the scan scope",
|
|
227
|
-
|
|
236
|
+
# Names the scoring model rather than the version, because that is
|
|
237
|
+
# what `_model_key` actually keys on. Saying "its version" sent a
|
|
238
|
+
# reader looking for a release that in the common case had not
|
|
239
|
+
# changed -- the v2 document breaks on `scoring_model`, and the
|
|
240
|
+
# version is only the v1 fallback.
|
|
241
|
+
"delegated_producers": "a delegated pillar's producer or its scoring model",
|
|
228
242
|
}
|
|
229
243
|
|
|
230
244
|
|
|
@@ -408,6 +422,15 @@ def read_history(path: Path) -> list[ScanRecord]:
|
|
|
408
422
|
try:
|
|
409
423
|
payload = json.loads(line)
|
|
410
424
|
payload.pop("history_schema_version", None)
|
|
425
|
+
# Schema 1-4 stored this as `rubric_version`. Renamed in 5
|
|
426
|
+
# because the name was never true (D158); every line written
|
|
427
|
+
# before that keeps loading, and keeps its place in a
|
|
428
|
+
# series, because the *value* never changed — only what it
|
|
429
|
+
# is called. A stored history is the one thing here that
|
|
430
|
+
# cannot be regenerated, so a rename that dropped it would
|
|
431
|
+
# cost more than the wrong name did.
|
|
432
|
+
if "rubric_version" in payload:
|
|
433
|
+
payload["tool_version"] = payload.pop("rubric_version")
|
|
411
434
|
# Every sequence field back to a tuple. JSON has one list
|
|
412
435
|
# type, so a field missed here returns as a list and the
|
|
413
436
|
# record stops comparing equal to a freshly built one —
|
|
@@ -506,7 +529,7 @@ def _delegated_producers(report: dict[str, Any]) -> tuple[str, ...]:
|
|
|
506
529
|
Sorted and joined into one string per pillar so the comparability
|
|
507
530
|
key stays a plain value. Only delegated pillars carry a producer;
|
|
508
531
|
the ones this tool measures itself are already covered by
|
|
509
|
-
`
|
|
532
|
+
`tool_version`.
|
|
510
533
|
|
|
511
534
|
A pillar whose document names no version still contributes its
|
|
512
535
|
producer, because "the same tool, version unknown" and "a different
|
|
@@ -575,7 +598,7 @@ def record_of(report: dict[str, Any], config: dict[str, Any], version: str,
|
|
|
575
598
|
commit=report.get("git_commit") or "",
|
|
576
599
|
branch=report.get("git_branch") or "",
|
|
577
600
|
scope=report.get("mode") or "full",
|
|
578
|
-
|
|
601
|
+
tool_version=version,
|
|
579
602
|
calibration=calibration,
|
|
580
603
|
thresholds_digest=thresholds_digest(config.get("thresholds") or {}),
|
|
581
604
|
analyzers=contributed,
|
{maintainability_agent-3.3.0 → maintainability_agent-3.5.0}/src/maintainability_audit/_work_order.py
RENAMED
|
@@ -427,7 +427,48 @@ def prompt_items(items: list[dict[str, Any]], limit: int = 12,
|
|
|
427
427
|
]
|
|
428
428
|
severe = [item for item in eligible if item.get("risk") == 5]
|
|
429
429
|
rest = [item for item in eligible if item.get("risk") != 5]
|
|
430
|
-
return (severe + rest)[:limit]
|
|
430
|
+
return _one_per_class(severe + rest)[:limit]
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
def _one_per_class(ordered: list[dict[str, Any]]) -> list[dict[str, Any]]:
|
|
434
|
+
"""The best member of each finding class, in the order they arrived.
|
|
435
|
+
|
|
436
|
+
**The paste is twelve kinds of work, not twelve rows.** Without this
|
|
437
|
+
a class with a hundred members takes every slot: measured on a real
|
|
438
|
+
tree, 100 of 125 items were one class and all twelve went to it,
|
|
439
|
+
six of them naming the same file, while 24 duplicate blocks and an
|
|
440
|
+
oversized file got none. The prompt says "the first items are the
|
|
441
|
+
highest value for the least change" and then spent its whole budget
|
|
442
|
+
on one rule while omitting two others entirely (D159).
|
|
443
|
+
|
|
444
|
+
One row per class is enough because the row already carries the
|
|
445
|
+
whole class: `class_count` and `class_delta` are on every item, so
|
|
446
|
+
it reads "clearing all 100 of these is worth +0.20" rather than
|
|
447
|
+
printing a hundred line numbers. An agent is better instructed by
|
|
448
|
+
one rule and its count than by twelve instances of it.
|
|
449
|
+
|
|
450
|
+
Order is preserved rather than re-sorted, so Severe still leads and
|
|
451
|
+
the economic ordering behind it still holds — this removes
|
|
452
|
+
repetition and decides nothing about priority.
|
|
453
|
+
"""
|
|
454
|
+
spread: dict[str, set[str]] = {}
|
|
455
|
+
for item in ordered:
|
|
456
|
+
name = str(item.get("finding_class") or item.get("title"))
|
|
457
|
+
spread.setdefault(name, set()).add(str(item.get("path") or ""))
|
|
458
|
+
|
|
459
|
+
seen: set[str] = set()
|
|
460
|
+
first: list[dict[str, Any]] = []
|
|
461
|
+
for item in ordered:
|
|
462
|
+
name = str(item.get("finding_class") or item.get("title"))
|
|
463
|
+
if name in seen:
|
|
464
|
+
continue
|
|
465
|
+
seen.add(name)
|
|
466
|
+
# The surviving row keeps its own title, which names one file,
|
|
467
|
+
# so it must also say how far the class reaches — otherwise a
|
|
468
|
+
# row standing for 46 findings across seven files reads as one
|
|
469
|
+
# finding in the file it happens to name.
|
|
470
|
+
first.append({**item, "class_paths": len(spread[name])})
|
|
471
|
+
return first
|
|
431
472
|
|
|
432
473
|
|
|
433
474
|
# The axes a reader can narrow by. Every one is a field already on the
|
|
@@ -462,6 +503,34 @@ def select(items: list[dict[str, Any]], **criteria: str) -> list[dict[str, Any]]
|
|
|
462
503
|
return [item for item in items if matches(item)]
|
|
463
504
|
|
|
464
505
|
|
|
506
|
+
def prompt_advised(items: list[dict[str, Any]], limit: int = 12,
|
|
507
|
+
escalated: set[str] | None = None) -> list[dict[str, Any]]:
|
|
508
|
+
"""Every eligible item the prompt's rows stand for.
|
|
509
|
+
|
|
510
|
+
`prompt_items` returns one row per class, because a paste of twelve
|
|
511
|
+
is twelve *kinds* of work (D159). What was advised is wider than
|
|
512
|
+
what was printed: a row reading "clearing all 68 of these" asks for
|
|
513
|
+
all 68, so recurrence has to remember all 68.
|
|
514
|
+
|
|
515
|
+
Derived from `prompt_items` rather than re-selected beside it. The
|
|
516
|
+
advised set is the classes those rows name, and this expands them —
|
|
517
|
+
one decision about what to advise, two views of it. Two independent
|
|
518
|
+
selections would drift, and the one that drifts is the one nobody
|
|
519
|
+
reads.
|
|
520
|
+
"""
|
|
521
|
+
advised = {
|
|
522
|
+
str(item.get("finding_class") or item.get("title"))
|
|
523
|
+
for item in prompt_items(items, limit, escalated)
|
|
524
|
+
}
|
|
525
|
+
blocked = escalated or set()
|
|
526
|
+
return [
|
|
527
|
+
item for item in items
|
|
528
|
+
if item["band"] != Band.MAJOR_PROJECT.value
|
|
529
|
+
and item.get("fingerprint") not in blocked
|
|
530
|
+
and str(item.get("finding_class") or item.get("title")) in advised
|
|
531
|
+
]
|
|
532
|
+
|
|
533
|
+
|
|
465
534
|
def prompt_targets(report: dict[str, Any]) -> tuple[str, ...]:
|
|
466
535
|
"""The identities a generated prompt actually asked somebody to fix.
|
|
467
536
|
|
|
@@ -495,7 +564,10 @@ def prompt_targets(report: dict[str, Any]) -> tuple[str, ...]:
|
|
|
495
564
|
}
|
|
496
565
|
known = set(finding_fingerprints(report))
|
|
497
566
|
targets = set()
|
|
498
|
-
|
|
567
|
+
# Every member of every advised class, not only the rows printed:
|
|
568
|
+
# the prompt asks for the whole class, so the told-fixed-returned
|
|
569
|
+
# signal has to cover the whole class (D159).
|
|
570
|
+
for item in prompt_advised(report.get("work_order") or [], escalated=escalated):
|
|
499
571
|
fingerprint = item.get("fingerprint")
|
|
500
572
|
if fingerprint is None:
|
|
501
573
|
continue
|