maintainability-agent 4.3.1__tar.gz → 4.4.1__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.1}/PKG-INFO +9 -6
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/README.md +7 -4
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/pyproject.toml +4 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1/src/maintainability_agent.egg-info}/PKG-INFO +9 -6
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_agent.egg-info/SOURCES.txt +4 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_agent.egg-info/requires.txt +1 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_analysis.py +55 -2
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_analyzer_sections.py +6 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_catalog.py +31 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_coverage_notes.py +13 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_criteria_scope.py +23 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_first_run.py +25 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_mcp_refusals.py +6 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_mcp_setup.py +56 -2
- maintainability_agent-4.4.1/src/maintainability_audit/_pipeline_results.py +112 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_setup_persist.py +27 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_skill_data/SKILL.md +10 -2
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_verdict_adapters.py +4 -2
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/cli.py +2 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/mcp_server.py +6 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_adapters.py +54 -0
- maintainability_agent-4.4.1/tests/test_analyzers_never_write.py +128 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_first_run_elicitation.py +1 -1
- maintainability_agent-4.4.1/tests/test_pipeline_results.py +267 -0
- maintainability_agent-4.4.1/tests/test_reported_but_not_scored.py +51 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_previous_release_was_tagged.py +16 -1
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/LICENSE +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/setup.cfg +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_anchor.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_banner.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_changed_code_policy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_cognitive.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_delegated_pillar.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_evidence_reader.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_gates.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_grammar.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_handoff.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_html_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_in_loop.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_in_loop_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_jvm_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_mcp_audit.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_metric_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_operator_reads.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_oracle.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_precommit.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_precommit_install.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_precommit_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_prompt_sections.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_cobol.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_go.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_kotlin.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_php.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_ruby.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_rust.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_shell.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_ratio_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_running_version.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_security_delegate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_security_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/prompts.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/renderers.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/report.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_a_clone_names_every_copy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_a_dangling_source_link_is_named_not_fatal.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_a_format_override_is_disclosed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_a_matching_format_stays_silent.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_a_published_question_offers_what_it_accepts.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_a_rendered_docs_site_is_not_scored_as_source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_a_setup_question_keeps_its_contract.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_added_lines.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_an_absent_work_order_renders_nothing.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_an_unmeasured_pillar_reports_no_number.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_file_lists_are_batched.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzers_against_the_real_tools.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_analyzers_report_what_actually_failed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_anchor_and_mode.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_anchor_disclosure.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_architecture.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_attestation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_audit_components.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_backfill.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_bands.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_behaviour_suites_are_tests.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_both_setup_paths_ask_the_same_stage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_changed_code_policy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_chat_leads_with_the_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_check_refuses_plus_only_fragments.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_child_sandbox.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_clean_sees_the_weakened_oracle.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_cli.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_code_scanning_gets_alerts_not_the_record.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_cohesion_with_nothing_to_read_is_not_applicable.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_config_shape.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_conformance_reads_the_operators_ask.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_consent_is_per_repository.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_consent_survives_setup_and_is_asked.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_consent_without_command_has_a_remedy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_corpus_note_counts_come_from_the_corpus.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_corroborate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_coverage_config_reaches_children.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_coverage_formats.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_criteria_completion.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_current_state_docs_name_every_parsed_language.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_dead_code.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_declaration_criteria_scope.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_declarative_parsers.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_declared_capabilities_match_the_delegate.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_delegated_security_pillar.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_demo_tree.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_determinism.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_discovery.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_docs_links.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_economic_context.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_every_built_presentation_is_offered.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_every_job_tests_the_pinned_oracle.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_every_language_counts_its_own_loop.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_every_language_has_a_loop_fixture.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_every_pool_install_is_the_same_pool.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_every_question_can_be_answered.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_every_surface_says_what_the_run_found.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_example_config_opens_claimed_languages.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_exclude_additional_keeps_the_defaults.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_exposure_never_outranks_band.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_first_stage_setup_wording_holds.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_format_ask.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_git_argv.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_go_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_grammar_constructs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_grammar_token_coverage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_grok_audit_of_3_11.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_history_window.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_html_executive.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_in_loop_budgets.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_in_loop_check.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_java_scored.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_kotlin_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_kotlin_metrics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_language_support_honesty.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_list_tools_publishes_the_answer_path.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_maintenance_signals.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_mcp_format_contract.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_mcp_start_failure_names_what_is_installed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_missing_security_scanners_are_named_before_the_run.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_mutation_recorded.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_no_private_names.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_operator_named_paths.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_operator_named_reads.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_oracle_weakening_precision_bar.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_pairing_reads_imports.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_php_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_platform_claim.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_policy_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_population_floors.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_precommit_staged.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_preflight_before_consent_runs_nothing_from_the_tree.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_previous_release_reached_pypi.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_promises.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_python_complexity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_readme_claims.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_recurrence.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_regular_file_reads_work_without_o_nonblock.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_release_needs_an_empty_ledger.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_release_plan.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_rendered_docs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_root_grants.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_ruby_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_runner.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_rust_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_sarif.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_scan_history.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_scanner_fingerprint_covers_the_measurement_path.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_scanner_unsafe_direction.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_scanning.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_security_delegate_versions_agree.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_security_findings_keep_their_handoff.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_security_pillar_asserts_a_scanner_set.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_security_pillar_runs_and_shows.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_selection_covers_every_parsed_language.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_semantic_findings_stay_inside_the_audited_files.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_setup_answers_are_the_same_setup.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_setup_instruction_describes_its_own_reply.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_setup_writes_a_valid_config.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_shell_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_shell_metrics.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_skill_install.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_sonar_resolve.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_source_index.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_stamped_documents_stay_honest.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_stdout_outputs.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_terminal_asks_the_same_questions.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_test_commands.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_agent_knows_when_it_is_stale.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_changelog_covers_the_shipping_version.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_chat_payload_has_a_budget.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_condition_says_what_it_measured.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_handoff_rules_are_their_own_module.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_pillar_row_reads_cleanly.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_presentation_question_stays_answerable.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_prompt_does_not_take_back_what_it_withheld.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_prompt_keeps_listing_what_it_did_not_withhold.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_release_process_describes_itself.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_release_record_stays_well_formed.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_report_is_saved_not_sent.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_security_run_has_a_configurable_limit.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_security_work_order_is_drawn.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_suite_names_the_program_it_ran.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_tree_cannot_redirect_a_read.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_the_version_has_one_source.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_tool_resolution.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_tree_chosen_spawn.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_tree_reads_use_the_primitive.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_trends.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_unanchored_set_matches_corpus.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_unread_code.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_version_claim.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_version_stamping.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_withheld_work_keeps_its_boundary.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_work_items_state_their_own_finding.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_work_order.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/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.1
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -37,7 +37,7 @@ Requires-Dist: mcp<3,>=2; extra == "dev"
|
|
|
37
37
|
Requires-Dist: PyYAML>=6; extra == "dev"
|
|
38
38
|
Requires-Dist: setuptools>=70; extra == "dev"
|
|
39
39
|
Requires-Dist: lizard>=1.17; extra == "dev"
|
|
40
|
-
Requires-Dist: markdown
|
|
40
|
+
Requires-Dist: markdown==3.11.1; extra == "dev"
|
|
41
41
|
Dynamic: license-file
|
|
42
42
|
|
|
43
43
|
# Maintainability Agent
|
|
@@ -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.1**.
|
|
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.1
|
|
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.1**.
|
|
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.1
|
|
471
474
|
with:
|
|
472
475
|
config: maintainability-agent.json
|
|
473
476
|
changed-only: main...HEAD
|
|
@@ -63,7 +63,10 @@ mcp = ["mcp>=2,<3"]
|
|
|
63
63
|
# ships imports it, and the oracle exists so a measurement can be
|
|
64
64
|
# checked against something other than its author. `markdown` renders the
|
|
65
65
|
# docs/html reading copy (`tools/render_docs.py`); the product never does.
|
|
66
|
-
|
|
66
|
+
# It is pinned exactly: the committed copy is checked against a fresh render,
|
|
67
|
+
# and markdown 3.11 rendered two pages differently from 3.10, so an unpinned
|
|
68
|
+
# release failed CI on files nobody had touched (2026-10-14).
|
|
69
|
+
dev = ["pytest>=8", "pytest-cov>=5", "pytest-xdist>=3.6", "jsonschema>=4", "ruff>=0.5", "pip-audit>=2.7", "mcp>=2,<3", "PyYAML>=6", "setuptools>=70", "lizard>=1.17", "markdown==3.11.1"]
|
|
67
70
|
|
|
68
71
|
[tool.pydocstyle]
|
|
69
72
|
# D401 ("First line should be in imperative mood") is switched off, and the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 4.
|
|
3
|
+
Version: 4.4.1
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -37,7 +37,7 @@ Requires-Dist: mcp<3,>=2; extra == "dev"
|
|
|
37
37
|
Requires-Dist: PyYAML>=6; extra == "dev"
|
|
38
38
|
Requires-Dist: setuptools>=70; extra == "dev"
|
|
39
39
|
Requires-Dist: lizard>=1.17; extra == "dev"
|
|
40
|
-
Requires-Dist: markdown
|
|
40
|
+
Requires-Dist: markdown==3.11.1; extra == "dev"
|
|
41
41
|
Dynamic: license-file
|
|
42
42
|
|
|
43
43
|
# Maintainability Agent
|
|
@@ -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.1**.
|
|
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.1
|
|
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
|
|
@@ -181,6 +182,7 @@ tests/test_analyzer_scoring_path.py
|
|
|
181
182
|
tests/test_analyzer_spread_range.py
|
|
182
183
|
tests/test_analyzer_xml_bounds.py
|
|
183
184
|
tests/test_analyzers_against_the_real_tools.py
|
|
185
|
+
tests/test_analyzers_never_write.py
|
|
184
186
|
tests/test_analyzers_report_what_actually_failed.py
|
|
185
187
|
tests/test_anchor_and_mode.py
|
|
186
188
|
tests/test_anchor_caveat_and_counts_follow_the_run.py
|
|
@@ -353,6 +355,7 @@ tests/test_pattern_budget.py
|
|
|
353
355
|
tests/test_phase6_claims.py
|
|
354
356
|
tests/test_php_declarations.py
|
|
355
357
|
tests/test_pillars_and_practice.py
|
|
358
|
+
tests/test_pipeline_results.py
|
|
356
359
|
tests/test_platform_claim.py
|
|
357
360
|
tests/test_pmd_adapter.py
|
|
358
361
|
tests/test_pmd_audit_closures.py
|
|
@@ -381,6 +384,7 @@ tests/test_release_plan.py
|
|
|
381
384
|
tests/test_release_plan_status.py
|
|
382
385
|
tests/test_rendered_docs.py
|
|
383
386
|
tests/test_report_remedy_copy.py
|
|
387
|
+
tests/test_reported_but_not_scored.py
|
|
384
388
|
tests/test_root_grants.py
|
|
385
389
|
tests/test_rubric_ignores_project_lint_config.py
|
|
386
390
|
tests/test_ruby_declarations.py
|
{maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/src/maintainability_audit/_analysis.py
RENAMED
|
@@ -19,6 +19,7 @@ clean result.
|
|
|
19
19
|
|
|
20
20
|
from __future__ import annotations
|
|
21
21
|
|
|
22
|
+
import hashlib
|
|
22
23
|
from collections.abc import Sequence
|
|
23
24
|
from dataclasses import dataclass, field, replace
|
|
24
25
|
from pathlib import Path
|
|
@@ -40,6 +41,11 @@ from ._metrics_types import KNOWN_SOURCE_SUFFIXES, Finding, Measurement
|
|
|
40
41
|
from ._runner import Outcome, Probe, ToolResult, run
|
|
41
42
|
from ._selection import Selected, select_runnable
|
|
42
43
|
from .config import acquisition_permitted
|
|
44
|
+
from .git_tools import GitCommandFailed, probe_git, run_git
|
|
45
|
+
|
|
46
|
+
#: Sources outside this package: an analyzer it ran, or a file the
|
|
47
|
+
#: developer's own pipeline wrote (Decision 17). Built-ins are not here.
|
|
48
|
+
EXTERNAL_TIERS = ("analyzer", "pipeline")
|
|
43
49
|
|
|
44
50
|
|
|
45
51
|
@dataclass(frozen=True)
|
|
@@ -152,7 +158,7 @@ class Analysis:
|
|
|
152
158
|
"""
|
|
153
159
|
covered: dict[str, set[str]] = {name: set() for name in self.languages}
|
|
154
160
|
for item in self.coverage:
|
|
155
|
-
if not item.contributed or item.tier
|
|
161
|
+
if not item.contributed or item.tier not in EXTERNAL_TIERS:
|
|
156
162
|
continue
|
|
157
163
|
concerns = self._concerns_of(item.concepts)
|
|
158
164
|
for name, slug in self.languages.items():
|
|
@@ -217,7 +223,7 @@ class Analysis:
|
|
|
217
223
|
if name in self.scored_languages
|
|
218
224
|
]
|
|
219
225
|
if not scored:
|
|
220
|
-
return self._concerns_from("analyzer")
|
|
226
|
+
return self._concerns_from("analyzer") | self._concerns_from("pipeline")
|
|
221
227
|
return set.intersection(*scored)
|
|
222
228
|
|
|
223
229
|
def single_source_concerns(self) -> list[str]:
|
|
@@ -352,6 +358,43 @@ def analyze(root: Path, config: dict[str, Any], probe: Probe | None = None) -> A
|
|
|
352
358
|
return analysis
|
|
353
359
|
|
|
354
360
|
|
|
361
|
+
class RepositoryModifiedError(Exception):
|
|
362
|
+
"""An analyzer changed the repository it was auditing.
|
|
363
|
+
|
|
364
|
+
The audit never edits source. A tool that writes to the audited tree
|
|
365
|
+
(ruff honouring a repository's `fix = true` rewrote 102 files of
|
|
366
|
+
an audited repository on 2026-10-14) fails the audit loudly rather than handing back
|
|
367
|
+
a grade for code that is no longer what was audited.
|
|
368
|
+
"""
|
|
369
|
+
|
|
370
|
+
|
|
371
|
+
def _tracked_state(root: Path) -> dict[str, str] | None:
|
|
372
|
+
"""Each tracked file that differs from HEAD, by a hash of its diff.
|
|
373
|
+
|
|
374
|
+
None when `root` is not a git work tree: there is nothing to compare
|
|
375
|
+
against, so nothing is claimed.
|
|
376
|
+
"""
|
|
377
|
+
if not probe_git(["rev-parse", "--is-inside-work-tree"], root):
|
|
378
|
+
return None
|
|
379
|
+
try:
|
|
380
|
+
diff = run_git(["diff", "HEAD", "--no-ext-diff", "--binary"], root, strip=False)
|
|
381
|
+
except GitCommandFailed:
|
|
382
|
+
return None
|
|
383
|
+
state: dict[str, str] = {}
|
|
384
|
+
for block in diff.split("\ndiff --git "):
|
|
385
|
+
if not block.strip():
|
|
386
|
+
continue
|
|
387
|
+
header = block.split("\n", 1)[0].removeprefix("diff --git ")
|
|
388
|
+
name = header.split(" b/", 1)[-1]
|
|
389
|
+
state[name] = hashlib.sha256(block.encode("utf-8", "replace")).hexdigest()
|
|
390
|
+
return state
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
def _changed_paths(before: dict[str, str], after: dict[str, str]) -> list[str]:
|
|
394
|
+
return sorted(path for path in set(before) | set(after)
|
|
395
|
+
if before.get(path) != after.get(path))
|
|
396
|
+
|
|
397
|
+
|
|
355
398
|
def _run_one(root: Path, adapter: Any, probe: Probe, timeout: int,
|
|
356
399
|
analysis: Analysis, excludes: Sequence[str] = (),
|
|
357
400
|
inventory: Any = None) -> ToolCoverage:
|
|
@@ -367,6 +410,9 @@ def _run_one(root: Path, adapter: Any, probe: Probe, timeout: int,
|
|
|
367
410
|
"""
|
|
368
411
|
try:
|
|
369
412
|
return _attempt(root, adapter, probe, timeout, analysis, excludes, inventory)
|
|
413
|
+
except RepositoryModifiedError:
|
|
414
|
+
# Not an adapter defect to record quietly: the audited tree changed.
|
|
415
|
+
raise
|
|
370
416
|
except Exception as error: # noqa: BLE001 - the backstop is the point
|
|
371
417
|
return ToolCoverage(
|
|
372
418
|
slug=adapter.slug, outcome="failed", concepts=tuple(adapter.concepts),
|
|
@@ -490,12 +536,19 @@ def _run_batches(adapter: Any, root: Path, excludes: Sequence[str],
|
|
|
490
536
|
invocations = planned(root, excludes) if planned else [adapter.invocation(root, excludes=excludes)]
|
|
491
537
|
results: list[ToolResult] = []
|
|
492
538
|
parsed: list[Extraction] = []
|
|
539
|
+
before = _tracked_state(root)
|
|
493
540
|
for invocation in invocations:
|
|
494
541
|
result = run(adapter.slug, invocation, timeout_seconds=timeout)
|
|
495
542
|
results.append(result)
|
|
496
543
|
parsed.append(adapter.parse(result))
|
|
497
544
|
if not result.usable:
|
|
498
545
|
break
|
|
546
|
+
after = _tracked_state(root) if before is not None else None
|
|
547
|
+
if before is not None and after is not None and after != before:
|
|
548
|
+
changed = _changed_paths(before, after)
|
|
549
|
+
raise RepositoryModifiedError(
|
|
550
|
+
f"{adapter.slug} modified the audited repository: {', '.join(changed)}. "
|
|
551
|
+
"The audit never edits source; restore these files and report the adapter.")
|
|
499
552
|
if len(results) == 1:
|
|
500
553
|
return results[0], parsed[0]
|
|
501
554
|
return _merged_result(results, len(invocations)), _merged_extraction(parsed)
|
|
@@ -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.1}/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.1}/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})
|
|
@@ -18,6 +18,7 @@ D48.
|
|
|
18
18
|
|
|
19
19
|
from __future__ import annotations
|
|
20
20
|
|
|
21
|
+
from ._analysis import RepositoryModifiedError
|
|
21
22
|
from ._catalog import PolicyError
|
|
22
23
|
from ._mcp_audit import InvalidAuditArgument, PathNotAllowed
|
|
23
24
|
from ._mcp_setup import SetupRequired
|
|
@@ -37,6 +38,11 @@ ANTICIPATED_REFUSALS = (
|
|
|
37
38
|
# type and `PathNotAllowed` both derive from it alongside the
|
|
38
39
|
# internal ones that must stay crashes.
|
|
39
40
|
ConfigUnreadable,
|
|
41
|
+
# An analyzer changed the audited repository. The message names the
|
|
42
|
+
# changed files and says to report the adapter: actionable, and a
|
|
43
|
+
# grade must never be returned for code that is no longer what was
|
|
44
|
+
# audited.
|
|
45
|
+
RepositoryModifiedError,
|
|
40
46
|
)
|
|
41
47
|
|
|
42
48
|
__all__ = ["ANTICIPATED_REFUSALS"]
|
{maintainability_agent-4.3.1 → maintainability_agent-4.4.1}/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
|
|