maintainability-agent 4.0.1__tar.gz → 4.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {maintainability_agent-4.0.1/src/maintainability_agent.egg-info → maintainability_agent-4.2.0}/PKG-INFO +17 -4
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/README.md +16 -3
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0/src/maintainability_agent.egg-info}/PKG-INFO +17 -4
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_agent.egg-info/SOURCES.txt +7 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_adapters.py +17 -1
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_analysis.py +46 -4
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_calibration.py +9 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_jvm_adapters.py +8 -8
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_metric_adapters.py +22 -31
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_operator_reads.py +3 -1
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_runner.py +35 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_security_delegate.py +23 -1
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_verdict_adapters.py +4 -1
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/config.py +19 -2
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/report.py +5 -4
- maintainability_agent-4.2.0/tests/test_a_rendered_docs_site_is_not_scored_as_source.py +61 -0
- maintainability_agent-4.2.0/tests/test_analyzer_file_lists_are_batched.py +114 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_provenance.py +10 -21
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_calibration_tooling.py +116 -0
- maintainability_agent-4.2.0/tests/test_cohesion_with_nothing_to_read_is_not_applicable.py +37 -0
- maintainability_agent-4.2.0/tests/test_exclude_additional_keeps_the_defaults.py +53 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_file_list_cap_class.py +17 -15
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_readme_claims.py +16 -0
- maintainability_agent-4.2.0/tests/test_regular_file_reads_work_without_o_nonblock.py +28 -0
- maintainability_agent-4.2.0/tests/test_scanner_fingerprint_covers_the_measurement_path.py +75 -0
- maintainability_agent-4.2.0/tests/test_the_security_run_has_a_configurable_limit.py +61 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/LICENSE +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/pyproject.toml +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/setup.cfg +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_agent.egg-info/requires.txt +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_analyzer_sections.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_anchor.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_banner.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_catalog.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_cognitive.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_coverage_notes.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_criteria_scope.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_delegated_pillar.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_evidence_reader.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_first_run.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_gates.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_grammar.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_handoff.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_html_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_in_loop.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_in_loop_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_mcp_audit.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_mcp_setup.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_oracle.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_precommit.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_precommit_install.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_precommit_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_prompt_sections.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_cobol.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_go.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_kotlin.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_php.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_ruby.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_rust.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_shell.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_ratio_adapters.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_running_version.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_security_work_order.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_setup_persist.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/cli.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/mcp_server.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/prompts.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/renderers.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_a_clone_names_every_copy.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_a_dangling_source_link_is_named_not_fatal.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_a_format_override_is_disclosed.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_a_matching_format_stays_silent.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_a_published_question_offers_what_it_accepts.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_a_setup_question_keeps_its_contract.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_adapters.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_added_lines.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_an_absent_work_order_renders_nothing.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_an_unmeasured_pillar_reports_no_number.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_anchor_and_mode.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_anchor_disclosure.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_architecture.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_attestation.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_audit_components.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_backfill.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_bands.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_behaviour_suites_are_tests.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_both_setup_paths_ask_the_same_stage.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_chat_leads_with_the_work_order.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_check_refuses_plus_only_fragments.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_child_sandbox.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_clean_sees_the_weakened_oracle.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_cli.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_code_scanning_gets_alerts_not_the_record.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_config_shape.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_conformance_reads_the_operators_ask.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_consent_is_per_repository.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_consent_survives_setup_and_is_asked.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_consent_without_command_has_a_remedy.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_corpus_note_counts_come_from_the_corpus.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_corroborate.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_coverage_config_reaches_children.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_coverage_formats.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_criteria_completion.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_current_state_docs_name_every_parsed_language.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_dead_code.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_declaration_criteria_scope.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_declarative_parsers.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_declared_capabilities_match_the_delegate.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_delegated_security_pillar.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_demo_tree.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_determinism.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_discovery.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_docs_links.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_economic_context.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_every_built_presentation_is_offered.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_every_language_counts_its_own_loop.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_every_language_has_a_loop_fixture.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_every_pool_install_is_the_same_pool.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_every_question_can_be_answered.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_every_surface_says_what_the_run_found.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_example_config_opens_claimed_languages.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_exposure_never_outranks_band.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_first_run_elicitation.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_first_stage_setup_wording_holds.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_format_ask.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_git_argv.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_go_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_grammar_constructs.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_grammar_token_coverage.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_grok_audit_of_3_11.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_history.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_history_window.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_html_executive.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_in_loop_budgets.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_in_loop_check.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_java_scored.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_kotlin_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_kotlin_metrics.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_language_support_honesty.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_list_tools_publishes_the_answer_path.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_maintenance_signals.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_mcp_format_contract.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_mcp_start_failure_names_what_is_installed.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_missing_security_scanners_are_named_before_the_run.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_mutation_recorded.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_operator_named_paths.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_operator_named_reads.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_oracle_weakening_precision_bar.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_pairing_reads_imports.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_php_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_platform_claim.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_policy_claims.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_population_floors.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_precommit_staged.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_preflight_before_consent_runs_nothing_from_the_tree.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_previous_release_reached_pypi.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_promises.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_python_complexity.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_recurrence.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_release_needs_an_empty_ledger.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_release_plan.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_rendered_docs.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_root_grants.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_ruby_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_runner.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_rust_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_sarif.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_scan_history.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_scanner_unsafe_direction.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_scanning.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_security_delegate_versions_agree.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_security_findings_keep_their_handoff.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_security_pillar_asserts_a_scanner_set.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_security_pillar_runs_and_shows.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_selection_covers_every_parsed_language.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_semantic_findings_stay_inside_the_audited_files.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_setup_answers_are_the_same_setup.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_setup_instruction_describes_its_own_reply.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_setup_writes_a_valid_config.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_shell_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_shell_metrics.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_skill_install.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_sonar_resolve.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_source_index.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_stamped_documents_stay_honest.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_stdout_outputs.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_terminal_asks_the_same_questions.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_test_commands.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_agent_knows_when_it_is_stale.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_changelog_covers_the_shipping_version.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_chat_payload_has_a_budget.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_condition_says_what_it_measured.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_handoff_rules_are_their_own_module.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_pillar_row_reads_cleanly.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_presentation_question_stays_answerable.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_previous_release_was_tagged.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_prompt_does_not_take_back_what_it_withheld.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_prompt_keeps_listing_what_it_did_not_withhold.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_release_process_describes_itself.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_release_record_stays_well_formed.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_report_is_saved_not_sent.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_security_work_order_is_drawn.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_suite_names_the_program_it_ran.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_tree_cannot_redirect_a_read.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_the_version_has_one_source.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_tool_resolution.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_tree_chosen_spawn.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_tree_reads_use_the_primitive.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_trends.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_unanchored_set_matches_corpus.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_unread_code.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_version_claim.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_version_stamping.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_withheld_work_keeps_its_boundary.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_work_items_state_their_own_finding.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_work_order.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/tests/test_written_record.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 4.0
|
|
3
|
+
Version: 4.2.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -47,7 +47,7 @@ Dynamic: license-file
|
|
|
47
47
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
48
48
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
49
49
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
50
|
-
Version **4.0
|
|
50
|
+
Version **4.2.0**.
|
|
51
51
|
|
|
52
52
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
53
53
|
>
|
|
@@ -56,6 +56,11 @@ Version **4.0.1**.
|
|
|
56
56
|
> taste, each pinned to the exact commit it was measured at, so anyone can
|
|
57
57
|
> re-run the calibration and get the same numbers. The median of that corpus
|
|
58
58
|
> scores a **B**. [How the corpus is chosen and measured](docs/standard.md#the-reference-corpus).
|
|
59
|
+
>
|
|
60
|
+
> So your grade places your code against those 201: a **B** means you are at
|
|
61
|
+
> the median of mature, widely used open source. The corpus is re-measured
|
|
62
|
+
> whenever the instrument changes — in 4.1.0 every file of even the largest
|
|
63
|
+
> repositories was read, and the scale came back unchanged to four decimals.
|
|
59
64
|
|
|
60
65
|
**Languages parsed:** Python, Java, Kotlin, C, C++, C#, Go, Rust, PHP, Ruby,
|
|
61
66
|
Swift, Shell, COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -93,7 +98,10 @@ you what it could not measure.
|
|
|
93
98
|
**Install secure-code-agent for the security pillar.** Every audit runs it; it is
|
|
94
99
|
installed alongside rather than as a dependency, so the two tools release
|
|
95
100
|
independently. Without it the report says the security pillar was not measured
|
|
96
|
-
and gives this command.
|
|
101
|
+
and gives this command. A full security run can take several minutes on a
|
|
102
|
+
large repository; the audit waits up to 15 minutes for it, and
|
|
103
|
+
`security.timeout_seconds` in `maintainability-agent.json` changes that. Its
|
|
104
|
+
scanners decide what it can grade — see
|
|
97
105
|
[machine setup](docs/machine-setup.md#3-toolchain) for which to install, and
|
|
98
106
|
don't add its `[mcp]` extra to this environment (it pins `mcp<2`).
|
|
99
107
|
|
|
@@ -356,6 +364,11 @@ signals on:
|
|
|
356
364
|
- an ISO/IEC 25010-inspired 0–5 estimate per category, and a verified grade —
|
|
357
365
|
or a disclosed withholding when the evidence is thin.
|
|
358
366
|
|
|
367
|
+
**Large repositories are measured whole.** Every file is handed to the
|
|
368
|
+
analyzers, split across as many runs as the command line needs, so a big
|
|
369
|
+
codebase is read rather than sampled — FFmpeg's 4,687 files, not the first
|
|
370
|
+
1,543 that fitted on one command line before 4.1.0.
|
|
371
|
+
|
|
359
372
|
The analyzer is intentionally conservative and under-reports rather than
|
|
360
373
|
over-reports: an unrecognized declaration costs one missed finding, never a
|
|
361
374
|
cascade of false ones. Pair it with native tools (ESLint, Ruff, Radon, Semgrep,
|
|
@@ -496,7 +509,7 @@ instead of an invokable skill:
|
|
|
496
509
|
This repo ships `action.yml`, usable as a composite action:
|
|
497
510
|
|
|
498
511
|
```yaml
|
|
499
|
-
- uses: marshallguillory86/maintainability-agent@v4.0
|
|
512
|
+
- uses: marshallguillory86/maintainability-agent@v4.2.0
|
|
500
513
|
with:
|
|
501
514
|
config: maintainability-agent.json
|
|
502
515
|
changed-only: main...HEAD
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
6
6
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
7
7
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
8
|
-
Version **4.0
|
|
8
|
+
Version **4.2.0**.
|
|
9
9
|
|
|
10
10
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
11
11
|
>
|
|
@@ -14,6 +14,11 @@ Version **4.0.1**.
|
|
|
14
14
|
> taste, each pinned to the exact commit it was measured at, so anyone can
|
|
15
15
|
> re-run the calibration and get the same numbers. The median of that corpus
|
|
16
16
|
> scores a **B**. [How the corpus is chosen and measured](docs/standard.md#the-reference-corpus).
|
|
17
|
+
>
|
|
18
|
+
> So your grade places your code against those 201: a **B** means you are at
|
|
19
|
+
> the median of mature, widely used open source. The corpus is re-measured
|
|
20
|
+
> whenever the instrument changes — in 4.1.0 every file of even the largest
|
|
21
|
+
> repositories was read, and the scale came back unchanged to four decimals.
|
|
17
22
|
|
|
18
23
|
**Languages parsed:** Python, Java, Kotlin, C, C++, C#, Go, Rust, PHP, Ruby,
|
|
19
24
|
Swift, Shell, COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -51,7 +56,10 @@ you what it could not measure.
|
|
|
51
56
|
**Install secure-code-agent for the security pillar.** Every audit runs it; it is
|
|
52
57
|
installed alongside rather than as a dependency, so the two tools release
|
|
53
58
|
independently. Without it the report says the security pillar was not measured
|
|
54
|
-
and gives this command.
|
|
59
|
+
and gives this command. A full security run can take several minutes on a
|
|
60
|
+
large repository; the audit waits up to 15 minutes for it, and
|
|
61
|
+
`security.timeout_seconds` in `maintainability-agent.json` changes that. Its
|
|
62
|
+
scanners decide what it can grade — see
|
|
55
63
|
[machine setup](docs/machine-setup.md#3-toolchain) for which to install, and
|
|
56
64
|
don't add its `[mcp]` extra to this environment (it pins `mcp<2`).
|
|
57
65
|
|
|
@@ -314,6 +322,11 @@ signals on:
|
|
|
314
322
|
- an ISO/IEC 25010-inspired 0–5 estimate per category, and a verified grade —
|
|
315
323
|
or a disclosed withholding when the evidence is thin.
|
|
316
324
|
|
|
325
|
+
**Large repositories are measured whole.** Every file is handed to the
|
|
326
|
+
analyzers, split across as many runs as the command line needs, so a big
|
|
327
|
+
codebase is read rather than sampled — FFmpeg's 4,687 files, not the first
|
|
328
|
+
1,543 that fitted on one command line before 4.1.0.
|
|
329
|
+
|
|
317
330
|
The analyzer is intentionally conservative and under-reports rather than
|
|
318
331
|
over-reports: an unrecognized declaration costs one missed finding, never a
|
|
319
332
|
cascade of false ones. Pair it with native tools (ESLint, Ruff, Radon, Semgrep,
|
|
@@ -454,7 +467,7 @@ instead of an invokable skill:
|
|
|
454
467
|
This repo ships `action.yml`, usable as a composite action:
|
|
455
468
|
|
|
456
469
|
```yaml
|
|
457
|
-
- uses: marshallguillory86/maintainability-agent@v4.0
|
|
470
|
+
- uses: marshallguillory86/maintainability-agent@v4.2.0
|
|
458
471
|
with:
|
|
459
472
|
config: maintainability-agent.json
|
|
460
473
|
changed-only: main...HEAD
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 4.0
|
|
3
|
+
Version: 4.2.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -47,7 +47,7 @@ Dynamic: license-file
|
|
|
47
47
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
48
48
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
49
49
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
50
|
-
Version **4.0
|
|
50
|
+
Version **4.2.0**.
|
|
51
51
|
|
|
52
52
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
53
53
|
>
|
|
@@ -56,6 +56,11 @@ Version **4.0.1**.
|
|
|
56
56
|
> taste, each pinned to the exact commit it was measured at, so anyone can
|
|
57
57
|
> re-run the calibration and get the same numbers. The median of that corpus
|
|
58
58
|
> scores a **B**. [How the corpus is chosen and measured](docs/standard.md#the-reference-corpus).
|
|
59
|
+
>
|
|
60
|
+
> So your grade places your code against those 201: a **B** means you are at
|
|
61
|
+
> the median of mature, widely used open source. The corpus is re-measured
|
|
62
|
+
> whenever the instrument changes — in 4.1.0 every file of even the largest
|
|
63
|
+
> repositories was read, and the scale came back unchanged to four decimals.
|
|
59
64
|
|
|
60
65
|
**Languages parsed:** Python, Java, Kotlin, C, C++, C#, Go, Rust, PHP, Ruby,
|
|
61
66
|
Swift, Shell, COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -93,7 +98,10 @@ you what it could not measure.
|
|
|
93
98
|
**Install secure-code-agent for the security pillar.** Every audit runs it; it is
|
|
94
99
|
installed alongside rather than as a dependency, so the two tools release
|
|
95
100
|
independently. Without it the report says the security pillar was not measured
|
|
96
|
-
and gives this command.
|
|
101
|
+
and gives this command. A full security run can take several minutes on a
|
|
102
|
+
large repository; the audit waits up to 15 minutes for it, and
|
|
103
|
+
`security.timeout_seconds` in `maintainability-agent.json` changes that. Its
|
|
104
|
+
scanners decide what it can grade — see
|
|
97
105
|
[machine setup](docs/machine-setup.md#3-toolchain) for which to install, and
|
|
98
106
|
don't add its `[mcp]` extra to this environment (it pins `mcp<2`).
|
|
99
107
|
|
|
@@ -356,6 +364,11 @@ signals on:
|
|
|
356
364
|
- an ISO/IEC 25010-inspired 0–5 estimate per category, and a verified grade —
|
|
357
365
|
or a disclosed withholding when the evidence is thin.
|
|
358
366
|
|
|
367
|
+
**Large repositories are measured whole.** Every file is handed to the
|
|
368
|
+
analyzers, split across as many runs as the command line needs, so a big
|
|
369
|
+
codebase is read rather than sampled — FFmpeg's 4,687 files, not the first
|
|
370
|
+
1,543 that fitted on one command line before 4.1.0.
|
|
371
|
+
|
|
359
372
|
The analyzer is intentionally conservative and under-reports rather than
|
|
360
373
|
over-reports: an unrecognized declaration costs one missed finding, never a
|
|
361
374
|
cascade of false ones. Pair it with native tools (ESLint, Ruff, Radon, Semgrep,
|
|
@@ -496,7 +509,7 @@ instead of an invokable skill:
|
|
|
496
509
|
This repo ships `action.yml`, usable as a composite action:
|
|
497
510
|
|
|
498
511
|
```yaml
|
|
499
|
-
- uses: marshallguillory86/maintainability-agent@v4.0
|
|
512
|
+
- uses: marshallguillory86/maintainability-agent@v4.2.0
|
|
500
513
|
with:
|
|
501
514
|
config: maintainability-agent.json
|
|
502
515
|
changed-only: main...HEAD
|
|
@@ -157,6 +157,7 @@ tests/test_a_dangling_source_link_is_named_not_fatal.py
|
|
|
157
157
|
tests/test_a_format_override_is_disclosed.py
|
|
158
158
|
tests/test_a_matching_format_stays_silent.py
|
|
159
159
|
tests/test_a_published_question_offers_what_it_accepts.py
|
|
160
|
+
tests/test_a_rendered_docs_site_is_not_scored_as_source.py
|
|
160
161
|
tests/test_a_setup_question_keeps_its_contract.py
|
|
161
162
|
tests/test_acquisition_trust.py
|
|
162
163
|
tests/test_adapter_docs.py
|
|
@@ -170,6 +171,7 @@ tests/test_analysis_execution.py
|
|
|
170
171
|
tests/test_analyzer_bridge.py
|
|
171
172
|
tests/test_analyzer_config_isolation.py
|
|
172
173
|
tests/test_analyzer_estimate_claims.py
|
|
174
|
+
tests/test_analyzer_file_lists_are_batched.py
|
|
173
175
|
tests/test_analyzer_pinning.py
|
|
174
176
|
tests/test_analyzer_primary_estimate.py
|
|
175
177
|
tests/test_analyzer_provenance.py
|
|
@@ -221,6 +223,7 @@ tests/test_clone_group_class.py
|
|
|
221
223
|
tests/test_cobol_declarations.py
|
|
222
224
|
tests/test_code_scanning_gets_alerts_not_the_record.py
|
|
223
225
|
tests/test_cognitive_complexity.py
|
|
226
|
+
tests/test_cohesion_with_nothing_to_read_is_not_applicable.py
|
|
224
227
|
tests/test_cohort_statistics.py
|
|
225
228
|
tests/test_concealment_properties.py
|
|
226
229
|
tests/test_config_shape.py
|
|
@@ -274,6 +277,7 @@ tests/test_evidence_invariants.py
|
|
|
274
277
|
tests/test_evidence_normalization.py
|
|
275
278
|
tests/test_evidence_properties.py
|
|
276
279
|
tests/test_example_config_opens_claimed_languages.py
|
|
280
|
+
tests/test_exclude_additional_keeps_the_defaults.py
|
|
277
281
|
tests/test_exclusion_dialects.py
|
|
278
282
|
tests/test_exposure_never_outranks_band.py
|
|
279
283
|
tests/test_falsifier_standard.py
|
|
@@ -365,6 +369,7 @@ tests/test_python_declarations.py
|
|
|
365
369
|
tests/test_read_boundary.py
|
|
366
370
|
tests/test_readme_claims.py
|
|
367
371
|
tests/test_recurrence.py
|
|
372
|
+
tests/test_regular_file_reads_work_without_o_nonblock.py
|
|
368
373
|
tests/test_release_needs_an_empty_ledger.py
|
|
369
374
|
tests/test_release_plan.py
|
|
370
375
|
tests/test_release_plan_status.py
|
|
@@ -379,6 +384,7 @@ tests/test_rust_declarations.py
|
|
|
379
384
|
tests/test_sarif.py
|
|
380
385
|
tests/test_scan_history.py
|
|
381
386
|
tests/test_scan_scope.py
|
|
387
|
+
tests/test_scanner_fingerprint_covers_the_measurement_path.py
|
|
382
388
|
tests/test_scanner_unsafe_direction.py
|
|
383
389
|
tests/test_scanning.py
|
|
384
390
|
tests/test_schema_fidelity.py
|
|
@@ -426,6 +432,7 @@ tests/test_the_prompt_keeps_listing_what_it_did_not_withhold.py
|
|
|
426
432
|
tests/test_the_release_process_describes_itself.py
|
|
427
433
|
tests/test_the_release_record_stays_well_formed.py
|
|
428
434
|
tests/test_the_report_is_saved_not_sent.py
|
|
435
|
+
tests/test_the_security_run_has_a_configurable_limit.py
|
|
429
436
|
tests/test_the_security_work_order_is_drawn.py
|
|
430
437
|
tests/test_the_suite_names_the_program_it_ran.py
|
|
431
438
|
tests/test_the_tree_cannot_redirect_a_read.py
|
{maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_adapters.py
RENAMED
|
@@ -35,7 +35,7 @@ from pathlib import Path
|
|
|
35
35
|
from typing import Any, Protocol
|
|
36
36
|
|
|
37
37
|
from ._metrics_types import Finding, Measurement
|
|
38
|
-
from ._runner import Invocation, ToolResult
|
|
38
|
+
from ._runner import Invocation, ToolResult, batches
|
|
39
39
|
|
|
40
40
|
|
|
41
41
|
class Exclusions(tuple): # noqa: SLOT001 - attribute is set once in __new__
|
|
@@ -315,6 +315,22 @@ class BaseAdapter:
|
|
|
315
315
|
cwd=root if self.exclude_dialect == "rel_regex" else None,
|
|
316
316
|
)
|
|
317
317
|
|
|
318
|
+
def target_files(self, root: Path, excludes: Sequence[str] = ()) -> tuple[str, ...] | None:
|
|
319
|
+
"""The explicit files this tool is handed, or None when it walks a directory."""
|
|
320
|
+
return None
|
|
321
|
+
|
|
322
|
+
def invocations(self, root: Path, excludes: Sequence[str] = ()) -> list[Invocation]:
|
|
323
|
+
"""Every run needed to read the whole tree.
|
|
324
|
+
|
|
325
|
+
One, for a tool that walks a directory. For a tool handed explicit
|
|
326
|
+
files, one per batch that fits a command line — the list used to
|
|
327
|
+
be cut to one argv instead, so the largest trees were read in part.
|
|
328
|
+
"""
|
|
329
|
+
files = self.target_files(root, excludes)
|
|
330
|
+
if not files:
|
|
331
|
+
return [self.invocation(root, excludes=excludes)]
|
|
332
|
+
return [self.invocation(root, batch, excludes=excludes) for batch in batches(files)]
|
|
333
|
+
|
|
318
334
|
def parse(self, result: ToolResult) -> Extraction:
|
|
319
335
|
if not result.usable:
|
|
320
336
|
return Extraction(parse_error=result.detail or f"{self.slug} did not run")
|
{maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_analysis.py
RENAMED
|
@@ -37,7 +37,7 @@ from ._built_ins import BUILT_IN_SOURCES
|
|
|
37
37
|
from ._catalog import CONCERNS, PolicyError, concepts_for, resolve_pool, settings_from
|
|
38
38
|
from ._discovery import CATALOG_LANGUAGE, discover
|
|
39
39
|
from ._metrics_types import KNOWN_SOURCE_SUFFIXES, Finding, Measurement
|
|
40
|
-
from ._runner import Outcome, Probe, run
|
|
40
|
+
from ._runner import Outcome, Probe, ToolResult, run
|
|
41
41
|
from ._selection import Selected, select_runnable
|
|
42
42
|
from .config import acquisition_permitted
|
|
43
43
|
|
|
@@ -446,12 +446,11 @@ def _attempt(root: Path, adapter: Any, probe: Probe, timeout: int,
|
|
|
446
446
|
),
|
|
447
447
|
)
|
|
448
448
|
|
|
449
|
-
result =
|
|
450
|
-
timeout_seconds=timeout)
|
|
449
|
+
result, parsed = _run_batches(adapter, root, excludes, timeout)
|
|
451
450
|
# Filtered before the counts are taken, not after. Recording 48
|
|
452
451
|
# measurements and reporting 6 describes an activity rather than a
|
|
453
452
|
# result, which is the defect this project keeps finding.
|
|
454
|
-
extraction = _ours_only_extraction(
|
|
453
|
+
extraction = _ours_only_extraction(parsed, root, adapter, excludes, inventory)
|
|
455
454
|
# ADR 012: an artifact-read tool states its staleness on the row it
|
|
456
455
|
# ran on, and its findings are labeled when the bytecode is older
|
|
457
456
|
# than the source — the method existing was not the promise
|
|
@@ -477,6 +476,49 @@ def _attempt(root: Path, adapter: Any, probe: Probe, timeout: int,
|
|
|
477
476
|
)
|
|
478
477
|
|
|
479
478
|
|
|
479
|
+
def _run_batches(adapter: Any, root: Path, excludes: Sequence[str],
|
|
480
|
+
timeout: int) -> tuple[ToolResult, Extraction]:
|
|
481
|
+
"""Every run the adapter needs, each parsed as it finishes, then merged.
|
|
482
|
+
|
|
483
|
+
A tool handed explicit files runs once per batch that fits a command
|
|
484
|
+
line; each is parsed before the next, because some tools rewrite one
|
|
485
|
+
results file per run. A batch that fails stops the rest and its outcome
|
|
486
|
+
is the tool's: a partial reading must not pass for a whole one.
|
|
487
|
+
"""
|
|
488
|
+
planned = getattr(adapter, "invocations", None)
|
|
489
|
+
invocations = planned(root, excludes) if planned else [adapter.invocation(root, excludes=excludes)]
|
|
490
|
+
results: list[ToolResult] = []
|
|
491
|
+
parsed: list[Extraction] = []
|
|
492
|
+
for invocation in invocations:
|
|
493
|
+
result = run(adapter.slug, invocation, timeout_seconds=timeout)
|
|
494
|
+
results.append(result)
|
|
495
|
+
parsed.append(adapter.parse(result))
|
|
496
|
+
if not result.usable:
|
|
497
|
+
break
|
|
498
|
+
if len(results) == 1:
|
|
499
|
+
return results[0], parsed[0]
|
|
500
|
+
return _merged_result(results, len(invocations)), _merged_extraction(parsed)
|
|
501
|
+
|
|
502
|
+
|
|
503
|
+
def _merged_result(results: list[ToolResult], planned: int) -> ToolResult:
|
|
504
|
+
failed = next((r for r in results if not r.usable), None)
|
|
505
|
+
basis = failed or results[0]
|
|
506
|
+
detail = (f"batch {len(results)} of {planned} failed: {failed.detail}" if failed
|
|
507
|
+
else f"read in {planned} batches, one command line each")
|
|
508
|
+
return replace(basis, detail=detail,
|
|
509
|
+
duration_seconds=sum(r.duration_seconds for r in results))
|
|
510
|
+
|
|
511
|
+
|
|
512
|
+
def _merged_extraction(parsed: list[Extraction]) -> Extraction:
|
|
513
|
+
return Extraction(
|
|
514
|
+
measurements=tuple(m for e in parsed for m in e.measurements),
|
|
515
|
+
findings=tuple(f for e in parsed for f in e.findings),
|
|
516
|
+
parse_error=next((e.parse_error for e in parsed if e.parse_error), None),
|
|
517
|
+
raw="\n".join(e.raw for e in parsed if e.raw),
|
|
518
|
+
truncated=any(e.truncated for e in parsed),
|
|
519
|
+
)
|
|
520
|
+
|
|
521
|
+
|
|
480
522
|
def _collect(extraction: Extraction, adapter: Any, analysis: Analysis) -> None:
|
|
481
523
|
# `measurements_only` is the enforcement point, not a formality: a
|
|
482
524
|
# verdict emitter that started returning measurements would silently
|
|
@@ -219,6 +219,15 @@ CATEGORIES = ["modularity", "reusability", "analyzability", "modifiability", "te
|
|
|
219
219
|
# moves 52 at the published decimal. Published grades move, so this is a
|
|
220
220
|
# major version, on the same reasoning as 3.0.0. The corpus median still
|
|
221
221
|
# rolls up to exactly 4.0000.
|
|
222
|
+
#
|
|
223
|
+
# **2026-10-03, every file read (4.1.0).** D220: analyzers handed a file
|
|
224
|
+
# list used to be cut to one command line, so the largest repositories were
|
|
225
|
+
# read in part (FFmpeg's multimetric saw 1,543 of 4,687 files). All 201 rows
|
|
226
|
+
# were re-measured with the list split across runs, and with the scanner
|
|
227
|
+
# fingerprint covering the whole measurement path (D221). Ten rows' analyzer
|
|
228
|
+
# readings moved; no built-in reading did. Every reference and CALIBRATION_C
|
|
229
|
+
# re-derived to the same four decimals, and no repository's score moved at
|
|
230
|
+
# the published decimal or changed grade, so the constants stand as shipped.
|
|
222
231
|
DIMENSION_REFERENCES: dict[str, float] = {
|
|
223
232
|
"file_size": 0.0871,
|
|
224
233
|
"declarations": 0.0929,
|
|
@@ -78,14 +78,14 @@ class PmdAdapter(BaseAdapter):
|
|
|
78
78
|
"""
|
|
79
79
|
return bool(expand_files(root, excludes, suffixes=(".java",)))
|
|
80
80
|
|
|
81
|
+
def target_files(self, root: Path, excludes: Sequence[str] = ()) -> tuple[str, ...]:
|
|
82
|
+
return expand_files(root, excludes, suffixes=(".java",))
|
|
83
|
+
|
|
81
84
|
def invocation(
|
|
82
85
|
self, root: Path, paths: Iterable[str] | None = None,
|
|
83
86
|
excludes: Sequence[str] = (),
|
|
84
87
|
) -> Invocation:
|
|
85
|
-
targets = (
|
|
86
|
-
tuple(paths) if paths
|
|
87
|
-
else expand_files(root, excludes, suffixes=(".java",))
|
|
88
|
-
)
|
|
88
|
+
targets = tuple(paths) if paths else self.target_files(root, excludes)
|
|
89
89
|
dirs: tuple[str, ...] = ()
|
|
90
90
|
for target in targets:
|
|
91
91
|
dirs += ("--dir", target)
|
|
@@ -173,14 +173,14 @@ class CheckstyleAdapter(BaseAdapter):
|
|
|
173
173
|
"""Whether any .java file survives the exclusions (never spawn empty)."""
|
|
174
174
|
return bool(expand_files(root, excludes, suffixes=(".java",)))
|
|
175
175
|
|
|
176
|
+
def target_files(self, root: Path, excludes: Sequence[str] = ()) -> tuple[str, ...]:
|
|
177
|
+
return expand_files(root, excludes, suffixes=(".java",))
|
|
178
|
+
|
|
176
179
|
def invocation(
|
|
177
180
|
self, root: Path, paths: Iterable[str] | None = None,
|
|
178
181
|
excludes: Sequence[str] = (),
|
|
179
182
|
) -> Invocation:
|
|
180
|
-
targets = (
|
|
181
|
-
tuple(paths) if paths
|
|
182
|
-
else expand_files(root, excludes, suffixes=(".java",))
|
|
183
|
-
)
|
|
183
|
+
targets = tuple(paths) if paths else self.target_files(root, excludes)
|
|
184
184
|
return Invocation(
|
|
185
185
|
argv=("checkstyle", "-c", "/google_checks.xml",
|
|
186
186
|
"-f", "xml", *targets),
|
|
@@ -13,8 +13,6 @@ from __future__ import annotations
|
|
|
13
13
|
import csv
|
|
14
14
|
import io
|
|
15
15
|
import json
|
|
16
|
-
import logging
|
|
17
|
-
import os
|
|
18
16
|
import re
|
|
19
17
|
import tempfile
|
|
20
18
|
from collections.abc import Iterable, Sequence
|
|
@@ -31,16 +29,6 @@ def _rows(text: str) -> list[list[str]]:
|
|
|
31
29
|
|
|
32
30
|
SOURCE_SUFFIXES = (".py", ".js", ".mjs", ".cjs", ".ts", ".java", ".c", ".cpp",
|
|
33
31
|
".h", ".go", ".rb", ".php")
|
|
34
|
-
# A file list has to fit on a command line. The old fixed cap of 400 was
|
|
35
|
-
# arbitrary and silent -- ~20 KB against an ARG_MAX of a megabyte -- so it
|
|
36
|
-
# truncated ordinary trees for no OS reason and said nothing (e88b429 #5).
|
|
37
|
-
# The budget is a quarter of the real ARG_MAX (room left for the exe, flags
|
|
38
|
-
# and env); beyond it a single invocation genuinely cannot name every file,
|
|
39
|
-
# and `expand_files` states the truncation through the logger, not silently.
|
|
40
|
-
_ARG_MAX = os.sysconf("SC_ARG_MAX") if hasattr(os, "sysconf") else 262144
|
|
41
|
-
_ARGV_BYTE_BUDGET = max(_ARG_MAX // 4, 131072)
|
|
42
|
-
|
|
43
|
-
logger = logging.getLogger(__name__)
|
|
44
32
|
|
|
45
33
|
|
|
46
34
|
def expand_files(
|
|
@@ -74,22 +62,8 @@ def expand_files(
|
|
|
74
62
|
and not any(part in skip for part in path.parts)
|
|
75
63
|
and not covers(path.relative_to(root).as_posix())
|
|
76
64
|
]
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
for name in eligible:
|
|
80
|
-
used += len(name.encode("utf-8")) + 1 # +1 for the argv separator
|
|
81
|
-
if used > _ARGV_BYTE_BUDGET and kept:
|
|
82
|
-
break
|
|
83
|
-
kept.append(name)
|
|
84
|
-
if len(kept) < len(eligible):
|
|
85
|
-
# Stated, not silent: a shortened file list is a shortened audit,
|
|
86
|
-
# and the reader has to know the tool saw only part of the tree.
|
|
87
|
-
logger.warning(
|
|
88
|
-
"file list for %s truncated to %d of %d files (%d-byte argv budget); "
|
|
89
|
-
"the remaining %d were not handed to the analyzer",
|
|
90
|
-
root, len(kept), len(eligible), _ARGV_BYTE_BUDGET, len(eligible) - len(kept),
|
|
91
|
-
)
|
|
92
|
-
return tuple(kept)
|
|
65
|
+
return tuple(eligible)
|
|
66
|
+
|
|
93
67
|
|
|
94
68
|
|
|
95
69
|
|
|
@@ -224,6 +198,9 @@ class ComplexipyAdapter(BaseAdapter):
|
|
|
224
198
|
)
|
|
225
199
|
self._work = Path(tempfile.mkdtemp(prefix="complexipy-"))
|
|
226
200
|
|
|
201
|
+
def target_files(self, root: Path, excludes: Sequence[str] = ()) -> tuple[str, ...]:
|
|
202
|
+
return expand_files(root.resolve(), excludes)
|
|
203
|
+
|
|
227
204
|
def invocation(
|
|
228
205
|
self, root: Path, paths: Iterable[str] | None = None,
|
|
229
206
|
excludes: Sequence[str] = (),
|
|
@@ -231,7 +208,7 @@ class ComplexipyAdapter(BaseAdapter):
|
|
|
231
208
|
# complexipy has no exclusion flag, so the filtering is done by
|
|
232
209
|
# naming files rather than handing it a directory. Without this it
|
|
233
210
|
# walks .venv and attributes vendored complexity to the user.
|
|
234
|
-
targets = tuple(paths) if paths else
|
|
211
|
+
targets = tuple(paths) if paths else self.target_files(root, excludes)
|
|
235
212
|
return Invocation(
|
|
236
213
|
argv=(self.executable, *targets, "--output-format", "json", "--quiet"),
|
|
237
214
|
findings_exit_codes=self.findings_exit_codes,
|
|
@@ -287,11 +264,14 @@ class MultimetricAdapter(BaseAdapter):
|
|
|
287
264
|
version_flag="--help", distribution="multimetric",
|
|
288
265
|
)
|
|
289
266
|
|
|
267
|
+
def target_files(self, root: Path, excludes: Sequence[str] = ()) -> tuple[str, ...]:
|
|
268
|
+
return expand_files(root, excludes)
|
|
269
|
+
|
|
290
270
|
def invocation(
|
|
291
271
|
self, root: Path, paths: Iterable[str] | None = None,
|
|
292
272
|
excludes: Sequence[str] = (),
|
|
293
273
|
) -> Invocation:
|
|
294
|
-
targets = tuple(paths) if paths else
|
|
274
|
+
targets = tuple(paths) if paths else self.target_files(root, excludes)
|
|
295
275
|
return Invocation(argv=(self.executable, *targets))
|
|
296
276
|
|
|
297
277
|
def _read(self, result: ToolResult) -> Extraction:
|
|
@@ -347,6 +327,17 @@ class CohesionAdapter(BaseAdapter):
|
|
|
347
327
|
distribution="cohesion",
|
|
348
328
|
)
|
|
349
329
|
|
|
330
|
+
def has_targets(self, root: Path, excludes: Sequence[str] = ()) -> bool:
|
|
331
|
+
"""Whether any .py file survives the exclusions.
|
|
332
|
+
|
|
333
|
+
With none, cohesion was spawned with an empty `--files` and exited 2,
|
|
334
|
+
so every repository without Python recorded it as failed.
|
|
335
|
+
"""
|
|
336
|
+
return bool(self.target_files(root, excludes))
|
|
337
|
+
|
|
338
|
+
def target_files(self, root: Path, excludes: Sequence[str] = ()) -> tuple[str, ...]:
|
|
339
|
+
return expand_files(root, excludes, suffixes=(".py",))
|
|
340
|
+
|
|
350
341
|
def invocation(
|
|
351
342
|
self, root: Path, paths: Iterable[str] | None = None,
|
|
352
343
|
excludes: Sequence[str] = (),
|
|
@@ -354,7 +345,7 @@ class CohesionAdapter(BaseAdapter):
|
|
|
354
345
|
# Explicit files: cohesion has no exclude flag, so what it must
|
|
355
346
|
# not read is excluded by never being named — the same rule as
|
|
356
347
|
# complexipy and multimetric.
|
|
357
|
-
targets = tuple(paths) if paths else
|
|
348
|
+
targets = tuple(paths) if paths else self.target_files(root, excludes)
|
|
358
349
|
return Invocation(argv=(self.executable, "--files", *targets))
|
|
359
350
|
|
|
360
351
|
def _read(self, result: ToolResult) -> Extraction:
|
|
@@ -55,7 +55,9 @@ def open_regular_file(path: Path, why: str) -> int:
|
|
|
55
55
|
"""
|
|
56
56
|
import stat as stat_module
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
# Windows has no `O_NONBLOCK` and no POSIX FIFO in the tree to guard
|
|
59
|
+
# against; using the flag unconditionally killed every read there.
|
|
60
|
+
handle = os.open(path, os.O_RDONLY | getattr(os, "O_NONBLOCK", 0))
|
|
59
61
|
if not stat_module.S_ISREG(os.fstat(handle).st_mode):
|
|
60
62
|
os.close(handle)
|
|
61
63
|
raise PathNotAllowed(f"{path} is not a regular file. {why}")
|
{maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/_runner.py
RENAMED
|
@@ -35,6 +35,7 @@ import sys
|
|
|
35
35
|
import sysconfig
|
|
36
36
|
import tempfile
|
|
37
37
|
import time
|
|
38
|
+
from collections.abc import Sequence
|
|
38
39
|
from contextlib import suppress
|
|
39
40
|
from dataclasses import dataclass, field
|
|
40
41
|
from enum import StrEnum
|
|
@@ -63,6 +64,40 @@ class Outcome(StrEnum):
|
|
|
63
64
|
FAILED = "failed"
|
|
64
65
|
|
|
65
66
|
|
|
67
|
+
# A file list has to fit on a command line. The old fixed cap of 400 was
|
|
68
|
+
# arbitrary and silent -- ~20 KB against an ARG_MAX of a megabyte -- so it
|
|
69
|
+
# truncated ordinary trees for no OS reason and said nothing (e88b429 #5).
|
|
70
|
+
# The budget is a quarter of the real ARG_MAX (room left for the exe, flags
|
|
71
|
+
# and env). Beyond it one invocation cannot name every file, so the list is
|
|
72
|
+
# split by `batches` and the tool runs once per batch; nothing is cut. The
|
|
73
|
+
# cut, stated in a log line, left FFmpeg's analyzers reading 1,543 of its
|
|
74
|
+
# 4,687 files in the 4.0.0 corpus run.
|
|
75
|
+
_ARG_MAX = os.sysconf("SC_ARG_MAX") if hasattr(os, "sysconf") else 262144
|
|
76
|
+
_ARGV_BYTE_BUDGET = max(_ARG_MAX // 4, 131072)
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
def batches(files: Sequence[str], budget: int | None = None) -> list[tuple[str, ...]]:
|
|
80
|
+
"""The file list in order, split so each part fits one command line.
|
|
81
|
+
|
|
82
|
+
A single name longer than the budget still gets a batch of its own:
|
|
83
|
+
refusing it would drop a file, which is the defect this replaces.
|
|
84
|
+
"""
|
|
85
|
+
limit = budget if budget is not None else _ARGV_BYTE_BUDGET
|
|
86
|
+
out: list[tuple[str, ...]] = []
|
|
87
|
+
current: list[str] = []
|
|
88
|
+
used = 0
|
|
89
|
+
for name in files:
|
|
90
|
+
size = len(name.encode("utf-8")) + 1 # +1 for the argv separator
|
|
91
|
+
if current and used + size > limit:
|
|
92
|
+
out.append(tuple(current))
|
|
93
|
+
current, used = [], 0
|
|
94
|
+
current.append(name)
|
|
95
|
+
used += size
|
|
96
|
+
if current:
|
|
97
|
+
out.append(tuple(current))
|
|
98
|
+
return out
|
|
99
|
+
|
|
100
|
+
|
|
66
101
|
@dataclass(frozen=True)
|
|
67
102
|
class Invocation:
|
|
68
103
|
"""How to run one tool. Described by adapters, executed only here."""
|
|
@@ -88,7 +88,29 @@ SUPPORTED_CEILING = (1,)
|
|
|
88
88
|
REQUIREMENT = "secure-code-agent>=0.12.10,<1"
|
|
89
89
|
|
|
90
90
|
#: How long the child may run before the pillar is reported as unmeasured.
|
|
91
|
-
|
|
91
|
+
#: 300 until a full run on this repository took about 8½ minutes and both
|
|
92
|
+
#: audits of it reported the pillar unmeasured; 900 is about twice that.
|
|
93
|
+
#: Configurable as `security.timeout_seconds`, through `security_timeout`.
|
|
94
|
+
DEFAULT_TIMEOUT_SECONDS = 900
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
def security_timeout(config: dict[str, Any]) -> int:
|
|
98
|
+
"""The configured limit for the security run, held to the analyzer band.
|
|
99
|
+
|
|
100
|
+
A repository naming a number is naming how long this host waits, so it
|
|
101
|
+
gets the clamp `analyzers.timeout_seconds` has (D40's family): 1 second
|
|
102
|
+
to 1 hour, and the default for anything that is not an integer.
|
|
103
|
+
"""
|
|
104
|
+
from ._catalog import MAX_TIMEOUT_SECONDS, MIN_TIMEOUT_SECONDS
|
|
105
|
+
|
|
106
|
+
configured = (config.get("security") or {}).get("timeout_seconds", DEFAULT_TIMEOUT_SECONDS)
|
|
107
|
+
if isinstance(configured, bool):
|
|
108
|
+
return DEFAULT_TIMEOUT_SECONDS
|
|
109
|
+
try:
|
|
110
|
+
seconds = int(configured)
|
|
111
|
+
except (TypeError, ValueError):
|
|
112
|
+
return DEFAULT_TIMEOUT_SECONDS
|
|
113
|
+
return max(MIN_TIMEOUT_SECONDS, min(seconds, MAX_TIMEOUT_SECONDS))
|
|
92
114
|
|
|
93
115
|
_ENTRY = "import sys; from secure_code_audit.cli import main; sys.exit(main())"
|
|
94
116
|
|
|
@@ -209,6 +209,9 @@ class PydocstyleAdapter(BaseAdapter):
|
|
|
209
209
|
exclude_flag="--match-dir", exclude_separator="|", exclude_dialect="files",
|
|
210
210
|
)
|
|
211
211
|
|
|
212
|
+
def target_files(self, root: Path, excludes: Sequence[str] = ()) -> tuple[str, ...]:
|
|
213
|
+
return expand_files(root, excludes, suffixes=(".py",))
|
|
214
|
+
|
|
212
215
|
def invocation(
|
|
213
216
|
self, root: Path, paths: Iterable[str] | None = None,
|
|
214
217
|
excludes: Sequence[str] = (),
|
|
@@ -226,7 +229,7 @@ class PydocstyleAdapter(BaseAdapter):
|
|
|
226
229
|
an include regex sitting beside an explicit file list can only
|
|
227
230
|
narrow it further in ways nobody asked for.
|
|
228
231
|
"""
|
|
229
|
-
targets = tuple(paths) if paths else
|
|
232
|
+
targets = tuple(paths) if paths else self.target_files(root, excludes)
|
|
230
233
|
return Invocation(
|
|
231
234
|
argv=(self.executable, *self.extra_args, *targets),
|
|
232
235
|
findings_exit_codes=self.findings_exit_codes,
|
{maintainability_agent-4.0.1 → maintainability_agent-4.2.0}/src/maintainability_audit/config.py
RENAMED
|
@@ -161,12 +161,29 @@ def load_config(path: str | None) -> dict[str, Any]:
|
|
|
161
161
|
return config
|
|
162
162
|
config["analyzers"]["run"] = True
|
|
163
163
|
if user_tier is not None:
|
|
164
|
-
|
|
164
|
+
_merge_tier(config, user_tier)
|
|
165
165
|
if path:
|
|
166
|
-
|
|
166
|
+
_merge_tier(config, _host_authority_stripped(_configured(Path(path))))
|
|
167
167
|
return config
|
|
168
168
|
|
|
169
169
|
|
|
170
|
+
def _merge_tier(config: dict[str, Any], tier: dict[str, Any]) -> None:
|
|
171
|
+
"""One tier over the ones before it, with `exclude_additional` appended.
|
|
172
|
+
|
|
173
|
+
`deep_update` replaces lists, so setting `paths.exclude_patterns` to add
|
|
174
|
+
one directory discarded every default exclusion and froze a copy that
|
|
175
|
+
drifts on the next release (#292). `exclude_additional` adds to whatever
|
|
176
|
+
the earlier tiers produced instead, so a repository can add without
|
|
177
|
+
restating.
|
|
178
|
+
"""
|
|
179
|
+
added = list((tier.get("paths") or {}).get("exclude_additional") or [])
|
|
180
|
+
deep_update(config, tier)
|
|
181
|
+
paths = config["paths"]
|
|
182
|
+
paths.pop("exclude_additional", None)
|
|
183
|
+
paths["exclude_patterns"] = [*paths["exclude_patterns"],
|
|
184
|
+
*(p for p in added if p not in paths["exclude_patterns"])]
|
|
185
|
+
|
|
186
|
+
|
|
170
187
|
#: The one key a repository may state and this tool will not act on,
|
|
171
188
|
#: because acting on it runs a program of the tree's choosing on the host.
|
|
172
189
|
#: The whole leaf is dropped, not merged.
|