maintainability-agent 3.7.7__tar.gz → 3.7.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {maintainability_agent-3.7.7/src/maintainability_agent.egg-info → maintainability_agent-3.7.9}/PKG-INFO +3 -3
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/README.md +2 -2
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/pyproject.toml +1 -1
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9/src/maintainability_agent.egg-info}/PKG-INFO +3 -3
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_agent.egg-info/SOURCES.txt +6 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_mcp_audit.py +7 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_mcp_gate.py +20 -1
- maintainability_agent-3.7.9/src/maintainability_audit/_running_version.py +121 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_security_delegate.py +10 -2
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_test_execution.py +22 -1
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/cli.py +7 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/config.py +1 -1
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/mcp_server.py +5 -0
- maintainability_agent-3.7.9/tests/test_code_scanning_gets_alerts_not_the_record.py +83 -0
- maintainability_agent-3.7.9/tests/test_consent_without_command_has_a_remedy.py +66 -0
- maintainability_agent-3.7.9/tests/test_declared_capabilities_match_the_delegate.py +118 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_security_delegate_versions_agree.py +9 -2
- maintainability_agent-3.7.9/tests/test_security_pillar_asserts_a_scanner_set.py +58 -0
- maintainability_agent-3.7.9/tests/test_the_agent_knows_when_it_is_stale.py +178 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/LICENSE +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/setup.cfg +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_agent.egg-info/requires.txt +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_adapters.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_analysis.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_analyzer_sections.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_anchor.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_banner.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_catalog.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_cognitive.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_coverage_notes.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_criteria_scope.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_delegated_pillar.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_evidence_reader.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_first_run.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_gates.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_grammar.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_html_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_in_loop.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_in_loop_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_jvm_adapters.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_mcp_setup.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_metric_adapters.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_operator_reads.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_precommit.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_precommit_install.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_precommit_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_prompt_sections.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_cobol.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_go.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_php.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_ruby.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_rust.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_ratio_adapters.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_security_work_order.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_setup_persist.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_verdict_adapters.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/prompts.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/renderers.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/report.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_adapters.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_added_lines.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_anchor_and_mode.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_anchor_disclosure.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_architecture.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_attestation.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_audit_components.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_backfill.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_bands.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_chat_leads_with_the_work_order.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_check_refuses_plus_only_fragments.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_child_sandbox.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_cli.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_config_shape.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_corroborate.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_criteria_completion.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_dead_code.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_declaration_criteria_scope.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_declarative_parsers.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_delegated_security_pillar.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_demo_tree.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_determinism.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_discovery.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_docs_links.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_economic_context.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_every_surface_says_what_the_run_found.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_example_config_opens_claimed_languages.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_exposure_never_outranks_band.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_first_run_elicitation.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_format_ask.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_git_argv.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_go_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_grammar_constructs.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_grammar_token_coverage.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_history.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_history_window.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_html_executive.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_in_loop_budgets.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_in_loop_check.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_java_scored.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_language_support_honesty.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_mcp_format_contract.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_mcp_start_failure_names_what_is_installed.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_mutation_recorded.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_operator_named_paths.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_operator_named_reads.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_pairing_reads_imports.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_php_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_platform_claim.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_policy_claims.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_population_floors.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_precommit_staged.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_promises.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_python_complexity.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_readme_claims.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_recurrence.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_release_needs_an_empty_ledger.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_release_plan.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_root_grants.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_ruby_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_runner.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_rust_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_sarif.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_scan_history.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_scanner_unsafe_direction.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_scanning.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_security_findings_keep_their_handoff.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_security_pillar_runs_and_shows.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_semantic_findings_stay_inside_the_audited_files.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_skill_install.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_sonar_resolve.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_source_index.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_stdout_outputs.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_terminal_asks_the_same_questions.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_test_commands.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_tool_resolution.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_tree_chosen_spawn.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_tree_reads_use_the_primitive.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_trends.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_unanchored_set_matches_corpus.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_unread_code.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_version_claim.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_withheld_work_keeps_its_boundary.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_work_items_state_their_own_finding.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_work_order.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/tests/test_written_record.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 3.7.
|
|
3
|
+
Version: 3.7.9
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -46,7 +46,7 @@ Dynamic: license-file
|
|
|
46
46
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
47
47
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
48
48
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
49
|
-
Version **3.7.
|
|
49
|
+
Version **3.7.9**.
|
|
50
50
|
|
|
51
51
|
**Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
|
|
52
52
|
COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -473,7 +473,7 @@ instead of an invokable skill:
|
|
|
473
473
|
This repo ships `action.yml`, usable as a composite action:
|
|
474
474
|
|
|
475
475
|
```yaml
|
|
476
|
-
- uses: marshallguillory86/maintainability-agent@v3.7.
|
|
476
|
+
- uses: marshallguillory86/maintainability-agent@v3.7.9
|
|
477
477
|
with:
|
|
478
478
|
config: maintainability-agent.json
|
|
479
479
|
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 **3.7.
|
|
8
|
+
Version **3.7.9**.
|
|
9
9
|
|
|
10
10
|
**Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
|
|
11
11
|
COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -432,7 +432,7 @@ instead of an invokable skill:
|
|
|
432
432
|
This repo ships `action.yml`, usable as a composite action:
|
|
433
433
|
|
|
434
434
|
```yaml
|
|
435
|
-
- uses: marshallguillory86/maintainability-agent@v3.7.
|
|
435
|
+
- uses: marshallguillory86/maintainability-agent@v3.7.9
|
|
436
436
|
with:
|
|
437
437
|
config: maintainability-agent.json
|
|
438
438
|
changed-only: main...HEAD
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "maintainability-agent"
|
|
7
|
-
version = "3.7.
|
|
7
|
+
version = "3.7.9"
|
|
8
8
|
description = "Maintainability gate and AI remediation prompt generator for CI."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
# 3.11, not 3.10. `_discovery`, `_pillars` and `_runner` all import
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 3.7.
|
|
3
|
+
Version: 3.7.9
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -46,7 +46,7 @@ Dynamic: license-file
|
|
|
46
46
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
47
47
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
48
48
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
49
|
-
Version **3.7.
|
|
49
|
+
Version **3.7.9**.
|
|
50
50
|
|
|
51
51
|
**Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
|
|
52
52
|
COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -473,7 +473,7 @@ instead of an invokable skill:
|
|
|
473
473
|
This repo ships `action.yml`, usable as a composite action:
|
|
474
474
|
|
|
475
475
|
```yaml
|
|
476
|
-
- uses: marshallguillory86/maintainability-agent@v3.7.
|
|
476
|
+
- uses: marshallguillory86/maintainability-agent@v3.7.9
|
|
477
477
|
with:
|
|
478
478
|
config: maintainability-agent.json
|
|
479
479
|
changed-only: main...HEAD
|
|
@@ -90,6 +90,7 @@ src/maintainability_audit/_ratio_adapters.py
|
|
|
90
90
|
src/maintainability_audit/_recurrence.py
|
|
91
91
|
src/maintainability_audit/_run_comparison.py
|
|
92
92
|
src/maintainability_audit/_runner.py
|
|
93
|
+
src/maintainability_audit/_running_version.py
|
|
93
94
|
src/maintainability_audit/_safe_write.py
|
|
94
95
|
src/maintainability_audit/_scan_history.py
|
|
95
96
|
src/maintainability_audit/_scan_view.py
|
|
@@ -203,11 +204,13 @@ tests/test_claimed_languages.py
|
|
|
203
204
|
tests/test_cli.py
|
|
204
205
|
tests/test_clone_group_class.py
|
|
205
206
|
tests/test_cobol_declarations.py
|
|
207
|
+
tests/test_code_scanning_gets_alerts_not_the_record.py
|
|
206
208
|
tests/test_cognitive_complexity.py
|
|
207
209
|
tests/test_cohort_statistics.py
|
|
208
210
|
tests/test_concealment_properties.py
|
|
209
211
|
tests/test_config_shape.py
|
|
210
212
|
tests/test_consent_and_grant.py
|
|
213
|
+
tests/test_consent_without_command_has_a_remedy.py
|
|
211
214
|
tests/test_consumer_migration.py
|
|
212
215
|
tests/test_contract_claims.py
|
|
213
216
|
tests/test_corroborate.py
|
|
@@ -224,6 +227,7 @@ tests/test_declaration_grading.py
|
|
|
224
227
|
tests/test_declaration_ranges.py
|
|
225
228
|
tests/test_declaration_source.py
|
|
226
229
|
tests/test_declarative_parsers.py
|
|
230
|
+
tests/test_declared_capabilities_match_the_delegate.py
|
|
227
231
|
tests/test_declared_imports.py
|
|
228
232
|
tests/test_delegated_security_pillar.py
|
|
229
233
|
tests/test_demo_tree.py
|
|
@@ -344,6 +348,7 @@ tests/test_scope_conformance.py
|
|
|
344
348
|
tests/test_scoring_calibration.py
|
|
345
349
|
tests/test_security_delegate_versions_agree.py
|
|
346
350
|
tests/test_security_findings_keep_their_handoff.py
|
|
351
|
+
tests/test_security_pillar_asserts_a_scanner_set.py
|
|
347
352
|
tests/test_security_pillar_runs_and_shows.py
|
|
348
353
|
tests/test_semantic_findings_stay_inside_the_audited_files.py
|
|
349
354
|
tests/test_semantic_policy.py
|
|
@@ -363,6 +368,7 @@ tests/test_tdd_structure.py
|
|
|
363
368
|
tests/test_terminal_asks_the_same_questions.py
|
|
364
369
|
tests/test_test_commands.py
|
|
365
370
|
tests/test_test_execution_class.py
|
|
371
|
+
tests/test_the_agent_knows_when_it_is_stale.py
|
|
366
372
|
tests/test_three_presentations.py
|
|
367
373
|
tests/test_tool_resolution.py
|
|
368
374
|
tests/test_tree_cannot_opt_the_host_in.py
|
{maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_mcp_audit.py
RENAMED
|
@@ -30,6 +30,7 @@ from ._grant_ledger import allowed_roots as allowed_roots # noqa: PLC0414
|
|
|
30
30
|
from ._grant_ledger import refused_root_grants as refused_root_grants # noqa: PLC0414
|
|
31
31
|
from ._mcp_gate import _gate
|
|
32
32
|
from ._recurrence import escalations
|
|
33
|
+
from ._running_version import version_drift
|
|
33
34
|
from ._scan_history import (
|
|
34
35
|
DEFAULT_HISTORY_PATH,
|
|
35
36
|
append_scan,
|
|
@@ -295,6 +296,12 @@ def _top_level_result(report: dict[str, Any], root: Path, status: str,
|
|
|
295
296
|
"analyzers_run": _analyzers_contributed(report),
|
|
296
297
|
"analyzers_requested": run_analyzers,
|
|
297
298
|
}
|
|
299
|
+
# Stated beside the score, not instead of it. A stale agent still
|
|
300
|
+
# produces a real audit; what a reader cannot otherwise know is which
|
|
301
|
+
# release produced it (D188).
|
|
302
|
+
drift = version_drift()
|
|
303
|
+
if drift is not None:
|
|
304
|
+
result["version_drift"] = drift
|
|
298
305
|
if baseline is not None:
|
|
299
306
|
result["new_findings"] = baseline
|
|
300
307
|
# D9: a selected tool that could not run is actionable evidence the
|
{maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/_mcp_gate.py
RENAMED
|
@@ -18,6 +18,8 @@ from pathlib import Path
|
|
|
18
18
|
from typing import Any
|
|
19
19
|
|
|
20
20
|
from ._mcp_setup import run_tests_pending, setup_pending, setup_questions
|
|
21
|
+
from ._running_version import version_drift
|
|
22
|
+
from ._test_execution import consented_without_command
|
|
21
23
|
from ._user_config import mark_repo_seen
|
|
22
24
|
from .config import VERSION, load_config
|
|
23
25
|
|
|
@@ -68,11 +70,18 @@ def _envelope(root: Path) -> dict[str, Any]:
|
|
|
68
70
|
number that no audit produced.
|
|
69
71
|
"""
|
|
70
72
|
mark_repo_seen(root)
|
|
71
|
-
|
|
73
|
+
reply = {
|
|
72
74
|
"agent": "maintainability-agent",
|
|
73
75
|
"agent_version": VERSION,
|
|
74
76
|
"audit_ran": False,
|
|
75
77
|
}
|
|
78
|
+
# Carried on the replies that run no audit, because this is the surface
|
|
79
|
+
# that went stale unnoticed: a server started before an upgrade answers
|
|
80
|
+
# every gate call with its own old version, stated as fact (D188).
|
|
81
|
+
drift = version_drift()
|
|
82
|
+
if drift is not None:
|
|
83
|
+
reply["version_drift"] = drift
|
|
84
|
+
return reply
|
|
76
85
|
|
|
77
86
|
|
|
78
87
|
def _choose_next(root: Path) -> dict[str, Any]:
|
|
@@ -100,6 +109,16 @@ def _choose_next(root: Path) -> dict[str, Any]:
|
|
|
100
109
|
"own test suite for a coverage reading (test effectiveness). "
|
|
101
110
|
"Choose reconfigure to set it up."
|
|
102
111
|
)
|
|
112
|
+
elif consented_without_command():
|
|
113
|
+
# The opt-in was answered yes and the command never reached the
|
|
114
|
+
# person's tier, so `run_tests_pending` reads it as asked-and-done
|
|
115
|
+
# and said nothing. The suite then does not run on any audit, and
|
|
116
|
+
# the report explained the refusal without naming a remedy.
|
|
117
|
+
prompt += (
|
|
118
|
+
" Note: this host is opted in to running the test suite, but no "
|
|
119
|
+
"test command is recorded for it, so no suite runs. Choose "
|
|
120
|
+
"reconfigure to record the command."
|
|
121
|
+
)
|
|
103
122
|
result["choice_needed"] = {
|
|
104
123
|
"name": "next_action",
|
|
105
124
|
"prompt": prompt,
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""Whether the code answering you is the code you installed.
|
|
2
|
+
|
|
3
|
+
`config.VERSION` is a source constant. Every surface reports it as
|
|
4
|
+
`agent_version`, which means the number is read from whatever code is
|
|
5
|
+
loaded — so it is always self-consistent and can never be wrong about
|
|
6
|
+
itself. A server running last week's code states last week's version
|
|
7
|
+
plainly, with nothing marking it stale, and a reader has no way to tell
|
|
8
|
+
that from a correct answer.
|
|
9
|
+
|
|
10
|
+
The installed distribution's metadata is the second opinion. It is
|
|
11
|
+
written to disk by the installer and read fresh on every call, so the
|
|
12
|
+
two disagree exactly when something is out of date — and *which* one is
|
|
13
|
+
ahead says which thing is out of date:
|
|
14
|
+
|
|
15
|
+
* **Loaded code behind the metadata.** A process started before an
|
|
16
|
+
upgrade and is still serving the old module. The install is fine; the
|
|
17
|
+
process is stale. Restart it.
|
|
18
|
+
* **Loaded code ahead of the metadata.** An editable install, whose
|
|
19
|
+
`dist-info` froze at whatever version was current when
|
|
20
|
+
`pip install -e .` ran. The source tree moves and the metadata does
|
|
21
|
+
not, so `--version` keeps printing the right answer while
|
|
22
|
+
`importlib.metadata` answers something years old. Reinstall it.
|
|
23
|
+
|
|
24
|
+
The second case is not hypothetical and is not cosmetic. This project
|
|
25
|
+
gates its security delegate on `metadata.version("secure-code-agent")`
|
|
26
|
+
(`_security_delegate`), so a stale environment does not merely misreport
|
|
27
|
+
a number — it can refuse a delegate that is correctly installed, and
|
|
28
|
+
report the Security pillar as unmeasured, with every other signal
|
|
29
|
+
looking green. On 2026-09-18 an editable venv here carried metadata for
|
|
30
|
+
1.8.0 while serving 3.7.8, with `secure-code-agent` metadata at 0.2.0
|
|
31
|
+
against a floor of 0.12.7.
|
|
32
|
+
|
|
33
|
+
The asymmetry this closes: the audit was strict about the *sibling's*
|
|
34
|
+
installed version and blind to its own.
|
|
35
|
+
|
|
36
|
+
Nothing here raises. An unreadable version is not a reason to fail an
|
|
37
|
+
audit, so the check reports what it found and says nothing when the two
|
|
38
|
+
agree or when metadata cannot be read at all.
|
|
39
|
+
"""
|
|
40
|
+
from __future__ import annotations
|
|
41
|
+
|
|
42
|
+
from .config import VERSION
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def installed_version() -> str | None:
|
|
46
|
+
"""The installed distribution's version, or `None` when unreadable.
|
|
47
|
+
|
|
48
|
+
`None` covers a tree run straight from source with nothing installed,
|
|
49
|
+
which is a legitimate way to run this and not a drift to report.
|
|
50
|
+
"""
|
|
51
|
+
import importlib.metadata as metadata
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
return metadata.version("maintainability-agent")
|
|
55
|
+
except metadata.PackageNotFoundError:
|
|
56
|
+
return None
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
def _as_numbers(text: str) -> tuple[int, ...] | None:
|
|
60
|
+
"""Leading numeric components, for ordering. No `packaging` import.
|
|
61
|
+
|
|
62
|
+
This package has no runtime dependencies, and `_security_delegate`
|
|
63
|
+
reads versions the same way for the same reason.
|
|
64
|
+
"""
|
|
65
|
+
import re
|
|
66
|
+
|
|
67
|
+
parts: list[int] = []
|
|
68
|
+
for piece in text.split("."):
|
|
69
|
+
match = re.match(r"\d+", piece)
|
|
70
|
+
if not match:
|
|
71
|
+
break
|
|
72
|
+
parts.append(int(match.group()))
|
|
73
|
+
if match.group() != piece:
|
|
74
|
+
break
|
|
75
|
+
return tuple(parts) or None
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def version_drift() -> dict[str, str] | None:
|
|
79
|
+
"""What is loaded versus what is installed, when they disagree.
|
|
80
|
+
|
|
81
|
+
`None` when they agree, and when the installed version cannot be read
|
|
82
|
+
— silence is correct for a source checkout, and a check that fired on
|
|
83
|
+
every uninstalled run would be trained away inside a day.
|
|
84
|
+
"""
|
|
85
|
+
installed = installed_version()
|
|
86
|
+
if installed is None or installed == VERSION:
|
|
87
|
+
return None
|
|
88
|
+
|
|
89
|
+
running_parts = _as_numbers(VERSION)
|
|
90
|
+
installed_parts = _as_numbers(installed)
|
|
91
|
+
|
|
92
|
+
if running_parts is not None and installed_parts is not None and running_parts < installed_parts:
|
|
93
|
+
remedy = (
|
|
94
|
+
"A process started before the upgrade is still serving the old "
|
|
95
|
+
"module. The install is current; restart the agent — for the MCP "
|
|
96
|
+
"server, restart the host or stop the running server process."
|
|
97
|
+
)
|
|
98
|
+
elif running_parts is not None and installed_parts is not None:
|
|
99
|
+
remedy = (
|
|
100
|
+
"The installed distribution's metadata is behind the code, which "
|
|
101
|
+
"is what an editable install does: `dist-info` froze when "
|
|
102
|
+
"`pip install -e .` last ran while the source tree moved on. "
|
|
103
|
+
"Reinstall it (`pip install -e .`). Until then anything reading "
|
|
104
|
+
"`importlib.metadata` — including this audit's own security "
|
|
105
|
+
"delegate range check — sees the old number."
|
|
106
|
+
)
|
|
107
|
+
else:
|
|
108
|
+
remedy = (
|
|
109
|
+
"The loaded code and the installed distribution report different "
|
|
110
|
+
"versions. Reinstall the package, and restart any long-running "
|
|
111
|
+
"process serving it."
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
"running": VERSION,
|
|
116
|
+
"installed": installed,
|
|
117
|
+
"detail": (
|
|
118
|
+
f"The code answering is {VERSION}; the installed distribution says "
|
|
119
|
+
f"{installed}. {remedy}"
|
|
120
|
+
),
|
|
121
|
+
}
|
|
@@ -61,9 +61,17 @@ from ._runner import Invocation, Outcome, run
|
|
|
61
61
|
#: `paths:` globs against absolute finding paths. This audit always hands it an
|
|
62
62
|
#: absolute root, so under 0.12.1 every reviewed `paths:` suppression is ignored
|
|
63
63
|
#: and its finding counts as live in the pillar every skin shows (D179).
|
|
64
|
-
|
|
64
|
+
#:
|
|
65
|
+
#: **Raised to 0.12.7 by D186.** The delegate config now declares what this
|
|
66
|
+
#: tool is — `capabilities` — and secure-code-agent sweeps unknown top-level
|
|
67
|
+
#: keys strictly, so anything below 0.12.6 refuses the configuration outright
|
|
68
|
+
#: rather than ignoring the key: the audit would not run at all. 0.12.6 runs
|
|
69
|
+
#: it and prints no reason under the declared axes (its D25), which is a grade
|
|
70
|
+
#: moved in silence. The floor is the first release where the declaration is
|
|
71
|
+
#: both accepted and disclosed.
|
|
72
|
+
SUPPORTED_FLOOR = (0, 12, 7)
|
|
65
73
|
SUPPORTED_CEILING = (1,)
|
|
66
|
-
REQUIREMENT = "secure-code-agent>=0.12.
|
|
74
|
+
REQUIREMENT = "secure-code-agent>=0.12.7,<1"
|
|
67
75
|
|
|
68
76
|
#: How long the child may run before the pillar is reported as unmeasured.
|
|
69
77
|
DEFAULT_TIMEOUT_SECONDS = 300
|
|
@@ -113,6 +113,25 @@ def opted_in_command() -> list[str]:
|
|
|
113
113
|
return list(command) if isinstance(command, list) else []
|
|
114
114
|
|
|
115
115
|
|
|
116
|
+
def consented_without_command() -> bool:
|
|
117
|
+
"""Opted in to running the suite, with no command in the person's tier.
|
|
118
|
+
|
|
119
|
+
`run_tests_pending` covers the config written before the opt-in existed:
|
|
120
|
+
no `test_execution` key at all, so the question was never asked. This
|
|
121
|
+
covers the state after it — the answer is recorded, `requested` is true,
|
|
122
|
+
and `expected_commands.test` never reached the user tier because setup
|
|
123
|
+
captured the consent without capturing the program.
|
|
124
|
+
|
|
125
|
+
Neither surface said anything about it. The report explained why nothing
|
|
126
|
+
ran and named no remedy, and the MCP gate treats a present `test_execution`
|
|
127
|
+
key as asked-and-answered, so it offered no discovery line either. A person
|
|
128
|
+
who said yes got silence on every door.
|
|
129
|
+
"""
|
|
130
|
+
answers = user_config_answers() or {}
|
|
131
|
+
requested = bool((answers.get("test_execution") or {}).get("requested"))
|
|
132
|
+
return requested and not opted_in_command()
|
|
133
|
+
|
|
134
|
+
|
|
116
135
|
def _bounded_suite_timeout(configured: Any) -> int:
|
|
117
136
|
"""A suite timeout the audited tree cannot weaponise.
|
|
118
137
|
|
|
@@ -153,7 +172,9 @@ def run_test_suite(root: Path, config: dict[str, Any]) -> dict[str, Any] | None:
|
|
|
153
172
|
"ran": False, "exit_code": None, "passed": False,
|
|
154
173
|
"detail": (
|
|
155
174
|
"opted in, but no test command is recorded in the user tier; "
|
|
156
|
-
"the repository's documented command is not run on its own say-so"
|
|
175
|
+
"the repository's documented command is not run on its own say-so. "
|
|
176
|
+
"Reconfigure to record the command you consent to, or add it to "
|
|
177
|
+
"expected_commands.test in the user configuration"
|
|
157
178
|
),
|
|
158
179
|
"coverage_percent": None,
|
|
159
180
|
}
|
{maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/cli.py
RENAMED
|
@@ -20,6 +20,7 @@ from ._gates import (
|
|
|
20
20
|
audit_exit_code,
|
|
21
21
|
)
|
|
22
22
|
from ._mcp_audit import record_scan_and_attach
|
|
23
|
+
from ._running_version import version_drift
|
|
23
24
|
from ._safe_write import write_artifact
|
|
24
25
|
from ._scan_history import (
|
|
25
26
|
DEFAULT_HISTORY_PATH,
|
|
@@ -451,6 +452,12 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
451
452
|
return mcp_server.main(argv[1:])
|
|
452
453
|
|
|
453
454
|
parser, args = _parse(argv)
|
|
455
|
+
# Before anything else this run reports, because it is about whether to
|
|
456
|
+
# trust what this run reports at all. stderr, so it never lands in a
|
|
457
|
+
# report piped from stdout (D188).
|
|
458
|
+
drift = version_drift()
|
|
459
|
+
if drift is not None:
|
|
460
|
+
print(f"maintainability-agent: {drift['detail']}", file=sys.stderr)
|
|
454
461
|
_refuse_stdout_where_it_cannot_work(parser, args)
|
|
455
462
|
# Every action that must not trigger the first-run questions.
|
|
456
463
|
early = _action_before_config(parser, args)
|
{maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/config.py
RENAMED
|
@@ -20,7 +20,7 @@ from ._operator_reads import (
|
|
|
20
20
|
# still the door every caller comes through.
|
|
21
21
|
__all__ = ["DEFAULT_CONFIG", "DEFAULT_IDIOM_GROUPS", "PROJECT_URL", "VERSION"]
|
|
22
22
|
|
|
23
|
-
VERSION = "3.7.
|
|
23
|
+
VERSION = "3.7.9"
|
|
24
24
|
|
|
25
25
|
PROJECT_URL = "https://github.com/marshallguillory86/maintainability-agent"
|
|
26
26
|
|
{maintainability_agent-3.7.7 → maintainability_agent-3.7.9}/src/maintainability_audit/mcp_server.py
RENAMED
|
@@ -52,6 +52,7 @@ from ._mcp_setup import (
|
|
|
52
52
|
setup_schema,
|
|
53
53
|
test_command_pending,
|
|
54
54
|
)
|
|
55
|
+
from ._running_version import version_drift
|
|
55
56
|
from ._scan_history import DEFAULT_HISTORY_PATH
|
|
56
57
|
from .baseline import StaleBaseline as StaleBaseline
|
|
57
58
|
from .config import (
|
|
@@ -110,9 +111,13 @@ SERVER_INSTRUCTIONS = (
|
|
|
110
111
|
|
|
111
112
|
def server_info(roots: tuple[Path, ...] | None = None) -> dict[str, Any]:
|
|
112
113
|
authorized_roots = roots if roots is not None else allowed_roots()
|
|
114
|
+
drift = version_drift()
|
|
113
115
|
return {
|
|
114
116
|
"agent": "maintainability-agent",
|
|
115
117
|
"agent_version": VERSION,
|
|
118
|
+
# None when the loaded code and the installed distribution agree,
|
|
119
|
+
# which is the ordinary case and says nothing (D188).
|
|
120
|
+
"version_drift": drift,
|
|
116
121
|
"transport": "stdio",
|
|
117
122
|
"local": True,
|
|
118
123
|
# Not blanket read-only since D2/D5: setup, the loop record and
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"""What this repository uploads to code scanning is what should become an alert (D187).
|
|
2
|
+
|
|
3
|
+
secure-code-agent writes two SARIF documents (its D22). `--sarif-output` is the
|
|
4
|
+
record: every result, a suppressed one carrying its `suppressions` entry and
|
|
5
|
+
reason. `--code-scanning-sarif-output` is the same document without the
|
|
6
|
+
suppressed results — the test tree, documentation, and every reviewed
|
|
7
|
+
`.scignore.yaml` entry.
|
|
8
|
+
|
|
9
|
+
The difference matters because code scanning opens an alert for every result it
|
|
10
|
+
is handed, `suppressions` array or not, and this repository's branch protection
|
|
11
|
+
requires every resulting review thread resolved before a merge. Uploading the
|
|
12
|
+
record put seventeen threads on one pull request, all of them `assert` in a
|
|
13
|
+
pytest file, and blocked it. That is not a one-off: it is the outcome for every
|
|
14
|
+
pull request that adds a test, forever, and the shape secure-code-agent already
|
|
15
|
+
fixed upstream and this repository had not adopted.
|
|
16
|
+
|
|
17
|
+
Nothing is hidden by the change. The record is still written, still kept as a
|
|
18
|
+
build artifact, and still carries every finding; so do the JSON report, the
|
|
19
|
+
Markdown report and the work order. What changes is which document becomes
|
|
20
|
+
somebody's blocking alert.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
from __future__ import annotations
|
|
24
|
+
|
|
25
|
+
import re
|
|
26
|
+
from pathlib import Path
|
|
27
|
+
|
|
28
|
+
ROOT = Path(__file__).resolve().parents[1]
|
|
29
|
+
WORKFLOWS = ROOT / ".github" / "workflows"
|
|
30
|
+
|
|
31
|
+
#: The record. Never the thing uploaded to code scanning.
|
|
32
|
+
_RECORD = "secure-code.sarif"
|
|
33
|
+
#: The filtered document, which is.
|
|
34
|
+
_FILTERED = "secure-code.code-scanning.sarif"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def _uploads() -> list[tuple[str, str]]:
|
|
38
|
+
"""Every `sarif_file:` value handed to the code-scanning upload action."""
|
|
39
|
+
found = []
|
|
40
|
+
for path in sorted(WORKFLOWS.glob("*.yml")):
|
|
41
|
+
for match in re.finditer(r"^\s*sarif_file:\s*(\S+)\s*$", path.read_text(encoding="utf-8"), re.MULTILINE):
|
|
42
|
+
found.append((path.name, match.group(1)))
|
|
43
|
+
return found
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
def test_the_security_record_is_never_uploaded_to_code_scanning() -> None:
|
|
47
|
+
"""The record carries the test tree; code scanning turns each one into a thread."""
|
|
48
|
+
uploads = _uploads()
|
|
49
|
+
assert uploads, "no workflow uploads SARIF; this sweep would pass vacuously"
|
|
50
|
+
record = [(name, value) for name, value in uploads if value == _RECORD]
|
|
51
|
+
assert not record, (
|
|
52
|
+
f"the full secure-code-agent record is uploaded to code scanning: {record}. "
|
|
53
|
+
"Every suppressed finding becomes an alert, and under this repository's "
|
|
54
|
+
"required-conversation-resolution policy, a blocking review thread."
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_the_filtered_document_is_what_is_uploaded() -> None:
|
|
59
|
+
"""Proving the record is absent is not proving the right file is present."""
|
|
60
|
+
uploaded = {value for _, value in _uploads()}
|
|
61
|
+
assert _FILTERED in uploaded, (
|
|
62
|
+
f"no workflow uploads {_FILTERED}; the security findings that should "
|
|
63
|
+
"become alerts would reach code scanning from nowhere"
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
def test_the_audit_asks_the_delegate_to_write_the_filtered_document() -> None:
|
|
68
|
+
"""An upload step naming a file nothing writes fails the job, loudly but late."""
|
|
69
|
+
writing = [
|
|
70
|
+
path.name
|
|
71
|
+
for path in sorted(WORKFLOWS.glob("*.yml"))
|
|
72
|
+
if f"--code-scanning-sarif-output {_FILTERED}" in path.read_text(encoding="utf-8")
|
|
73
|
+
]
|
|
74
|
+
assert writing, (
|
|
75
|
+
f"no workflow passes --code-scanning-sarif-output {_FILTERED}; the upload "
|
|
76
|
+
"step would name a file the security audit never produced"
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
def test_the_filtered_document_is_not_committed() -> None:
|
|
81
|
+
"""Generated per run, like every other audit output this repository writes."""
|
|
82
|
+
ignored = (ROOT / ".gitignore").read_text(encoding="utf-8").splitlines()
|
|
83
|
+
assert _FILTERED in ignored, f"{_FILTERED} is not in .gitignore"
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"""Consent to run the suite, with no command, must name a way out (D185).
|
|
2
|
+
|
|
3
|
+
`test_execution.requested` true with no `expected_commands.test` in the user
|
|
4
|
+
tier is a reachable state: setup recorded the answer without recording the
|
|
5
|
+
program. In that state no suite runs on any audit.
|
|
6
|
+
|
|
7
|
+
Neither surface said what to do about it. The report explained the refusal and
|
|
8
|
+
stopped there, and the MCP gate treats a present `test_execution` key as
|
|
9
|
+
asked-and-answered, so `run_tests_pending` is false and no discovery line is
|
|
10
|
+
offered. A person who opted in got silence on every door, which is how this
|
|
11
|
+
repository's own audit reported "it did not run" for weeks.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
import pytest
|
|
18
|
+
|
|
19
|
+
from maintainability_audit import _mcp_gate, _test_execution
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@pytest.fixture
|
|
23
|
+
def consented(monkeypatch):
|
|
24
|
+
"""User tier that opted in and carries no command."""
|
|
25
|
+
monkeypatch.setattr(
|
|
26
|
+
_test_execution, "user_config_answers",
|
|
27
|
+
lambda: {"test_execution": {"requested": True}})
|
|
28
|
+
return None
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_the_report_detail_names_a_remedy(consented, tmp_path):
|
|
32
|
+
"""The operator is told how to fix it, not only why it happened."""
|
|
33
|
+
result = _test_execution.run_test_suite(
|
|
34
|
+
tmp_path,
|
|
35
|
+
{"test_execution": {"requested": True},
|
|
36
|
+
"expected_commands": {"test": ["pytest", "-q"]}})
|
|
37
|
+
|
|
38
|
+
assert result is not None and result["ran"] is False
|
|
39
|
+
detail = result["detail"].lower()
|
|
40
|
+
assert "reconfigure" in detail or "expected_commands" in detail, (
|
|
41
|
+
f"the refusal names no remedy: {result['detail']!r}")
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def test_the_predicate_sees_consent_without_a_command(consented):
|
|
45
|
+
"""`run_tests_pending` cannot see this state; this is what does."""
|
|
46
|
+
assert _test_execution.consented_without_command() is True
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_a_recorded_command_is_not_reported_as_missing(monkeypatch):
|
|
50
|
+
"""The predicate is about the gap, not about opting in."""
|
|
51
|
+
monkeypatch.setattr(
|
|
52
|
+
_test_execution, "user_config_answers",
|
|
53
|
+
lambda: {"test_execution": {"requested": True},
|
|
54
|
+
"expected_commands": {"test": ["pytest", "-q"]}})
|
|
55
|
+
assert _test_execution.consented_without_command() is False
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
def test_the_mcp_gate_offers_reconfigure_for_the_gap(consented, monkeypatch, tmp_path):
|
|
59
|
+
"""The chat door surfaces it too, where `run_tests_pending` is false."""
|
|
60
|
+
monkeypatch.setattr(_mcp_gate, "run_tests_pending", lambda root: False)
|
|
61
|
+
|
|
62
|
+
result = _mcp_gate._choose_next(Path(tmp_path))
|
|
63
|
+
|
|
64
|
+
prompt = (result.get("choice_needed") or {}).get("prompt", "").lower()
|
|
65
|
+
assert "no test command is recorded" in prompt, (
|
|
66
|
+
f"the gate says nothing about the gap: {prompt!r}")
|