maintainability-agent 4.3.1__tar.gz → 4.4.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.3.1/src/maintainability_agent.egg-info → maintainability_agent-4.4.0}/PKG-INFO +8 -5
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/README.md +7 -4
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0/src/maintainability_agent.egg-info}/PKG-INFO +8 -5
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_agent.egg-info/SOURCES.txt +3 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_analysis.py +6 -2
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_analyzer_sections.py +6 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_catalog.py +31 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_coverage_notes.py +13 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_criteria_scope.py +23 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_first_run.py +25 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_mcp_setup.py +56 -2
- maintainability_agent-4.4.0/src/maintainability_audit/_pipeline_results.py +112 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_setup_persist.py +27 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_skill_data/SKILL.md +10 -2
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/cli.py +2 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/mcp_server.py +6 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_first_run_elicitation.py +1 -1
- maintainability_agent-4.4.0/tests/test_pipeline_results.py +267 -0
- maintainability_agent-4.4.0/tests/test_reported_but_not_scored.py +51 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_previous_release_was_tagged.py +16 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/LICENSE +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/pyproject.toml +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/setup.cfg +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_agent.egg-info/requires.txt +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_anchor.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_banner.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_changed_code_policy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_cognitive.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_delegated_pillar.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_evidence_reader.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_gates.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_grammar.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_handoff.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_html_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_in_loop.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_in_loop_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_jvm_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_mcp_audit.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_metric_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_operator_reads.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_oracle.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_precommit.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_precommit_install.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_precommit_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_prompt_sections.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_cobol.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_go.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_kotlin.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_php.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_ruby.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_rust.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_shell.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_ratio_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_running_version.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_security_delegate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_security_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_verdict_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/prompts.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/renderers.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/report.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_a_clone_names_every_copy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_a_dangling_source_link_is_named_not_fatal.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_a_format_override_is_disclosed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_a_matching_format_stays_silent.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_a_published_question_offers_what_it_accepts.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_a_rendered_docs_site_is_not_scored_as_source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_a_setup_question_keeps_its_contract.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_added_lines.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_an_absent_work_order_renders_nothing.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_an_unmeasured_pillar_reports_no_number.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_file_lists_are_batched.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzers_against_the_real_tools.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_analyzers_report_what_actually_failed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_anchor_and_mode.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_anchor_disclosure.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_architecture.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_attestation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_audit_components.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_backfill.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_bands.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_behaviour_suites_are_tests.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_both_setup_paths_ask_the_same_stage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_changed_code_policy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_chat_leads_with_the_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_check_refuses_plus_only_fragments.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_child_sandbox.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_clean_sees_the_weakened_oracle.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_cli.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_code_scanning_gets_alerts_not_the_record.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_cohesion_with_nothing_to_read_is_not_applicable.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_config_shape.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_conformance_reads_the_operators_ask.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_consent_is_per_repository.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_consent_survives_setup_and_is_asked.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_consent_without_command_has_a_remedy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_corpus_note_counts_come_from_the_corpus.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_corroborate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_coverage_config_reaches_children.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_coverage_formats.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_criteria_completion.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_current_state_docs_name_every_parsed_language.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_dead_code.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_declaration_criteria_scope.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_declarative_parsers.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_declared_capabilities_match_the_delegate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_delegated_security_pillar.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_demo_tree.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_determinism.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_discovery.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_docs_links.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_economic_context.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_every_built_presentation_is_offered.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_every_job_tests_the_pinned_oracle.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_every_language_counts_its_own_loop.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_every_language_has_a_loop_fixture.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_every_pool_install_is_the_same_pool.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_every_question_can_be_answered.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_every_surface_says_what_the_run_found.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_example_config_opens_claimed_languages.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_exclude_additional_keeps_the_defaults.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_exposure_never_outranks_band.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_first_stage_setup_wording_holds.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_format_ask.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_git_argv.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_go_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_grammar_constructs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_grammar_token_coverage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_grok_audit_of_3_11.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_history_window.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_html_executive.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_in_loop_budgets.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_in_loop_check.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_java_scored.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_kotlin_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_kotlin_metrics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_language_support_honesty.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_list_tools_publishes_the_answer_path.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_maintenance_signals.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_mcp_format_contract.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_mcp_start_failure_names_what_is_installed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_missing_security_scanners_are_named_before_the_run.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_mutation_recorded.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_no_private_names.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_operator_named_paths.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_operator_named_reads.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_oracle_weakening_precision_bar.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_pairing_reads_imports.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_php_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_platform_claim.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_policy_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_population_floors.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_precommit_staged.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_preflight_before_consent_runs_nothing_from_the_tree.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_previous_release_reached_pypi.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_promises.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_python_complexity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_readme_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_recurrence.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_regular_file_reads_work_without_o_nonblock.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_release_needs_an_empty_ledger.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_release_plan.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_rendered_docs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_root_grants.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_ruby_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_runner.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_rust_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_sarif.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_scan_history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_scanner_fingerprint_covers_the_measurement_path.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_scanner_unsafe_direction.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_scanning.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_security_delegate_versions_agree.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_security_findings_keep_their_handoff.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_security_pillar_asserts_a_scanner_set.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_security_pillar_runs_and_shows.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_selection_covers_every_parsed_language.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_semantic_findings_stay_inside_the_audited_files.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_setup_answers_are_the_same_setup.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_setup_instruction_describes_its_own_reply.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_setup_writes_a_valid_config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_shell_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_shell_metrics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_skill_install.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_sonar_resolve.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_source_index.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_stamped_documents_stay_honest.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_stdout_outputs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_terminal_asks_the_same_questions.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_test_commands.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_agent_knows_when_it_is_stale.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_changelog_covers_the_shipping_version.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_chat_payload_has_a_budget.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_condition_says_what_it_measured.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_handoff_rules_are_their_own_module.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_pillar_row_reads_cleanly.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_presentation_question_stays_answerable.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_prompt_does_not_take_back_what_it_withheld.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_prompt_keeps_listing_what_it_did_not_withhold.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_release_process_describes_itself.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_release_record_stays_well_formed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_report_is_saved_not_sent.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_security_run_has_a_configurable_limit.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_security_work_order_is_drawn.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_suite_names_the_program_it_ran.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_tree_cannot_redirect_a_read.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_the_version_has_one_source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_tool_resolution.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_tree_chosen_spawn.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_tree_reads_use_the_primitive.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_trends.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_unanchored_set_matches_corpus.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_unread_code.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_version_claim.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_version_stamping.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_withheld_work_keeps_its_boundary.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_work_items_state_their_own_finding.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/tests/test_written_record.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -47,7 +47,7 @@ Dynamic: license-file
|
|
|
47
47
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
48
48
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
49
49
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
50
|
-
Version **4.
|
|
50
|
+
Version **4.4.0**.
|
|
51
51
|
|
|
52
52
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
53
53
|
>
|
|
@@ -372,8 +372,11 @@ codebase is read rather than sampled — FFmpeg's 4,687 files, not the first
|
|
|
372
372
|
The analyzer is intentionally conservative and under-reports rather than
|
|
373
373
|
over-reports: an unrecognized declaration costs one missed finding, never a
|
|
374
374
|
cascade of false ones. Pair it with native tools (ESLint, Ruff, Radon, Semgrep,
|
|
375
|
-
SonarQube, Qlty) rather than replacing them
|
|
376
|
-
|
|
375
|
+
SonarQube, Qlty) rather than replacing them. This tool runs a pinned handful of
|
|
376
|
+
the analyzers it catalogs; the rest run where you already run them, and their
|
|
377
|
+
SARIF is read, never run: declare each file in `analyzers.pipeline_results`
|
|
378
|
+
with the concerns it covers (first-run setup asks), and those concerns count as
|
|
379
|
+
examined for the languages it names. One-off files fold in via `--sarif-input`. Accuracy and limits: [docs/language-support.md](docs/language-support.md).
|
|
377
380
|
|
|
378
381
|
## Language support
|
|
379
382
|
|
|
@@ -509,7 +512,7 @@ instead of an invokable skill:
|
|
|
509
512
|
This repo ships `action.yml`, usable as a composite action:
|
|
510
513
|
|
|
511
514
|
```yaml
|
|
512
|
-
- uses: marshallguillory86/maintainability-agent@v4.
|
|
515
|
+
- uses: marshallguillory86/maintainability-agent@v4.4.0
|
|
513
516
|
with:
|
|
514
517
|
config: maintainability-agent.json
|
|
515
518
|
changed-only: main...HEAD
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
6
6
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
7
7
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
8
|
-
Version **4.
|
|
8
|
+
Version **4.4.0**.
|
|
9
9
|
|
|
10
10
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
11
11
|
>
|
|
@@ -330,8 +330,11 @@ codebase is read rather than sampled — FFmpeg's 4,687 files, not the first
|
|
|
330
330
|
The analyzer is intentionally conservative and under-reports rather than
|
|
331
331
|
over-reports: an unrecognized declaration costs one missed finding, never a
|
|
332
332
|
cascade of false ones. Pair it with native tools (ESLint, Ruff, Radon, Semgrep,
|
|
333
|
-
SonarQube, Qlty) rather than replacing them
|
|
334
|
-
|
|
333
|
+
SonarQube, Qlty) rather than replacing them. This tool runs a pinned handful of
|
|
334
|
+
the analyzers it catalogs; the rest run where you already run them, and their
|
|
335
|
+
SARIF is read, never run: declare each file in `analyzers.pipeline_results`
|
|
336
|
+
with the concerns it covers (first-run setup asks), and those concerns count as
|
|
337
|
+
examined for the languages it names. One-off files fold in via `--sarif-input`. Accuracy and limits: [docs/language-support.md](docs/language-support.md).
|
|
335
338
|
|
|
336
339
|
## Language support
|
|
337
340
|
|
|
@@ -467,7 +470,7 @@ instead of an invokable skill:
|
|
|
467
470
|
This repo ships `action.yml`, usable as a composite action:
|
|
468
471
|
|
|
469
472
|
```yaml
|
|
470
|
-
- uses: marshallguillory86/maintainability-agent@v4.
|
|
473
|
+
- uses: marshallguillory86/maintainability-agent@v4.4.0
|
|
471
474
|
with:
|
|
472
475
|
config: maintainability-agent.json
|
|
473
476
|
changed-only: main...HEAD
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -47,7 +47,7 @@ Dynamic: license-file
|
|
|
47
47
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
48
48
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
49
49
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
50
|
-
Version **4.
|
|
50
|
+
Version **4.4.0**.
|
|
51
51
|
|
|
52
52
|
> ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
|
|
53
53
|
>
|
|
@@ -372,8 +372,11 @@ codebase is read rather than sampled — FFmpeg's 4,687 files, not the first
|
|
|
372
372
|
The analyzer is intentionally conservative and under-reports rather than
|
|
373
373
|
over-reports: an unrecognized declaration costs one missed finding, never a
|
|
374
374
|
cascade of false ones. Pair it with native tools (ESLint, Ruff, Radon, Semgrep,
|
|
375
|
-
SonarQube, Qlty) rather than replacing them
|
|
376
|
-
|
|
375
|
+
SonarQube, Qlty) rather than replacing them. This tool runs a pinned handful of
|
|
376
|
+
the analyzers it catalogs; the rest run where you already run them, and their
|
|
377
|
+
SARIF is read, never run: declare each file in `analyzers.pipeline_results`
|
|
378
|
+
with the concerns it covers (first-run setup asks), and those concerns count as
|
|
379
|
+
examined for the languages it names. One-off files fold in via `--sarif-input`. Accuracy and limits: [docs/language-support.md](docs/language-support.md).
|
|
377
380
|
|
|
378
381
|
## Language support
|
|
379
382
|
|
|
@@ -509,7 +512,7 @@ instead of an invokable skill:
|
|
|
509
512
|
This repo ships `action.yml`, usable as a composite action:
|
|
510
513
|
|
|
511
514
|
```yaml
|
|
512
|
-
- uses: marshallguillory86/maintainability-agent@v4.
|
|
515
|
+
- uses: marshallguillory86/maintainability-agent@v4.4.0
|
|
513
516
|
with:
|
|
514
517
|
config: maintainability-agent.json
|
|
515
518
|
changed-only: main...HEAD
|
|
@@ -69,6 +69,7 @@ src/maintainability_audit/_metrics_types.py
|
|
|
69
69
|
src/maintainability_audit/_operator_reads.py
|
|
70
70
|
src/maintainability_audit/_oracle.py
|
|
71
71
|
src/maintainability_audit/_pillars.py
|
|
72
|
+
src/maintainability_audit/_pipeline_results.py
|
|
72
73
|
src/maintainability_audit/_practice.py
|
|
73
74
|
src/maintainability_audit/_precommit.py
|
|
74
75
|
src/maintainability_audit/_precommit_install.py
|
|
@@ -353,6 +354,7 @@ tests/test_pattern_budget.py
|
|
|
353
354
|
tests/test_phase6_claims.py
|
|
354
355
|
tests/test_php_declarations.py
|
|
355
356
|
tests/test_pillars_and_practice.py
|
|
357
|
+
tests/test_pipeline_results.py
|
|
356
358
|
tests/test_platform_claim.py
|
|
357
359
|
tests/test_pmd_adapter.py
|
|
358
360
|
tests/test_pmd_audit_closures.py
|
|
@@ -381,6 +383,7 @@ tests/test_release_plan.py
|
|
|
381
383
|
tests/test_release_plan_status.py
|
|
382
384
|
tests/test_rendered_docs.py
|
|
383
385
|
tests/test_report_remedy_copy.py
|
|
386
|
+
tests/test_reported_but_not_scored.py
|
|
384
387
|
tests/test_root_grants.py
|
|
385
388
|
tests/test_rubric_ignores_project_lint_config.py
|
|
386
389
|
tests/test_ruby_declarations.py
|
{maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_analysis.py
RENAMED
|
@@ -41,6 +41,10 @@ from ._runner import Outcome, Probe, ToolResult, run
|
|
|
41
41
|
from ._selection import Selected, select_runnable
|
|
42
42
|
from .config import acquisition_permitted
|
|
43
43
|
|
|
44
|
+
#: Sources outside this package: an analyzer it ran, or a file the
|
|
45
|
+
#: developer's own pipeline wrote (Decision 17). Built-ins are not here.
|
|
46
|
+
EXTERNAL_TIERS = ("analyzer", "pipeline")
|
|
47
|
+
|
|
44
48
|
|
|
45
49
|
@dataclass(frozen=True)
|
|
46
50
|
class ToolCoverage:
|
|
@@ -152,7 +156,7 @@ class Analysis:
|
|
|
152
156
|
"""
|
|
153
157
|
covered: dict[str, set[str]] = {name: set() for name in self.languages}
|
|
154
158
|
for item in self.coverage:
|
|
155
|
-
if not item.contributed or item.tier
|
|
159
|
+
if not item.contributed or item.tier not in EXTERNAL_TIERS:
|
|
156
160
|
continue
|
|
157
161
|
concerns = self._concerns_of(item.concepts)
|
|
158
162
|
for name, slug in self.languages.items():
|
|
@@ -217,7 +221,7 @@ class Analysis:
|
|
|
217
221
|
if name in self.scored_languages
|
|
218
222
|
]
|
|
219
223
|
if not scored:
|
|
220
|
-
return self._concerns_from("analyzer")
|
|
224
|
+
return self._concerns_from("analyzer") | self._concerns_from("pipeline")
|
|
221
225
|
return set.intersection(*scored)
|
|
222
226
|
|
|
223
227
|
def single_source_concerns(self) -> list[str]:
|
|
@@ -12,7 +12,7 @@ from pathlib import Path
|
|
|
12
12
|
from typing import Any
|
|
13
13
|
|
|
14
14
|
from ._analysis import analyze
|
|
15
|
-
from ._criteria_scope import built_in_readings
|
|
15
|
+
from ._criteria_scope import built_in_readings, reported_not_scored
|
|
16
16
|
from ._documents import (
|
|
17
17
|
coverage_document,
|
|
18
18
|
findings_document,
|
|
@@ -21,6 +21,7 @@ from ._documents import (
|
|
|
21
21
|
)
|
|
22
22
|
from ._environment import environment_work_order
|
|
23
23
|
from ._metrics_types import FunctionMetric
|
|
24
|
+
from ._pipeline_results import add_pipeline_results
|
|
24
25
|
from ._pressures import (
|
|
25
26
|
ExternalPressures,
|
|
26
27
|
analyzer_pressures,
|
|
@@ -46,6 +47,9 @@ def analyzer_sections(
|
|
|
46
47
|
return {"coverage": None, "findings": [], "measurements": {},
|
|
47
48
|
"pressures": None, "environment": []}
|
|
48
49
|
analysis = analyze(root, config)
|
|
50
|
+
# Decision 17: the files the developer's own pipeline wrote, read
|
|
51
|
+
# beside what this run's analyzers produced.
|
|
52
|
+
add_pipeline_results(analysis, root, config)
|
|
49
53
|
coverage = coverage_document(analysis)
|
|
50
54
|
# P8: where the analyzer tier could not drive a dimension, say so on
|
|
51
55
|
# the coverage document rather than leaving the built-in fallback to
|
|
@@ -58,6 +62,7 @@ def analyzer_sections(
|
|
|
58
62
|
built_in = built_in_readings(function_metrics, prefix)
|
|
59
63
|
coverage["dimensions_declined"] = list(
|
|
60
64
|
declined_dimensions(analysis.measurements, False, built_in, prefix))
|
|
65
|
+
coverage["reported_not_scored"] = reported_not_scored(coverage)
|
|
61
66
|
return {
|
|
62
67
|
"coverage": coverage,
|
|
63
68
|
# ADR 006 §2c: what did not run and what it would take, for the
|
{maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_catalog.py
RENAMED
|
@@ -166,9 +166,40 @@ def settings_from(config: dict[str, Any]) -> dict[str, Any]:
|
|
|
166
166
|
if unknown:
|
|
167
167
|
raise PolicyError(f"unknown concerns {sorted(unknown)}; expected from {list(CONCERNS)}")
|
|
168
168
|
settings["timeout_seconds"] = _bounded_timeout(settings["timeout_seconds"])
|
|
169
|
+
settings["pipeline_results"] = _pipeline_results(settings.get("pipeline_results"))
|
|
169
170
|
return settings
|
|
170
171
|
|
|
171
172
|
|
|
173
|
+
def pipeline_results_from_answer(answer: str) -> list[dict[str, Any]]:
|
|
174
|
+
"""The first-run answer, `path: concern, concern; path: concern`, as declarations."""
|
|
175
|
+
entries = []
|
|
176
|
+
for part in (answer or "").split(";"):
|
|
177
|
+
if not part.strip():
|
|
178
|
+
continue
|
|
179
|
+
path, _, covers = part.partition(":")
|
|
180
|
+
entries.append({"path": path.strip(),
|
|
181
|
+
"covers": [c.strip() for c in covers.split(",") if c.strip()]})
|
|
182
|
+
return _pipeline_results(entries)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
def _pipeline_results(declared: Any) -> list[dict[str, Any]]:
|
|
186
|
+
"""Each file the developer's pipeline writes, and what it covers (Decision 17).
|
|
187
|
+
|
|
188
|
+
Refused rather than skipped: a declaration that silently examined
|
|
189
|
+
nothing would leave a concern unexamined with the operator believing
|
|
190
|
+
it covered.
|
|
191
|
+
"""
|
|
192
|
+
entries = list(declared or [])
|
|
193
|
+
for entry in entries:
|
|
194
|
+
if not isinstance(entry, dict) or not isinstance(entry.get("path"), str) or not entry["path"]:
|
|
195
|
+
raise PolicyError(f"analyzers.pipeline_results entry {entry!r} needs a `path`")
|
|
196
|
+
covers = entry.get("covers")
|
|
197
|
+
if not covers or not isinstance(covers, list) or set(covers) - set(CONCERNS):
|
|
198
|
+
raise PolicyError(
|
|
199
|
+
f"analyzers.pipeline_results {entry['path']!r} needs `covers` from {list(CONCERNS)}")
|
|
200
|
+
return entries
|
|
201
|
+
|
|
202
|
+
|
|
172
203
|
#: The widest per-analyzer wall clock a configured value may ask for. An
|
|
173
204
|
#: hour is far past any real analyzer on any real tree and still bounds
|
|
174
205
|
#: the host against a repository config that names a number designed
|
|
@@ -48,6 +48,17 @@ def coverage_notes(coverage: dict[str, Any]) -> list[str]:
|
|
|
48
48
|
"",
|
|
49
49
|
])
|
|
50
50
|
|
|
51
|
+
for unused in coverage.get("reported_not_scored") or []:
|
|
52
|
+
# The count sits in the findings beside a grade computed from
|
|
53
|
+
# something else; without this a reader takes it as ignored.
|
|
54
|
+
lines.extend([
|
|
55
|
+
f"**`{unused['tool']}` reported {unused['findings']} `{unused['concept']}` "
|
|
56
|
+
f"findings; they are listed and their count does not move the grade:** the "
|
|
57
|
+
f"`{unused['dimension']}` dimension is scored from the built-in "
|
|
58
|
+
"detectors only.",
|
|
59
|
+
"",
|
|
60
|
+
])
|
|
61
|
+
|
|
51
62
|
unexamined = coverage["concepts_unexamined"]
|
|
52
63
|
if unexamined:
|
|
53
64
|
# The point of the whole section. Silence about a concern is not
|
|
@@ -56,7 +67,8 @@ def coverage_notes(coverage: dict[str, Any]) -> list[str]:
|
|
|
56
67
|
"**Nothing examined:** " + ", ".join(f"`{c}`" for c in unexamined) + ".",
|
|
57
68
|
"",
|
|
58
69
|
"These concerns are unmeasured, not clean. Install a tool that covers them, "
|
|
59
|
-
"
|
|
70
|
+
"widen `analyzers.depth`, or declare the SARIF your own build or pipeline "
|
|
71
|
+
"already writes in `analyzers.pipeline_results` to have them reported.",
|
|
60
72
|
"",
|
|
61
73
|
])
|
|
62
74
|
|
|
@@ -40,6 +40,29 @@ DECLARATION_CRITERIA: tuple[tuple[str, str, str], ...] = (
|
|
|
40
40
|
# `risk` and `gates` are configured policy with no external equivalent.
|
|
41
41
|
ANALYZER_DIMENSIONS: tuple[str, ...] = ("declarations",)
|
|
42
42
|
|
|
43
|
+
# Concepts an analyzer can report whose dimension is scored from the
|
|
44
|
+
# built-in detectors only. Their findings are listed, never scored.
|
|
45
|
+
BUILT_IN_SCORED_CONCEPTS: dict[str, str] = {"duplication": "duplication", "file_lines": "file_size"}
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def reported_not_scored(coverage: dict) -> list[dict]:
|
|
49
|
+
"""Analyzer findings listed in the report that do not move the grade.
|
|
50
|
+
|
|
51
|
+
A field report on a C# repository read jscpd's 439 duplicate blocks,
|
|
52
|
+
listed beside a duplication grade computed from the built-in detector,
|
|
53
|
+
as the analyzer's output being ignored. The design was right and the
|
|
54
|
+
page did not say it (P8).
|
|
55
|
+
"""
|
|
56
|
+
return [
|
|
57
|
+
{"tool": entry["tool"], "concept": concept,
|
|
58
|
+
"dimension": BUILT_IN_SCORED_CONCEPTS[concept], "findings": entry["findings"]}
|
|
59
|
+
for entry in (coverage.get("by_outcome") or {}).get("ran", [])
|
|
60
|
+
if entry.get("tier") == "analyzer" and entry.get("findings")
|
|
61
|
+
for concept in entry.get("concepts", [])
|
|
62
|
+
if concept in BUILT_IN_SCORED_CONCEPTS
|
|
63
|
+
and BUILT_IN_SCORED_CONCEPTS[concept] not in ANALYZER_DIMENSIONS
|
|
64
|
+
]
|
|
65
|
+
|
|
43
66
|
|
|
44
67
|
def declaration_concepts_missing(covered: set[str]) -> tuple[str, ...]:
|
|
45
68
|
"""Criteria the analyzers did not supply, in rubric order.
|
{maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_first_run.py
RENAMED
|
@@ -111,6 +111,7 @@ def maybe_prompt_first_run(root: Path, explicit_config: str | None) -> None:
|
|
|
111
111
|
"Add the economic scenario (loaded labor rate per hour) beside "
|
|
112
112
|
"the score? Skip leaves money out of reports. "
|
|
113
113
|
"(include/skip) [skip]: ", ("include", "skip"), "skip"),
|
|
114
|
+
"pipeline_results": _ask_pipeline_results(), # Decision 17
|
|
114
115
|
}
|
|
115
116
|
apply_answers(root, answers)
|
|
116
117
|
print(f"Wrote {root / CONFIG_FILENAME}")
|
|
@@ -338,3 +339,27 @@ def _record_test_command(root: Path, config: dict, answer: str) -> None:
|
|
|
338
339
|
if not answer:
|
|
339
340
|
config["test_execution"] = {"requested": False}
|
|
340
341
|
print(f"Wrote {target}")
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def _ask_pipeline_results() -> str:
|
|
345
|
+
"""Whether the developer's own pipeline writes SARIF; the files are the
|
|
346
|
+
second stage, `maybe_prompt_pipeline_files` (Decision 17)."""
|
|
347
|
+
from ._mcp_setup import pipeline_results_question
|
|
348
|
+
|
|
349
|
+
return _ask(pipeline_results_question()["prompt"] + " (none/declare) [none]: ",
|
|
350
|
+
("none", "declare"), "none")
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
def maybe_prompt_pipeline_files(root: Path, config: dict) -> dict:
|
|
354
|
+
"""The CLI half of the Decision 17 second stage: at a TTY, after `declare`.
|
|
355
|
+
|
|
356
|
+
Returns the configuration this run should use, so files declared at the
|
|
357
|
+
prompt are read by the audit that asked for them.
|
|
358
|
+
"""
|
|
359
|
+
from ._mcp_setup import pipeline_files_pending, pipeline_files_questions
|
|
360
|
+
from ._setup_persist import _apply_pipeline_files
|
|
361
|
+
|
|
362
|
+
if not _stdin_is_a_tty() or not pipeline_files_pending(root):
|
|
363
|
+
return config
|
|
364
|
+
answer = input(pipeline_files_questions()[0]["prompt"] + " ").strip()
|
|
365
|
+
return _apply_pipeline_files(root, {"pipeline_files": answer})
|
{maintainability_agent-4.3.1 → maintainability_agent-4.4.0}/src/maintainability_audit/_mcp_setup.py
RENAMED
|
@@ -28,13 +28,14 @@ from __future__ import annotations
|
|
|
28
28
|
from pathlib import Path
|
|
29
29
|
from typing import Any
|
|
30
30
|
|
|
31
|
-
from ._catalog import LICENSE_POLICIES, PRESENTATIONS
|
|
31
|
+
from ._catalog import CONCERNS, LICENSE_POLICIES, PRESENTATIONS
|
|
32
32
|
from ._setup_errors import SetupRequired as SetupRequired
|
|
33
33
|
from ._setup_persist import (
|
|
34
34
|
BOUNDS,
|
|
35
35
|
_accepted,
|
|
36
36
|
_apply_bounds,
|
|
37
37
|
_apply_command,
|
|
38
|
+
_apply_pipeline_files,
|
|
38
39
|
_economics_block,
|
|
39
40
|
_is_bounds_only,
|
|
40
41
|
_is_command_only,
|
|
@@ -88,6 +89,7 @@ def setup_questions(config: dict[str, Any]) -> list[dict[str, Any]]:
|
|
|
88
89
|
},
|
|
89
90
|
*_economics_questions(),
|
|
90
91
|
*run_tests_question(),
|
|
92
|
+
pipeline_results_question(),
|
|
91
93
|
{
|
|
92
94
|
"name": "default_format",
|
|
93
95
|
"prompt": "Default report presentation for this user.",
|
|
@@ -112,6 +114,48 @@ def setup_questions(config: dict[str, Any]) -> list[dict[str, Any]]:
|
|
|
112
114
|
]
|
|
113
115
|
|
|
114
116
|
|
|
117
|
+
def pipeline_results_question() -> dict[str, Any]:
|
|
118
|
+
"""Whether the developer's own pipeline writes analyzer results (Decision 17).
|
|
119
|
+
|
|
120
|
+
A choice, like every first-stage question; the files are the second
|
|
121
|
+
stage, asked only on `declare`. This tool runs a pinned handful of the
|
|
122
|
+
catalog, and the rest are run where they already run and read here.
|
|
123
|
+
"""
|
|
124
|
+
return {
|
|
125
|
+
"name": "pipeline_results",
|
|
126
|
+
"prompt": (
|
|
127
|
+
"Does your own build or pipeline already write analyzer results as "
|
|
128
|
+
"SARIF (Roslyn analyzers, Semgrep, CodeQL...)? Declare names the files "
|
|
129
|
+
"next; this reads them and never runs the tools."
|
|
130
|
+
),
|
|
131
|
+
"options": ["none", "declare"],
|
|
132
|
+
"default": "none",
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def pipeline_files_questions() -> list[dict[str, Any]]:
|
|
137
|
+
"""The files, asked only of someone who said `declare`."""
|
|
138
|
+
return [{
|
|
139
|
+
"name": "pipeline_files",
|
|
140
|
+
"prompt": (
|
|
141
|
+
"Each SARIF file and the concerns it covers, from "
|
|
142
|
+
+ ", ".join(CONCERNS) + " — e.g. `artifacts/roslyn.sarif: style, "
|
|
143
|
+
"documentation, dead-code`; separate files with `;`. Paths are "
|
|
144
|
+
"relative to the repository. Blank cancels."
|
|
145
|
+
),
|
|
146
|
+
"options": [],
|
|
147
|
+
"default": "",
|
|
148
|
+
}]
|
|
149
|
+
|
|
150
|
+
|
|
151
|
+
def pipeline_files_pending(root: Path) -> bool:
|
|
152
|
+
"""`declare` was answered and no file is declared yet."""
|
|
153
|
+
discovered = discovered_config(Path(root))
|
|
154
|
+
stored = _read_config(Path(discovered)) if discovered is not None else None
|
|
155
|
+
analyzers = (stored or {}).get("analyzers") or {}
|
|
156
|
+
return bool(analyzers.get("pipeline_requested")) and not analyzers.get("pipeline_results")
|
|
157
|
+
|
|
158
|
+
|
|
115
159
|
def economics_bound_questions() -> list[dict[str, Any]]:
|
|
116
160
|
"""The three rates, asked only of someone who said yes to the gate."""
|
|
117
161
|
return [
|
|
@@ -179,6 +223,8 @@ def published_questions(root: Path | None = None) -> dict[str, dict[str, Any]]:
|
|
|
179
223
|
questions[question["name"]] = question
|
|
180
224
|
for question in test_command_questions(root):
|
|
181
225
|
questions[question["name"]] = question
|
|
226
|
+
for question in pipeline_files_questions():
|
|
227
|
+
questions[question["name"]] = question
|
|
182
228
|
return questions
|
|
183
229
|
|
|
184
230
|
|
|
@@ -248,6 +294,7 @@ def submittable_answer_names() -> frozenset[str]:
|
|
|
248
294
|
names = {question["name"] for question in setup_questions({})}
|
|
249
295
|
names.update(name for name, _, _ in BOUNDS)
|
|
250
296
|
names.add("test_command")
|
|
297
|
+
names.add("pipeline_files")
|
|
251
298
|
return frozenset(names)
|
|
252
299
|
|
|
253
300
|
|
|
@@ -258,6 +305,8 @@ def apply_answers(root: Path, answers: dict[str, Any]) -> dict[str, Any]:
|
|
|
258
305
|
return _apply_bounds(root, answers)
|
|
259
306
|
if _is_command_only(answers):
|
|
260
307
|
return _apply_command(root, answers)
|
|
308
|
+
if set(k for k, v in answers.items() if v is not None) == {"pipeline_files"}:
|
|
309
|
+
return _apply_pipeline_files(root, answers)
|
|
261
310
|
payload: dict[str, Any] = {
|
|
262
311
|
"version": 1,
|
|
263
312
|
"analyzers": {
|
|
@@ -272,6 +321,8 @@ def apply_answers(root: Path, answers: dict[str, Any]) -> dict[str, Any]:
|
|
|
272
321
|
# suite; the command is a staged second ask.
|
|
273
322
|
"test_execution": {"requested": _accepted(answers.get("run_tests", "no"))},
|
|
274
323
|
}
|
|
324
|
+
if answers.get("pipeline_results") == "declare":
|
|
325
|
+
payload["analyzers"]["pipeline_requested"] = True
|
|
275
326
|
economics = _economics_block(answers)
|
|
276
327
|
if economics is not None:
|
|
277
328
|
payload["economic_context"] = economics
|
|
@@ -406,7 +457,8 @@ def setup_pending(root: Path) -> bool:
|
|
|
406
457
|
# rates for someone who wanted the scenario, or the test command for
|
|
407
458
|
# someone who opted to run the suite. Both are stage two of an ask
|
|
408
459
|
# already begun, not a new one.
|
|
409
|
-
return economics_bounds_pending(root) or test_command_pending(root)
|
|
460
|
+
return (economics_bounds_pending(root) or test_command_pending(root)
|
|
461
|
+
or pipeline_files_pending(root))
|
|
410
462
|
# No repository file: the person's answers carry to it (first-run.md),
|
|
411
463
|
# and it is asked only what is its own — its test command (Decision 4).
|
|
412
464
|
return user_config_answers() is None or test_command_pending(root)
|
|
@@ -465,6 +517,8 @@ def staged_questions(root: Path | None = None) -> list[dict[str, Any]]:
|
|
|
465
517
|
return economics_bound_questions()
|
|
466
518
|
if root is not None and test_command_pending(root):
|
|
467
519
|
return test_command_questions(root)
|
|
520
|
+
if root is not None and pipeline_files_pending(root):
|
|
521
|
+
return pipeline_files_questions()
|
|
468
522
|
return setup_questions(load_config(None))
|
|
469
523
|
|
|
470
524
|
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
"""Analyzer output the developer's own pipeline wrote (Decision 17).
|
|
2
|
+
|
|
3
|
+
The catalog holds some 760 tools and this one runs a pinned handful. The
|
|
4
|
+
rest run where they already run — a .NET build runs the Roslyn analyzers,
|
|
5
|
+
and executes code from the repository it builds, which nothing here does —
|
|
6
|
+
and this reads the SARIF they wrote. Each file is declared in
|
|
7
|
+
`analyzers.pipeline_results` with the concerns it covers, because one file
|
|
8
|
+
can mix style, documentation and dead-code rules and only its owner knows
|
|
9
|
+
which they asked for.
|
|
10
|
+
|
|
11
|
+
A file becomes a coverage row of its own tier, `pipeline`: it examines its
|
|
12
|
+
declared concerns for the languages its results name, never the languages
|
|
13
|
+
it does not, and is never counted as a tool this run attempted. Its
|
|
14
|
+
findings are listed and do not score.
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
|
|
19
|
+
import json
|
|
20
|
+
from pathlib import Path, PurePosixPath
|
|
21
|
+
from typing import Any
|
|
22
|
+
|
|
23
|
+
from ._analysis import Analysis, ToolCoverage
|
|
24
|
+
from ._catalog import PolicyError, settings_from
|
|
25
|
+
from ._discovery import CATALOG_LANGUAGE
|
|
26
|
+
from ._generic import parse_sarif
|
|
27
|
+
from ._metrics_types import KNOWN_SOURCE_SUFFIXES
|
|
28
|
+
from ._runner import Outcome
|
|
29
|
+
from .config import PathNotAllowed, read_operator_file, repository_path
|
|
30
|
+
from .git_tools import GitCommandFailed, run_git
|
|
31
|
+
|
|
32
|
+
#: Matches no catalog language, so a row carrying it examines nothing.
|
|
33
|
+
NO_LANGUAGE = ("unstated",)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def add_pipeline_results(analysis: Analysis, root: Path, config: dict[str, Any]) -> None:
|
|
37
|
+
"""Append one coverage row, and its findings, per declared file.
|
|
38
|
+
|
|
39
|
+
Never raises, like `analyze`: a block it refuses is already recorded
|
|
40
|
+
there as the analysis error, and must degrade the audit, not end it.
|
|
41
|
+
"""
|
|
42
|
+
try:
|
|
43
|
+
declarations = settings_from(config)["pipeline_results"]
|
|
44
|
+
except PolicyError:
|
|
45
|
+
return
|
|
46
|
+
for declared in declarations:
|
|
47
|
+
row, findings = _read_one(root, declared)
|
|
48
|
+
analysis.coverage.append(row)
|
|
49
|
+
analysis.findings.extend(findings)
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def _read_one(root: Path, declared: dict[str, Any]) -> tuple[ToolCoverage, list]:
|
|
53
|
+
named = declared["path"]
|
|
54
|
+
covers = tuple(declared["covers"])
|
|
55
|
+
try:
|
|
56
|
+
path = repository_path(root, named, named)
|
|
57
|
+
text = read_operator_file(path)
|
|
58
|
+
extraction = parse_sarif(text, "pipeline", ", ".join(covers))
|
|
59
|
+
payload = json.loads(text)
|
|
60
|
+
except (PathNotAllowed, OSError, ValueError) as error:
|
|
61
|
+
return ToolCoverage(
|
|
62
|
+
slug=named, outcome=Outcome.FAILED.value, tier="pipeline", concepts=covers,
|
|
63
|
+
languages=NO_LANGUAGE,
|
|
64
|
+
detail=f"declared in analyzers.pipeline_results as {named}, and not read: {error}",
|
|
65
|
+
), []
|
|
66
|
+
findings = list(extraction.findings)
|
|
67
|
+
languages = _languages(payload, declared.get("languages") or ())
|
|
68
|
+
stale = path.stat().st_mtime < _last_commit_time(root)
|
|
69
|
+
detail = f"read from {named}, which your pipeline wrote"
|
|
70
|
+
if stale:
|
|
71
|
+
detail += "; the file is older than the last commit, so it may not describe this code"
|
|
72
|
+
if languages == NO_LANGUAGE:
|
|
73
|
+
detail += ("; it names no source file and declares no languages, so it examines "
|
|
74
|
+
"nothing — add `languages` to its declaration")
|
|
75
|
+
tools = sorted({f.tool for f in findings}) or [_driver(payload) or named]
|
|
76
|
+
return ToolCoverage(
|
|
77
|
+
slug=", ".join(tools), outcome=Outcome.RAN.value, tier="pipeline", concepts=covers,
|
|
78
|
+
findings=len(findings), languages=languages, stale=stale, detail=detail,
|
|
79
|
+
), findings
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def _languages(payload: dict[str, Any], declared: Any) -> tuple[str, ...]:
|
|
83
|
+
"""Catalog languages of the source files the results and artifacts name."""
|
|
84
|
+
names = {KNOWN_SOURCE_SUFFIXES.get(PurePosixPath(uri).suffix.lower())
|
|
85
|
+
for uri in _uris(payload)} | set(declared)
|
|
86
|
+
slugs = sorted({CATALOG_LANGUAGE[name] for name in names if name in CATALOG_LANGUAGE})
|
|
87
|
+
return tuple(slugs) or NO_LANGUAGE
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def _uris(payload: dict[str, Any]) -> list[str]:
|
|
91
|
+
"""Every file a result points at, and every artifact the run lists."""
|
|
92
|
+
uris = []
|
|
93
|
+
for run in payload.get("runs", []):
|
|
94
|
+
for result in run.get("results", []):
|
|
95
|
+
for location in result.get("locations") or []:
|
|
96
|
+
physical = location.get("physicalLocation") or {}
|
|
97
|
+
uris.append((physical.get("artifactLocation") or {}).get("uri", ""))
|
|
98
|
+
for artifact in run.get("artifacts", []):
|
|
99
|
+
uris.append((artifact.get("location") or {}).get("uri", ""))
|
|
100
|
+
return uris
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _driver(payload: dict[str, Any]) -> str:
|
|
104
|
+
runs = payload.get("runs") or [{}]
|
|
105
|
+
return ((runs[0].get("tool") or {}).get("driver") or {}).get("name", "")
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
def _last_commit_time(root: Path) -> float:
|
|
109
|
+
try:
|
|
110
|
+
return float(run_git(["log", "-1", "--format=%ct"], root) or 0)
|
|
111
|
+
except (GitCommandFailed, ValueError):
|
|
112
|
+
return 0.0
|
|
@@ -194,7 +194,12 @@ def _persist_answers(root: Path, payload: dict[str, Any]) -> dict[str, Any]:
|
|
|
194
194
|
Path(root), config_path,
|
|
195
195
|
json.dumps(merged, indent=2, sort_keys=True) + "\n",
|
|
196
196
|
)
|
|
197
|
-
|
|
197
|
+
# Which SARIF files a build writes is a fact about this repository
|
|
198
|
+
# (Decision 17), so `declare` stays in its file and never carries to
|
|
199
|
+
# the person's next repository.
|
|
200
|
+
person = {**payload, "analyzers": {
|
|
201
|
+
key: value for key, value in payload["analyzers"].items() if key != "pipeline_requested"}}
|
|
202
|
+
write_user_answers(_keeping_consents(person))
|
|
198
203
|
return load_config(str(config_path))
|
|
199
204
|
|
|
200
205
|
|
|
@@ -212,3 +217,24 @@ def _keeping_consents(payload: dict[str, Any]) -> dict[str, Any]:
|
|
|
212
217
|
kept = dict(payload)
|
|
213
218
|
kept["test_execution"] = {**(payload.get("test_execution") or {}), "commands": recorded}
|
|
214
219
|
return kept
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def _apply_pipeline_files(root: Path, answers: dict[str, Any]) -> dict[str, Any]:
|
|
223
|
+
"""Merge the declared files into the repository's config; blank cancels."""
|
|
224
|
+
from ._catalog import PolicyError, pipeline_results_from_answer
|
|
225
|
+
from ._setup_errors import SetupRequired
|
|
226
|
+
|
|
227
|
+
try:
|
|
228
|
+
declared = pipeline_results_from_answer(str(answers.get("pipeline_files") or ""))
|
|
229
|
+
except PolicyError as malformed:
|
|
230
|
+
raise SetupRequired(str(malformed)) from None
|
|
231
|
+
discovered = discovered_config(Path(root))
|
|
232
|
+
stored = dict(_read_config(Path(discovered)) or {}) if discovered else {}
|
|
233
|
+
analyzers = dict(stored.get("analyzers") or {})
|
|
234
|
+
analyzers["pipeline_requested"] = bool(declared)
|
|
235
|
+
if declared:
|
|
236
|
+
analyzers["pipeline_results"] = declared
|
|
237
|
+
stored["analyzers"] = analyzers
|
|
238
|
+
config_path = Path(root) / CONFIG_FILENAME
|
|
239
|
+
write_bounded(Path(root), config_path, json.dumps(stored, indent=2, sort_keys=True) + "\n")
|
|
240
|
+
return load_config(str(config_path))
|
|
@@ -39,7 +39,9 @@ engineering changes, not as permission to refactor unrelated code.
|
|
|
39
39
|
names and no others, then call again with `setup_answers` — a
|
|
40
40
|
mapping of each question's `name` to the option chosen. Answering
|
|
41
41
|
one stage can open the next (`include` for the economic scenario
|
|
42
|
-
asks the three rates; `yes` to the suite asks for the command
|
|
42
|
+
asks the three rates; `yes` to the suite asks for the command;
|
|
43
|
+
`declare` for pipeline results asks which SARIF files the
|
|
44
|
+
developer's own build writes and what each covers),
|
|
43
45
|
and the next reply carries whatever is still outstanding.
|
|
44
46
|
Answering does *not* start an audit.
|
|
45
47
|
- **Configured** — the result carries `choice_needed`: run the
|
|
@@ -76,7 +78,13 @@ engineering changes, not as permission to refactor unrelated code.
|
|
|
76
78
|
secure-code-agent scanner that is not installed, its install
|
|
77
79
|
command, and the concepts installing it restores. It can arrive
|
|
78
80
|
with `choice_needed`, before the run, so the user can install
|
|
79
|
-
first. The agent never installs tools itself.
|
|
81
|
+
first. The agent never installs tools itself. Where the coverage
|
|
82
|
+
section lists concerns as unexamined — C# style, documentation and
|
|
83
|
+
dead code, for instance — tell the user their own build or pipeline
|
|
84
|
+
can cover them: the SARIF it already writes is declared in
|
|
85
|
+
`analyzers.pipeline_results` (or by answering `declare` in setup)
|
|
86
|
+
and read, never run. This tool runs a pinned handful of analyzers;
|
|
87
|
+
the rest run where the developer already runs them.
|
|
80
88
|
6. Re-run the audit and any native tests/lints required by the repo,
|
|
81
89
|
then report what ran, whether the gate passed, and any remaining
|
|
82
90
|
false positives or follow-ups.
|