maintainability-agent 4.4.4__tar.gz → 4.4.6__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.4.4/src/maintainability_agent.egg-info → maintainability_agent-4.4.6}/PKG-INFO +28 -9
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/README.md +27 -8
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6/src/maintainability_agent.egg-info}/PKG-INFO +28 -9
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/SOURCES.txt +2 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_adapters.py +23 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_analysis.py +6 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_jvm_adapters.py +15 -13
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_metric_adapters.py +2 -4
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ratio_adapters.py +4 -5
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/cli.py +9 -2
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_primary_estimate.py +2 -4
- maintainability_agent-4.4.6/tests/test_analyzers_leave_no_temp_dirs.py +88 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_artifact_write_route_class.py +15 -9
- maintainability_agent-4.4.6/tests/test_base_ref_only_where_it_exists.py +75 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_calibration_corpus.py +5 -3
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_three_presentations.py +9 -7
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_version_stamping.py +5 -3
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/LICENSE +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/pyproject.toml +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/setup.cfg +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/requires.txt +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_analyzer_sections.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_anchor.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_banner.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_catalog.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_changed_code_policy.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_cognitive.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_coverage_notes.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_criteria_scope.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_delegated_pillar.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_evidence_reader.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_first_run.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_gates.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_grammar.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_handoff.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_html_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_in_loop.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_in_loop_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_audit.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_servers.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_setup.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_operator_reads.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_oracle.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_pipeline_results.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_precommit.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_precommit_install.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_precommit_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_prompt_sections.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_cobol.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_go.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_kotlin.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_php.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_ruby.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_rust.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_shell.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_running_version.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_security_delegate.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_security_work_order.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_self_update.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_setup_persist.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_verdict_adapters.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/config.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/mcp_server.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/prompts.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/renderers.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/report.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_clone_names_every_copy.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_dangling_source_link_is_named_not_fatal.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_format_override_is_disclosed.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_matching_format_stays_silent.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_production_name_keeps_its_test_prefix.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_published_question_offers_what_it_accepts.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_rendered_docs_site_is_not_scored_as_source.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_setup_question_keeps_its_contract.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_adapters.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_added_lines.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_an_absent_work_order_renders_nothing.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_an_unmeasured_pillar_reports_no_number.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_file_lists_are_batched.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzers_against_the_real_tools.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzers_never_write.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzers_report_what_actually_failed.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_anchor_and_mode.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_anchor_disclosure.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_architecture.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_attestation.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_audit_components.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_backfill.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_bands.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_behaviour_suites_are_tests.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_both_setup_paths_ask_the_same_stage.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_changed_code_policy.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_chat_leads_with_the_work_order.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_check_refuses_plus_only_fragments.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_child_sandbox.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ci_runs_once.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_clean_sees_the_weakened_oracle.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cli.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_code_scanning_gets_alerts_not_the_record.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cohesion_with_nothing_to_read_is_not_applicable.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_config_shape.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_conformance_reads_the_operators_ask.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consent_is_per_repository.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consent_survives_setup_and_is_asked.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consent_without_command_has_a_remedy.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_corpus_note_counts_come_from_the_corpus.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_corroborate.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_coverage_config_reaches_children.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_coverage_formats.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_criteria_completion.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_current_state_docs_name_every_parsed_language.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_dead_code.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_criteria_scope.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declarative_parsers.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declared_capabilities_match_the_delegate.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_delegated_security_pillar.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_demo_tree.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_determinism.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_discovery.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_docs_links.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_economic_context.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_built_presentation_is_offered.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_job_tests_the_pinned_oracle.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_language_counts_its_own_loop.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_language_has_a_loop_fixture.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_pool_install_is_the_same_pool.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_question_can_be_answered.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_surface_says_what_the_run_found.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_example_config_opens_claimed_languages.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_exclude_additional_keeps_the_defaults.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_exposure_never_outranks_band.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_first_run_elicitation.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_first_stage_setup_wording_holds.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_format_ask.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_git_argv.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_go_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_grammar_constructs.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_grammar_token_coverage.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_grok_audit_of_3_11.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history_window.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_html_executive.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_in_loop_budgets.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_in_loop_check.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_java_scored.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_kotlin_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_kotlin_metrics.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_language_support_honesty.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_list_tools_publishes_the_answer_path.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_local_gate.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_maintenance_signals.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_format_contract.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_servers.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_start_failure_names_what_is_installed.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_missing_security_scanners_are_named_before_the_run.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mutation_recorded.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_no_private_names.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_operator_named_paths.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_operator_named_reads.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_oracle_weakening_precision_bar.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pairing_reads_imports.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_php_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pipeline_results.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_platform_claim.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_policy_claims.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_population_floors.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_precommit_staged.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_preflight_before_consent_runs_nothing_from_the_tree.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_previous_release_reached_pypi.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_promises.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_python_complexity.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_readme_claims.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_recurrence.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_regular_file_reads_work_without_o_nonblock.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_release_needs_an_empty_ledger.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_release_plan.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_rendered_docs.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_reported_but_not_scored.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_root_grants.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ruby_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_runner.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_rust_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_sarif.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scan_history.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scanner_fingerprint_covers_the_measurement_path.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scanner_unsafe_direction.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scanning.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_security_delegate_versions_agree.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_security_findings_keep_their_handoff.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_security_pillar_asserts_a_scanner_set.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_security_pillar_runs_and_shows.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_selection_covers_every_parsed_language.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_self_update.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_semantic_findings_stay_inside_the_audited_files.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_answers_are_the_same_setup.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_instruction_describes_its_own_reply.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_writes_a_valid_config.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_shell_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_shell_metrics.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_skill_install.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_sonar_resolve.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_source_index.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_stamped_documents_stay_honest.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_stdout_outputs.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_terminal_asks_the_same_questions.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_test_commands.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_agent_knows_when_it_is_stale.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_changelog_covers_the_shipping_version.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_chat_payload_has_a_budget.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_condition_says_what_it_measured.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_handoff_rules_are_their_own_module.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_pillar_row_reads_cleanly.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_presentation_question_stays_answerable.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_previous_release_was_tagged.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_prompt_does_not_take_back_what_it_withheld.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_prompt_keeps_listing_what_it_did_not_withhold.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_release_process_describes_itself.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_release_record_stays_well_formed.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_report_is_saved_not_sent.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_security_run_has_a_configurable_limit.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_security_work_order_is_drawn.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_suite_names_the_program_it_ran.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_tree_cannot_redirect_a_read.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_version_has_one_source.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tool_resolution.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tree_chosen_spawn.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tree_reads_use_the_primitive.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_trends.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_unanchored_set_matches_corpus.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_unread_code.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_version_claim.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_withheld_work_keeps_its_boundary.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_items_state_their_own_finding.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_order.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/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.4.
|
|
3
|
+
Version: 4.4.6
|
|
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.4.
|
|
50
|
+
Version **4.4.6**.
|
|
51
51
|
|
|
52
52
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
53
53
|
>
|
|
@@ -90,10 +90,12 @@ npm install -g jscpd eslint # duplication + JavaScript/TypeScript
|
|
|
90
90
|
brew install pmd checkstyle spotbugs # JVM languages, optional
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
disagree.
|
|
96
|
-
|
|
93
|
+
This is the exact set CI installs, and
|
|
94
|
+
`test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
|
|
95
|
+
disagree. CI installs it at the versions in `constraints/analyzers.txt`, the
|
|
96
|
+
ones the scale was calibrated with; add `-c constraints/analyzers.txt` from a
|
|
97
|
+
source checkout to match them. Nothing here is required — the audit runs
|
|
98
|
+
without any of it and tells you what it could not measure.
|
|
97
99
|
|
|
98
100
|
**Install secure-code-agent for the security pillar.** Every audit runs it; it is
|
|
99
101
|
installed alongside rather than as a dependency, so the two tools release
|
|
@@ -204,6 +206,7 @@ The full argument, including what this deliberately does not compete on:
|
|
|
204
206
|
```bash
|
|
205
207
|
python3 -m pip install maintainability-agent
|
|
206
208
|
maintainability-agent --root . --config maintainability-agent.json
|
|
209
|
+
maintainability-agent --update # later: upgrade, re-sync the skill, restart stale MCP servers
|
|
207
210
|
```
|
|
208
211
|
|
|
209
212
|
Or run from a source checkout without installing:
|
|
@@ -267,6 +270,21 @@ withheld estimate. For PR work, add `--changed-only main...HEAD` to audit the
|
|
|
267
270
|
diff; on a change too small to support a rate, the estimate and grade are
|
|
268
271
|
withheld and the scope is named as the reason.
|
|
269
272
|
|
|
273
|
+
**Hold the code a change touches to a stricter bar.** `policy.changed_code` in
|
|
274
|
+
`maintainability-agent.json` sets tighter function limits for what a change
|
|
275
|
+
adds or alters, so a team can gate new work without first fixing every old
|
|
276
|
+
function:
|
|
277
|
+
|
|
278
|
+
```json
|
|
279
|
+
"policy": {"changed_code": {"max_function_lines": 40, "max_complexity": 10}}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
On a `--changed-only` run, a function the change touched is held to it and
|
|
283
|
+
untouched code is judged by the standard as before. A policy only tightens — a
|
|
284
|
+
looser limit is refused when the config loads — and it decides the gate, never
|
|
285
|
+
the grade: breaches fail `--fail-on-gate` and are listed under *Changed-code
|
|
286
|
+
policy*, and the score is unchanged.
|
|
287
|
+
|
|
270
288
|
### Checking that the agent did the work
|
|
271
289
|
|
|
272
290
|
The work order tells an agent to fix exactly these findings and refactor nothing
|
|
@@ -503,8 +521,9 @@ maintainability-agent --install-skill # writes ~/.claude/skills
|
|
|
503
521
|
```
|
|
504
522
|
|
|
505
523
|
`maintainability-agent --update` upgrades the install to the newest release —
|
|
506
|
-
never a downgrade — re-syncs the skill, and
|
|
507
|
-
|
|
524
|
+
never a downgrade — re-syncs the skill, and stops any MCP server still on an
|
|
525
|
+
older version that is not mid-audit, so the host starts the new one on its
|
|
526
|
+
next call; `maintainability-agent --install-updater` runs it hourly (macOS launch
|
|
508
527
|
agent). Run `--install-skill` by hand after any other upgrade — a drifted skill
|
|
509
528
|
teaches agents a dead workflow,
|
|
510
529
|
so a differing installed copy is refused with the list of differences. Per-host
|
|
@@ -517,7 +536,7 @@ instead of an invokable skill:
|
|
|
517
536
|
This repo ships `action.yml`, usable as a composite action:
|
|
518
537
|
|
|
519
538
|
```yaml
|
|
520
|
-
- uses: marshallguillory86/maintainability-agent@v4.4.
|
|
539
|
+
- uses: marshallguillory86/maintainability-agent@v4.4.6
|
|
521
540
|
with:
|
|
522
541
|
config: maintainability-agent.json
|
|
523
542
|
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.4.
|
|
8
|
+
Version **4.4.6**.
|
|
9
9
|
|
|
10
10
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
11
11
|
>
|
|
@@ -48,10 +48,12 @@ npm install -g jscpd eslint # duplication + JavaScript/TypeScript
|
|
|
48
48
|
brew install pmd checkstyle spotbugs # JVM languages, optional
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
disagree.
|
|
54
|
-
|
|
51
|
+
This is the exact set CI installs, and
|
|
52
|
+
`test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
|
|
53
|
+
disagree. CI installs it at the versions in `constraints/analyzers.txt`, the
|
|
54
|
+
ones the scale was calibrated with; add `-c constraints/analyzers.txt` from a
|
|
55
|
+
source checkout to match them. Nothing here is required — the audit runs
|
|
56
|
+
without any of it and tells you what it could not measure.
|
|
55
57
|
|
|
56
58
|
**Install secure-code-agent for the security pillar.** Every audit runs it; it is
|
|
57
59
|
installed alongside rather than as a dependency, so the two tools release
|
|
@@ -162,6 +164,7 @@ The full argument, including what this deliberately does not compete on:
|
|
|
162
164
|
```bash
|
|
163
165
|
python3 -m pip install maintainability-agent
|
|
164
166
|
maintainability-agent --root . --config maintainability-agent.json
|
|
167
|
+
maintainability-agent --update # later: upgrade, re-sync the skill, restart stale MCP servers
|
|
165
168
|
```
|
|
166
169
|
|
|
167
170
|
Or run from a source checkout without installing:
|
|
@@ -225,6 +228,21 @@ withheld estimate. For PR work, add `--changed-only main...HEAD` to audit the
|
|
|
225
228
|
diff; on a change too small to support a rate, the estimate and grade are
|
|
226
229
|
withheld and the scope is named as the reason.
|
|
227
230
|
|
|
231
|
+
**Hold the code a change touches to a stricter bar.** `policy.changed_code` in
|
|
232
|
+
`maintainability-agent.json` sets tighter function limits for what a change
|
|
233
|
+
adds or alters, so a team can gate new work without first fixing every old
|
|
234
|
+
function:
|
|
235
|
+
|
|
236
|
+
```json
|
|
237
|
+
"policy": {"changed_code": {"max_function_lines": 40, "max_complexity": 10}}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
On a `--changed-only` run, a function the change touched is held to it and
|
|
241
|
+
untouched code is judged by the standard as before. A policy only tightens — a
|
|
242
|
+
looser limit is refused when the config loads — and it decides the gate, never
|
|
243
|
+
the grade: breaches fail `--fail-on-gate` and are listed under *Changed-code
|
|
244
|
+
policy*, and the score is unchanged.
|
|
245
|
+
|
|
228
246
|
### Checking that the agent did the work
|
|
229
247
|
|
|
230
248
|
The work order tells an agent to fix exactly these findings and refactor nothing
|
|
@@ -461,8 +479,9 @@ maintainability-agent --install-skill # writes ~/.claude/skills
|
|
|
461
479
|
```
|
|
462
480
|
|
|
463
481
|
`maintainability-agent --update` upgrades the install to the newest release —
|
|
464
|
-
never a downgrade — re-syncs the skill, and
|
|
465
|
-
|
|
482
|
+
never a downgrade — re-syncs the skill, and stops any MCP server still on an
|
|
483
|
+
older version that is not mid-audit, so the host starts the new one on its
|
|
484
|
+
next call; `maintainability-agent --install-updater` runs it hourly (macOS launch
|
|
466
485
|
agent). Run `--install-skill` by hand after any other upgrade — a drifted skill
|
|
467
486
|
teaches agents a dead workflow,
|
|
468
487
|
so a differing installed copy is refused with the list of differences. Per-host
|
|
@@ -475,7 +494,7 @@ instead of an invokable skill:
|
|
|
475
494
|
This repo ships `action.yml`, usable as a composite action:
|
|
476
495
|
|
|
477
496
|
```yaml
|
|
478
|
-
- uses: marshallguillory86/maintainability-agent@v4.4.
|
|
497
|
+
- uses: marshallguillory86/maintainability-agent@v4.4.6
|
|
479
498
|
with:
|
|
480
499
|
config: maintainability-agent.json
|
|
481
500
|
changed-only: main...HEAD
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 4.4.
|
|
3
|
+
Version: 4.4.6
|
|
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.4.
|
|
50
|
+
Version **4.4.6**.
|
|
51
51
|
|
|
52
52
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
53
53
|
>
|
|
@@ -90,10 +90,12 @@ npm install -g jscpd eslint # duplication + JavaScript/TypeScript
|
|
|
90
90
|
brew install pmd checkstyle spotbugs # JVM languages, optional
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
disagree.
|
|
96
|
-
|
|
93
|
+
This is the exact set CI installs, and
|
|
94
|
+
`test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
|
|
95
|
+
disagree. CI installs it at the versions in `constraints/analyzers.txt`, the
|
|
96
|
+
ones the scale was calibrated with; add `-c constraints/analyzers.txt` from a
|
|
97
|
+
source checkout to match them. Nothing here is required — the audit runs
|
|
98
|
+
without any of it and tells you what it could not measure.
|
|
97
99
|
|
|
98
100
|
**Install secure-code-agent for the security pillar.** Every audit runs it; it is
|
|
99
101
|
installed alongside rather than as a dependency, so the two tools release
|
|
@@ -204,6 +206,7 @@ The full argument, including what this deliberately does not compete on:
|
|
|
204
206
|
```bash
|
|
205
207
|
python3 -m pip install maintainability-agent
|
|
206
208
|
maintainability-agent --root . --config maintainability-agent.json
|
|
209
|
+
maintainability-agent --update # later: upgrade, re-sync the skill, restart stale MCP servers
|
|
207
210
|
```
|
|
208
211
|
|
|
209
212
|
Or run from a source checkout without installing:
|
|
@@ -267,6 +270,21 @@ withheld estimate. For PR work, add `--changed-only main...HEAD` to audit the
|
|
|
267
270
|
diff; on a change too small to support a rate, the estimate and grade are
|
|
268
271
|
withheld and the scope is named as the reason.
|
|
269
272
|
|
|
273
|
+
**Hold the code a change touches to a stricter bar.** `policy.changed_code` in
|
|
274
|
+
`maintainability-agent.json` sets tighter function limits for what a change
|
|
275
|
+
adds or alters, so a team can gate new work without first fixing every old
|
|
276
|
+
function:
|
|
277
|
+
|
|
278
|
+
```json
|
|
279
|
+
"policy": {"changed_code": {"max_function_lines": 40, "max_complexity": 10}}
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
On a `--changed-only` run, a function the change touched is held to it and
|
|
283
|
+
untouched code is judged by the standard as before. A policy only tightens — a
|
|
284
|
+
looser limit is refused when the config loads — and it decides the gate, never
|
|
285
|
+
the grade: breaches fail `--fail-on-gate` and are listed under *Changed-code
|
|
286
|
+
policy*, and the score is unchanged.
|
|
287
|
+
|
|
270
288
|
### Checking that the agent did the work
|
|
271
289
|
|
|
272
290
|
The work order tells an agent to fix exactly these findings and refactor nothing
|
|
@@ -503,8 +521,9 @@ maintainability-agent --install-skill # writes ~/.claude/skills
|
|
|
503
521
|
```
|
|
504
522
|
|
|
505
523
|
`maintainability-agent --update` upgrades the install to the newest release —
|
|
506
|
-
never a downgrade — re-syncs the skill, and
|
|
507
|
-
|
|
524
|
+
never a downgrade — re-syncs the skill, and stops any MCP server still on an
|
|
525
|
+
older version that is not mid-audit, so the host starts the new one on its
|
|
526
|
+
next call; `maintainability-agent --install-updater` runs it hourly (macOS launch
|
|
508
527
|
agent). Run `--install-skill` by hand after any other upgrade — a drifted skill
|
|
509
528
|
teaches agents a dead workflow,
|
|
510
529
|
so a differing installed copy is refused with the list of differences. Per-host
|
|
@@ -517,7 +536,7 @@ instead of an invokable skill:
|
|
|
517
536
|
This repo ships `action.yml`, usable as a composite action:
|
|
518
537
|
|
|
519
538
|
```yaml
|
|
520
|
-
- uses: marshallguillory86/maintainability-agent@v4.4.
|
|
539
|
+
- uses: marshallguillory86/maintainability-agent@v4.4.6
|
|
521
540
|
with:
|
|
522
541
|
config: maintainability-agent.json
|
|
523
542
|
changed-only: main...HEAD
|
|
@@ -185,6 +185,7 @@ tests/test_analyzer_scoring_path.py
|
|
|
185
185
|
tests/test_analyzer_spread_range.py
|
|
186
186
|
tests/test_analyzer_xml_bounds.py
|
|
187
187
|
tests/test_analyzers_against_the_real_tools.py
|
|
188
|
+
tests/test_analyzers_leave_no_temp_dirs.py
|
|
188
189
|
tests/test_analyzers_never_write.py
|
|
189
190
|
tests/test_analyzers_report_what_actually_failed.py
|
|
190
191
|
tests/test_anchor_and_mode.py
|
|
@@ -206,6 +207,7 @@ tests/test_band_concealment_class.py
|
|
|
206
207
|
tests/test_band_concealment_p3.py
|
|
207
208
|
tests/test_band_pressures.py
|
|
208
209
|
tests/test_bands.py
|
|
210
|
+
tests/test_base_ref_only_where_it_exists.py
|
|
209
211
|
tests/test_behaviour_suites_are_tests.py
|
|
210
212
|
tests/test_body_or_signature_class.py
|
|
211
213
|
tests/test_both_setup_paths_ask_the_same_stage.py
|
{maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_adapters.py
RENAMED
|
@@ -236,6 +236,29 @@ class BaseAdapter:
|
|
|
236
236
|
# Empty means "trust the catalog entry".
|
|
237
237
|
languages: tuple[str, ...] = ()
|
|
238
238
|
|
|
239
|
+
def scratch(self) -> Path:
|
|
240
|
+
"""This run's scratch directory, made on first use (D235).
|
|
241
|
+
|
|
242
|
+
Four adapters made one with `mkdtemp` in their constructors and
|
|
243
|
+
never removed it, so every adapter object left a directory whether
|
|
244
|
+
or not its tool ran: 74,535 of them on one machine. Made here only
|
|
245
|
+
when a run needs it; `release` removes it.
|
|
246
|
+
"""
|
|
247
|
+
made = getattr(self, "_scratch_dir", None)
|
|
248
|
+
if made is None:
|
|
249
|
+
import tempfile
|
|
250
|
+
|
|
251
|
+
made = Path(tempfile.mkdtemp(prefix=f"{self.slug}-"))
|
|
252
|
+
self._scratch_dir = made
|
|
253
|
+
return made
|
|
254
|
+
|
|
255
|
+
def release(self) -> None:
|
|
256
|
+
"""Remove the scratch directory, if a run made one."""
|
|
257
|
+
made = getattr(self, "_scratch_dir", None)
|
|
258
|
+
if made is not None:
|
|
259
|
+
shutil.rmtree(made, ignore_errors=True)
|
|
260
|
+
self._scratch_dir = None
|
|
261
|
+
|
|
239
262
|
def version_argv(self) -> tuple[str, ...]:
|
|
240
263
|
return (self.executable, self.version_flag)
|
|
241
264
|
|
{maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_analysis.py
RENAMED
|
@@ -422,6 +422,12 @@ def _run_one(root: Path, adapter: Any, probe: Probe, timeout: int,
|
|
|
422
422
|
"concern it covers is reported unexamined."
|
|
423
423
|
),
|
|
424
424
|
)
|
|
425
|
+
finally:
|
|
426
|
+
# Every path, the backstop's included: a scratch dir left behind is
|
|
427
|
+
# one per run, forever (D235).
|
|
428
|
+
release = getattr(adapter, "release", None)
|
|
429
|
+
if release is not None:
|
|
430
|
+
release()
|
|
425
431
|
|
|
426
432
|
|
|
427
433
|
def _cover_one(selected: Selected, root: Path, probe: Probe, timeout: int,
|
|
@@ -14,7 +14,6 @@ from __future__ import annotations
|
|
|
14
14
|
|
|
15
15
|
import dataclasses
|
|
16
16
|
import json
|
|
17
|
-
import tempfile
|
|
18
17
|
from collections.abc import Iterable, Sequence
|
|
19
18
|
from pathlib import Path
|
|
20
19
|
from typing import Any
|
|
@@ -167,7 +166,6 @@ class CheckstyleAdapter(BaseAdapter):
|
|
|
167
166
|
findings_exit_codes=tuple(range(254)),
|
|
168
167
|
languages=("java",),
|
|
169
168
|
)
|
|
170
|
-
self._work = Path(tempfile.mkdtemp(prefix="checkstyle-"))
|
|
171
169
|
|
|
172
170
|
def has_targets(self, root: Path, excludes: Sequence[str] = ()) -> bool:
|
|
173
171
|
"""Whether any .java file survives the exclusions (never spawn empty)."""
|
|
@@ -189,7 +187,7 @@ class CheckstyleAdapter(BaseAdapter):
|
|
|
189
187
|
# resolves its optional checkstyle-suppressions.xml against
|
|
190
188
|
# the working directory, and the audited tree must not be
|
|
191
189
|
# able to suppress its own findings (audit M2).
|
|
192
|
-
cwd=self.
|
|
190
|
+
cwd=self.scratch(),
|
|
193
191
|
)
|
|
194
192
|
|
|
195
193
|
def _read(self, result: ToolResult) -> Extraction:
|
|
@@ -265,15 +263,19 @@ class SpotBugsAdapter(BaseAdapter):
|
|
|
265
263
|
# default detectors include the SECURITY category. A bundled
|
|
266
264
|
# exclude filter — written to this adapter's own scratch dir,
|
|
267
265
|
# never read from the audited tree — keeps that boundary real
|
|
268
|
-
# instead of documentation (48293d3 audit M1).
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
266
|
+
# instead of documentation (48293d3 audit M1). Written when a run
|
|
267
|
+
# needs it, into a scratch dir removed after the run (D235).
|
|
268
|
+
|
|
269
|
+
def _exclude_filter(self) -> Path:
|
|
270
|
+
path = self.scratch() / "exclude-security.xml"
|
|
271
|
+
if not path.exists():
|
|
272
|
+
path.write_text(
|
|
273
|
+
"<FindBugsFilter>\n"
|
|
274
|
+
' <Match><Bug category="SECURITY"/></Match>\n'
|
|
275
|
+
"</FindBugsFilter>\n",
|
|
276
|
+
encoding="utf-8",
|
|
277
|
+
)
|
|
278
|
+
return path
|
|
277
279
|
|
|
278
280
|
def version_argv(self) -> tuple[str, ...]:
|
|
279
281
|
return ("spotbugs", "-version")
|
|
@@ -347,7 +349,7 @@ class SpotBugsAdapter(BaseAdapter):
|
|
|
347
349
|
dirs = self._target_dirs(root, class_dirs)
|
|
348
350
|
return Invocation(
|
|
349
351
|
argv=("spotbugs", "-textui", "-exitcode", "-xml:withMessages",
|
|
350
|
-
"-exclude", str(self.
|
|
352
|
+
"-exclude", str(self._exclude_filter()),
|
|
351
353
|
*(str(directory) for directory in dirs)),
|
|
352
354
|
findings_exit_codes=self.findings_exit_codes,
|
|
353
355
|
)
|
|
@@ -14,7 +14,6 @@ import csv
|
|
|
14
14
|
import io
|
|
15
15
|
import json
|
|
16
16
|
import re
|
|
17
|
-
import tempfile
|
|
18
17
|
from collections.abc import Iterable, Sequence
|
|
19
18
|
from pathlib import Path
|
|
20
19
|
|
|
@@ -196,7 +195,6 @@ class ComplexipyAdapter(BaseAdapter):
|
|
|
196
195
|
slug="complexipy", emits="metric", executable="complexipy",
|
|
197
196
|
concepts=("cognitive_complexity",), findings_exit_codes=(0, 1),
|
|
198
197
|
)
|
|
199
|
-
self._work = Path(tempfile.mkdtemp(prefix="complexipy-"))
|
|
200
198
|
|
|
201
199
|
def target_files(self, root: Path, excludes: Sequence[str] = ()) -> tuple[str, ...]:
|
|
202
200
|
return expand_files(root.resolve(), excludes)
|
|
@@ -212,11 +210,11 @@ class ComplexipyAdapter(BaseAdapter):
|
|
|
212
210
|
return Invocation(
|
|
213
211
|
argv=(self.executable, *targets, "--output-format", "json", "--quiet"),
|
|
214
212
|
findings_exit_codes=self.findings_exit_codes,
|
|
215
|
-
cwd=self.
|
|
213
|
+
cwd=self.scratch(),
|
|
216
214
|
)
|
|
217
215
|
|
|
218
216
|
def _read(self, result: ToolResult) -> Extraction:
|
|
219
|
-
report = self.
|
|
217
|
+
report = self.scratch() / "complexipy-results.json"
|
|
220
218
|
if not report.exists():
|
|
221
219
|
raise ValueError("complexipy wrote no results file")
|
|
222
220
|
entries = json.loads(report.read_text(encoding="utf-8"))
|
|
@@ -20,7 +20,6 @@ for analyzability and testability. Two kinds of number, two modules.
|
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
|
|
22
22
|
import json
|
|
23
|
-
import tempfile
|
|
24
23
|
from collections.abc import Iterable, Sequence
|
|
25
24
|
from pathlib import Path
|
|
26
25
|
|
|
@@ -64,8 +63,8 @@ class JscpdAdapter(BaseAdapter):
|
|
|
64
63
|
# picks the destination when it builds the invocation and reads it
|
|
65
64
|
# back when parsing. A scratch directory rather than the scanned
|
|
66
65
|
# tree: writing into the repository under audit would change what
|
|
67
|
-
# the next tool sees.
|
|
68
|
-
|
|
66
|
+
# the next tool sees. Made on first use and removed after the
|
|
67
|
+
# run (`BaseAdapter.scratch`, D235).
|
|
69
68
|
|
|
70
69
|
def version_argv(self) -> tuple[str, ...]:
|
|
71
70
|
return _npx("jscpd", "--version")
|
|
@@ -91,11 +90,11 @@ class JscpdAdapter(BaseAdapter):
|
|
|
91
90
|
ignore = ("--ignore", ",".join(patterns)) if patterns else ()
|
|
92
91
|
return Invocation(
|
|
93
92
|
argv=(*_npx("jscpd"), str(root), "--reporters", "json", "--silent",
|
|
94
|
-
*ignore, "--output", str(self.
|
|
93
|
+
*ignore, "--output", str(self.scratch())),
|
|
95
94
|
)
|
|
96
95
|
|
|
97
96
|
def _read(self, result: ToolResult) -> Extraction:
|
|
98
|
-
report = self.
|
|
97
|
+
report = self.scratch() / "jscpd-report.json"
|
|
99
98
|
raw = report.read_text(encoding="utf-8") if report.exists() else result.stdout
|
|
100
99
|
if not raw.strip():
|
|
101
100
|
# No report file and no stdout is "ran, produced nothing",
|
{maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/cli.py
RENAMED
|
@@ -43,7 +43,7 @@ from .config import (
|
|
|
43
43
|
load_config,
|
|
44
44
|
repository_path,
|
|
45
45
|
)
|
|
46
|
-
from .git_tools import changed_paths
|
|
46
|
+
from .git_tools import GitCommandFailed, changed_paths
|
|
47
47
|
from .instructions import (
|
|
48
48
|
INSTRUCTION_TARGETS,
|
|
49
49
|
UnknownTarget,
|
|
@@ -492,7 +492,14 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
492
492
|
return 0
|
|
493
493
|
|
|
494
494
|
selection = _selection_from(parser, args.work)
|
|
495
|
-
|
|
495
|
+
try:
|
|
496
|
+
only_paths = changed_paths(root, args.changed_only) if args.changed_only else None
|
|
497
|
+
except GitCommandFailed as unresolved:
|
|
498
|
+
# A range git cannot resolve is a bad input, said so by name, not a
|
|
499
|
+
# traceback a pipeline cannot tell from a broken tool (D234).
|
|
500
|
+
print(f"maintainability-agent: --changed-only {args.changed_only} cannot be "
|
|
501
|
+
f"resolved ({unresolved})", file=sys.stderr)
|
|
502
|
+
return 2
|
|
496
503
|
external_findings = read_sarif_inputs(args.sarif_input)
|
|
497
504
|
report = build_report(root, config, only_paths=only_paths,
|
|
498
505
|
changed_revspec=args.changed_only,
|
{maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_primary_estimate.py
RENAMED
|
@@ -31,8 +31,6 @@ calibration constant against the new path is 3.6.
|
|
|
31
31
|
from __future__ import annotations
|
|
32
32
|
|
|
33
33
|
import subprocess
|
|
34
|
-
import tempfile
|
|
35
|
-
from pathlib import Path
|
|
36
34
|
|
|
37
35
|
import pytest
|
|
38
36
|
|
|
@@ -44,9 +42,9 @@ from maintainability_audit.scoring import score_evidence
|
|
|
44
42
|
|
|
45
43
|
|
|
46
44
|
@pytest.fixture
|
|
47
|
-
def evidence():
|
|
45
|
+
def evidence(tmp_path):
|
|
48
46
|
"""A committed tree of ordinary small functions, scored cleanly."""
|
|
49
|
-
root =
|
|
47
|
+
root = tmp_path / "r"
|
|
50
48
|
root.mkdir()
|
|
51
49
|
subprocess.run(["git", "init", "-q", str(root)], check=True)
|
|
52
50
|
(root / "README.md").write_text("# r\n", encoding="utf-8")
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"""An analyzer leaves nothing behind in the system temp directory (D235).
|
|
2
|
+
|
|
3
|
+
Four adapters — jscpd, complexipy, checkstyle, spotbugs — made a scratch
|
|
4
|
+
directory with `tempfile.mkdtemp` in their constructors and never removed
|
|
5
|
+
it. Every adapter object built left a directory, whether or not its tool
|
|
6
|
+
ever ran: the registry is built on every audit and many times in every
|
|
7
|
+
test run, so one machine's temp directory held 74,535 of them (21,294
|
|
8
|
+
`jscpd-`, 20,185 `complexipy-`, 16,952 `checkstyle-`, 16,104 `spotbugs-`)
|
|
9
|
+
on a disk at 98%, and removing them freed 13.5 GB.
|
|
10
|
+
|
|
11
|
+
A scratch directory is now made only when a tool is about to run, and is
|
|
12
|
+
removed once its output has been read, whatever the outcome.
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import tempfile
|
|
18
|
+
from pathlib import Path
|
|
19
|
+
from types import SimpleNamespace
|
|
20
|
+
|
|
21
|
+
import pytest
|
|
22
|
+
|
|
23
|
+
from maintainability_audit import _analysis
|
|
24
|
+
from maintainability_audit._generic import DECLARED, declared_adapter
|
|
25
|
+
from maintainability_audit._runner import Outcome, ToolResult
|
|
26
|
+
from maintainability_audit._tool_adapters import ADAPTERS
|
|
27
|
+
|
|
28
|
+
SCRATCH_ADAPTERS = ("jscpd", "complexipy", "checkstyle", "spotbugs")
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@pytest.fixture
|
|
32
|
+
def temp_root(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
|
|
33
|
+
"""The system temp directory, redirected to one this test can count."""
|
|
34
|
+
root = tmp_path / "system-temp"
|
|
35
|
+
root.mkdir()
|
|
36
|
+
monkeypatch.setattr(tempfile, "tempdir", str(root))
|
|
37
|
+
return root
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def test_building_every_adapter_makes_no_directory(temp_root: Path) -> None:
|
|
41
|
+
adapters = [make() for make in ADAPTERS.values()] + [declared_adapter(slug) for slug in DECLARED]
|
|
42
|
+
|
|
43
|
+
assert len(adapters) > 10
|
|
44
|
+
assert list(temp_root.iterdir()) == []
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@pytest.mark.parametrize("slug", SCRATCH_ADAPTERS)
|
|
48
|
+
def test_a_run_removes_its_scratch_directory_whatever_the_outcome(
|
|
49
|
+
slug: str, temp_root: Path, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
|
|
50
|
+
tree = tmp_path / "tree"
|
|
51
|
+
tree.mkdir()
|
|
52
|
+
(tree / "A.java").write_text("class A {}\n", encoding="utf-8")
|
|
53
|
+
(tree / "a.py").write_text("x = 1\n", encoding="utf-8")
|
|
54
|
+
(tree / "build" / "classes").mkdir(parents=True)
|
|
55
|
+
(tree / "build" / "classes" / "A.class").write_bytes(b"\xca\xfe\xba\xbe")
|
|
56
|
+
monkeypatch.setattr(_analysis, "run", lambda tool, invocation, **k: ToolResult(
|
|
57
|
+
slug=tool, outcome=Outcome.RAN, stdout="", stderr="", exit_code=0))
|
|
58
|
+
probe = SimpleNamespace(check=lambda tool, argv: SimpleNamespace(
|
|
59
|
+
usable=True, version="1", outcome=Outcome.RAN, detail=""))
|
|
60
|
+
|
|
61
|
+
_analysis._run_one(tree, ADAPTERS[slug](), probe, 60, _analysis.Analysis())
|
|
62
|
+
|
|
63
|
+
assert list(temp_root.iterdir()) == []
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_no_test_makes_a_temp_directory_it_never_removes() -> None:
|
|
67
|
+
"""The suite's own share of the same leak: `mkdtemp` is never cleaned up.
|
|
68
|
+
|
|
69
|
+
`tmp_path` is pytest's and is pruned; `TemporaryDirectory` removes
|
|
70
|
+
itself. A bare `mkdtemp` in a test leaves one directory per run.
|
|
71
|
+
"""
|
|
72
|
+
tests = Path(__file__).resolve().parent
|
|
73
|
+
offenders = sorted(
|
|
74
|
+
path.name for path in tests.glob("*.py")
|
|
75
|
+
if path.name != Path(__file__).name and "mkdtemp(" in path.read_text(encoding="utf-8")
|
|
76
|
+
)
|
|
77
|
+
assert offenders == [], f"these tests leave a temp directory behind: {offenders}"
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_every_test_writes_its_temp_files_under_pytests_own_base(
|
|
81
|
+
tmp_path: Path, tmp_path_factory: pytest.TempPathFactory) -> None:
|
|
82
|
+
"""A test that builds an adapter and calls it piecemeal never reaches the
|
|
83
|
+
release in `_run_one`; the suite left 29 directories that way after the
|
|
84
|
+
adapters were fixed. So no test can write to the system temp directory —
|
|
85
|
+
and not into `tmp_path` either, which is often the tree under audit."""
|
|
86
|
+
temp = Path(tempfile.gettempdir()).resolve()
|
|
87
|
+
assert temp.is_relative_to(tmp_path_factory.getbasetemp().resolve())
|
|
88
|
+
assert not temp.is_relative_to(tmp_path.resolve())
|
{maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_artifact_write_route_class.py
RENAMED
|
@@ -93,10 +93,16 @@ def test_no_artifact_writer_reaches_for_a_raw_write_text() -> None:
|
|
|
93
93
|
)
|
|
94
94
|
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
@pytest.fixture
|
|
97
|
+
def inward_repo():
|
|
97
98
|
"""A repo under ``/var`` (unresolved on macOS) whose ``.maintainability``
|
|
98
|
-
is a symlink back into ``src`` -- the redirect ``tmp_path`` cannot make.
|
|
99
|
-
|
|
99
|
+
is a symlink back into ``src`` -- the redirect ``tmp_path`` cannot make.
|
|
100
|
+
Removed afterwards; a bare ``mkdtemp`` left one per run (D235)."""
|
|
101
|
+
with tempfile.TemporaryDirectory(dir="/var/tmp") as base:
|
|
102
|
+
yield _inward_symlink_repo(Path(base))
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _inward_symlink_repo(base: Path) -> Path:
|
|
100
106
|
root = base / "repo"
|
|
101
107
|
(root / "src").mkdir(parents=True)
|
|
102
108
|
(root / "src" / "app.py").write_text("x = 1\n", encoding="utf-8")
|
|
@@ -109,12 +115,12 @@ def _report(root: Path) -> dict:
|
|
|
109
115
|
|
|
110
116
|
|
|
111
117
|
@pytest.mark.parametrize("spelling", ["/var", "/private/var"])
|
|
112
|
-
def test_write_baseline_refuses_the_inward_route_on_either_spelling(spelling: str) -> None:
|
|
118
|
+
def test_write_baseline_refuses_the_inward_route_on_either_spelling(spelling: str, inward_repo: Path) -> None:
|
|
113
119
|
"""``.maintainability -> src`` is refused whether the grant is named
|
|
114
120
|
``/var/...`` or its ``/private/var/...`` real path. Binding the check
|
|
115
121
|
to ``target.parent`` checked the symlink against itself and let both
|
|
116
122
|
through."""
|
|
117
|
-
root =
|
|
123
|
+
root = inward_repo
|
|
118
124
|
if spelling == "/private/var":
|
|
119
125
|
root = Path(os.path.realpath(root))
|
|
120
126
|
target = root / ".maintainability" / "baseline.json"
|
|
@@ -125,11 +131,11 @@ def test_write_baseline_refuses_the_inward_route_on_either_spelling(spelling: st
|
|
|
125
131
|
assert not (Path(os.path.realpath(root)) / "src" / "baseline.json").exists()
|
|
126
132
|
|
|
127
133
|
|
|
128
|
-
def test_write_baseline_refuses_to_truncate_a_non_json_file() -> None:
|
|
134
|
+
def test_write_baseline_refuses_to_truncate_a_non_json_file(inward_repo: Path) -> None:
|
|
129
135
|
"""``write_baseline(baseline_path="README.md")`` truncated source once
|
|
130
136
|
(D34). A stage-and-replace still unlinks that inode, so the refusal is
|
|
131
137
|
on the existing bytes not being JSON, before any stage begins."""
|
|
132
|
-
root =
|
|
138
|
+
root = inward_repo
|
|
133
139
|
readme = root / "README.md"
|
|
134
140
|
readme.write_text("# real docs\n", encoding="utf-8")
|
|
135
141
|
report = _report(root)
|
|
@@ -138,11 +144,11 @@ def test_write_baseline_refuses_to_truncate_a_non_json_file() -> None:
|
|
|
138
144
|
assert readme.read_text(encoding="utf-8") == "# real docs\n"
|
|
139
145
|
|
|
140
146
|
|
|
141
|
-
def test_a_baseline_outside_the_tree_is_still_allowed() -> None:
|
|
147
|
+
def test_a_baseline_outside_the_tree_is_still_allowed(inward_repo: Path) -> None:
|
|
142
148
|
"""The predating contract: a person may keep a baseline outside the
|
|
143
149
|
audited tree. Outside the grant the tree cannot plant a route, so the
|
|
144
150
|
write proceeds -- the refusals above do not become a new bound."""
|
|
145
|
-
root =
|
|
151
|
+
root = inward_repo
|
|
146
152
|
outside = root.parent / "backups" / "baseline.json"
|
|
147
153
|
write_baseline(str(outside), _report(root))
|
|
148
154
|
assert json.loads(outside.read_text(encoding="utf-8"))["version"] == 3
|