maintainability-agent 3.6.3__tar.gz → 3.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {maintainability_agent-3.6.3/src/maintainability_agent.egg-info → maintainability_agent-3.7.0}/PKG-INFO +3 -2
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/README.md +1 -1
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/pyproject.toml +9 -1
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0/src/maintainability_agent.egg-info}/PKG-INFO +3 -2
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_agent.egg-info/SOURCES.txt +2 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_agent.egg-info/requires.txt +1 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/__init__.py +1 -1
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_delegated_pillar.py +19 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_pillars.py +9 -3
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_prompt_sections.py +24 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_scan_view.py +7 -0
- maintainability_agent-3.7.0/src/maintainability_audit/_security_delegate.py +121 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/config.py +1 -1
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/mcp_server.py +15 -9
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/prompts.py +2 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/renderers.py +6 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/report.py +29 -13
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_consent_and_grant.py +8 -3
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_first_run_elicitation.py +1 -1
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_mcp_baseline_payload.py +1 -1
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_mcp_history.py +7 -3
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_mcp_server.py +1 -1
- maintainability_agent-3.7.0/tests/test_security_pillar_runs_and_shows.py +207 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/LICENSE +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/setup.cfg +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_adapters.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_analysis.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_analyzer_sections.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_anchor.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_assets/standard.md +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_banner.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_catalog.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_cognitive.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_coverage_notes.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_criteria_scope.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_evidence_reader.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_evidence_view.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_first_run.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_gates.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_grammar.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_html_view.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_in_loop.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_in_loop_view.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_jvm_adapters.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_masking.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_mcp_audit.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_mcp_setup.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_metric_adapters.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_operator_reads.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_precommit.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_precommit_install.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_precommit_view.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_cobol.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_go.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_php.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_ruby.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_rust.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ranges_swift.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_ratio_adapters.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_semantic_ts.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_setup_persist.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_verdict_adapters.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/cli.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/scoring.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_adapters.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_added_lines.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_anchor_and_mode.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_anchor_disclosure.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_architecture.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_attestation.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_audit_components.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_backfill.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_bands.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_chat_leads_with_the_work_order.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_check_refuses_plus_only_fragments.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_child_sandbox.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_cli.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_config_shape.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_corroborate.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_criteria_completion.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_dead_code.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_declaration_criteria_scope.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_declarative_parsers.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_declared_authorship.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_delegated_security_pillar.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_demo_tree.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_determinism.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_direct_runner_availability_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_discovery.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_docs_links.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_economic_context.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_every_surface_says_what_the_run_found.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_example_config_opens_claimed_languages.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_exposure_never_outranks_band.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_format_ask.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_git_argv.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_go_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_grammar_constructs.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_grammar_token_coverage.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_history.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_history_window.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_html_executive.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_in_loop_budgets.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_in_loop_check.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_java_scored.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_language_support_honesty.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_mcp_format_contract.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_operator_named_paths.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_operator_named_reads.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_pairing_reads_imports.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_php_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_platform_claim.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_policy_claims.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_population_floors.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_precommit_staged.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_promises.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_python_complexity.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_readme_claims.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_recurrence.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_release_needs_an_empty_ledger.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_release_plan.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_roles_recorded.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_root_grants.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_ruby_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_runner.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_rust_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_sarif.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_scan_history.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_scanner_unsafe_direction.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_scanning.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_skill_install.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_sonar_resolve.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_source_index.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_stage8_contract.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_stdout_outputs.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_terminal_asks_the_same_questions.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_test_commands.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_tool_resolution.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_tree_chosen_spawn.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_tree_reads_use_the_primitive.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_trends.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_unanchored_set_matches_corpus.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_unread_code.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_verified_grade.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_version_claim.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_work_items_state_their_own_finding.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_work_order.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_written_record.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.7.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -19,6 +19,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
19
19
|
Requires-Python: >=3.11
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
+
Requires-Dist: secure-code-agent<0.11,>=0.10
|
|
22
23
|
Provides-Extra: test
|
|
23
24
|
Requires-Dist: pytest>=8; extra == "test"
|
|
24
25
|
Requires-Dist: pytest-cov>=5; extra == "test"
|
|
@@ -46,7 +47,7 @@ Dynamic: license-file
|
|
|
46
47
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
47
48
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
48
49
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
49
|
-
Version **3.
|
|
50
|
+
Version **3.7.0**.
|
|
50
51
|
|
|
51
52
|
**Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
|
|
52
53
|
COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -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.
|
|
8
|
+
Version **3.7.0**.
|
|
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
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "maintainability-agent"
|
|
7
|
-
version = "3.
|
|
7
|
+
version = "3.7.0"
|
|
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
|
|
@@ -13,6 +13,14 @@ readme = "README.md"
|
|
|
13
13
|
# metadata said a user could stand: the suite runs 3.12 and the
|
|
14
14
|
# composite action pins 3.11 (D42).
|
|
15
15
|
requires-python = ">=3.11"
|
|
16
|
+
# The security pillar is complete (D177): every audit runs secure-code-agent,
|
|
17
|
+
# so it installs with this package rather than being left to the operator.
|
|
18
|
+
# Its own dependency is PyYAML; this package still imports no YAML
|
|
19
|
+
# (`test_the_shipped_package_does_not_import_yaml`) — it runs the tool as a
|
|
20
|
+
# child and reads the JSON document it writes.
|
|
21
|
+
dependencies = [
|
|
22
|
+
"secure-code-agent>=0.10,<0.11",
|
|
23
|
+
]
|
|
16
24
|
license = { text = "MIT" }
|
|
17
25
|
authors = [
|
|
18
26
|
{ name = "Marshall Guillory" }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.7.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -19,6 +19,7 @@ Classifier: Topic :: Software Development :: Quality Assurance
|
|
|
19
19
|
Requires-Python: >=3.11
|
|
20
20
|
Description-Content-Type: text/markdown
|
|
21
21
|
License-File: LICENSE
|
|
22
|
+
Requires-Dist: secure-code-agent<0.11,>=0.10
|
|
22
23
|
Provides-Extra: test
|
|
23
24
|
Requires-Dist: pytest>=8; extra == "test"
|
|
24
25
|
Requires-Dist: pytest-cov>=5; extra == "test"
|
|
@@ -46,7 +47,7 @@ Dynamic: license-file
|
|
|
46
47
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
47
48
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
48
49
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
49
|
-
Version **3.
|
|
50
|
+
Version **3.7.0**.
|
|
50
51
|
|
|
51
52
|
**Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
|
|
52
53
|
COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
|
|
@@ -94,6 +94,7 @@ src/maintainability_audit/_safe_write.py
|
|
|
94
94
|
src/maintainability_audit/_scan_history.py
|
|
95
95
|
src/maintainability_audit/_scan_view.py
|
|
96
96
|
src/maintainability_audit/_second_source.py
|
|
97
|
+
src/maintainability_audit/_security_delegate.py
|
|
97
98
|
src/maintainability_audit/_selection.py
|
|
98
99
|
src/maintainability_audit/_semantic.py
|
|
99
100
|
src/maintainability_audit/_semantic_policy.py
|
|
@@ -340,6 +341,7 @@ tests/test_scanning.py
|
|
|
340
341
|
tests/test_schema_fidelity.py
|
|
341
342
|
tests/test_scope_conformance.py
|
|
342
343
|
tests/test_scoring_calibration.py
|
|
344
|
+
tests/test_security_pillar_runs_and_shows.py
|
|
343
345
|
tests/test_semantic_policy.py
|
|
344
346
|
tests/test_setup_gate_completeness.py
|
|
345
347
|
tests/test_setup_gate_independent_contract.py
|
|
@@ -123,6 +123,25 @@ def read_delegated(root: Path, relative: str = DEFAULT_PILLAR_PATH) -> dict[str,
|
|
|
123
123
|
if isinstance(error, PathNotAllowed):
|
|
124
124
|
raise
|
|
125
125
|
return None
|
|
126
|
+
return trusted(payload)
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def read_produced(path: Path) -> dict[str, Any] | None:
|
|
130
|
+
"""The document this tool's own run of secure-code-agent just wrote (D177).
|
|
131
|
+
|
|
132
|
+
The file sits in a temporary directory this process created, not in the
|
|
133
|
+
audited tree, so it is read directly; every check a handed-over document
|
|
134
|
+
passes still applies, because the producer is the same tool either way.
|
|
135
|
+
"""
|
|
136
|
+
try:
|
|
137
|
+
payload = json.loads(Path(path).read_text(encoding="utf-8"))
|
|
138
|
+
except (OSError, ValueError):
|
|
139
|
+
return None
|
|
140
|
+
return trusted(payload)
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
def trusted(payload: Any) -> dict[str, Any] | None:
|
|
144
|
+
"""The payload when it is a document this module understands, else `None`."""
|
|
126
145
|
if not isinstance(payload, dict):
|
|
127
146
|
return None
|
|
128
147
|
if payload.get("schema") != SCHEMA:
|
{maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_pillars.py
RENAMED
|
@@ -87,8 +87,9 @@ PILLARS: tuple[Pillar, ...] = (
|
|
|
87
87
|
name="security",
|
|
88
88
|
scope=Scope.DELEGATED,
|
|
89
89
|
reason=(
|
|
90
|
-
"delegated to secure-code-agent
|
|
91
|
-
"
|
|
90
|
+
"delegated to secure-code-agent, which this audit runs for the pillar; "
|
|
91
|
+
"when no measurement comes back the reason is given here, because "
|
|
92
|
+
"silence is not safety"
|
|
92
93
|
),
|
|
93
94
|
),
|
|
94
95
|
Pillar(
|
|
@@ -213,9 +214,14 @@ def pillar_report(
|
|
|
213
214
|
score: dict[str, Any],
|
|
214
215
|
practice: dict[str, Any],
|
|
215
216
|
delegated: dict[str, dict[str, Any]] | None = None,
|
|
217
|
+
unmeasured: dict[str, str] | None = None,
|
|
216
218
|
) -> list[dict[str, Any]]:
|
|
217
219
|
"""The pillar block exactly as it ships.
|
|
218
220
|
|
|
221
|
+
`unmeasured` names, per delegated pillar, why no measurement came back
|
|
222
|
+
from a run of the tool that owns it (D177), and replaces the generic
|
|
223
|
+
reason so the reader learns what actually happened.
|
|
224
|
+
|
|
219
225
|
Practice arrives as an argument rather than being computed here.
|
|
220
226
|
`_practice` reads the repository's configuration off disk, which
|
|
221
227
|
makes it a scanner, and the scoring layer may not reach upward into
|
|
@@ -251,7 +257,7 @@ def pillar_report(
|
|
|
251
257
|
report.append({
|
|
252
258
|
"pillar": pillar.name,
|
|
253
259
|
"scope": pillar.scope.value,
|
|
254
|
-
"reason": pillar.reason,
|
|
260
|
+
"reason": (unmeasured or {}).get(pillar.name) or pillar.reason,
|
|
255
261
|
# Both axes, side by side, never merged. A consumer reads
|
|
256
262
|
# either one; nothing in the document offers their mean.
|
|
257
263
|
"practice": resolved["level"],
|
|
@@ -118,6 +118,30 @@ def prompt_analyzer_caveat(report: dict[str, Any]) -> list[str]:
|
|
|
118
118
|
]
|
|
119
119
|
|
|
120
120
|
|
|
121
|
+
def prompt_security_pillar(report: dict[str, Any]) -> list[str]:
|
|
122
|
+
"""What the security pillar reported, stated where an agent reads the run (D176).
|
|
123
|
+
|
|
124
|
+
Evidence, never a task: security remediation is secure-code-agent's own
|
|
125
|
+
work order, not this prompt's. But a prompt that says nothing about
|
|
126
|
+
security lets an agent read silence as a clean bill, which is the one
|
|
127
|
+
reading ADR 007 exists to prevent.
|
|
128
|
+
"""
|
|
129
|
+
entry = next((p for p in report.get("pillars") or [] if p.get("pillar") == "security"), None)
|
|
130
|
+
if entry is None:
|
|
131
|
+
return []
|
|
132
|
+
if not entry.get("delegated_to"):
|
|
133
|
+
return [f"**Security pillar: not measured.** {entry.get('reason')}.", ""]
|
|
134
|
+
producer = entry.get("delegated_to") or "the delegated tool"
|
|
135
|
+
version = f" {entry['producer_version']}" if entry.get("producer_version") else ""
|
|
136
|
+
condition = "not graded" if entry.get("condition") is None else f"{entry['condition']:.1f}"
|
|
137
|
+
return [
|
|
138
|
+
f"**Security pillar (measured by {producer}{version}):** posture "
|
|
139
|
+
f"{entry.get('posture')}, practice level {entry.get('practice')}, condition "
|
|
140
|
+
f"{condition}. Its findings are that tool's work order, not this one.",
|
|
141
|
+
"",
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
|
|
121
145
|
def prompt_escalation_note(report: dict[str, Any]) -> list[str]:
|
|
122
146
|
"""Tell the agent what is deliberately absent, and why.
|
|
123
147
|
|
{maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/_scan_view.py
RENAMED
|
@@ -364,6 +364,13 @@ def pillar_cells(entry: dict[str, Any]) -> tuple[str, str]:
|
|
|
364
364
|
condition = "—" if entry["condition"] is None else f"{entry['condition']:.1f}"
|
|
365
365
|
if entry["posture"] is None:
|
|
366
366
|
return condition, "not measured — see below"
|
|
367
|
+
if entry["condition"] is None:
|
|
368
|
+
# An ungraded pillar is `unverified` because nothing could be graded,
|
|
369
|
+
# not because a clean scan lacks enforcement — the note for that cell
|
|
370
|
+
# told a reader of secure-code-agent's partial-coverage pillar that
|
|
371
|
+
# its scan was clean (D176). Say why no grade was issued instead.
|
|
372
|
+
why = (entry.get("evidence_reasons") or [None])[0] or "the evidence could not support a grade"
|
|
373
|
+
return condition, f"{entry['posture']}: not graded — {why}"
|
|
367
374
|
note = POSTURE_NOTE.get(entry["posture"], entry["posture"])
|
|
368
375
|
return condition, f"{entry['posture']}: {note}"
|
|
369
376
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""This tool runs secure-code-agent for the security pillar (D177).
|
|
2
|
+
|
|
3
|
+
[ADR 007](adr-007-pillars-and-practice.md) delegates the security pillar to
|
|
4
|
+
`secure-code-agent`. Until 3.7.0 the delegation was a handoff: the other
|
|
5
|
+
tool wrote `security-pillar.json` and this one read it if it happened to be
|
|
6
|
+
there. Nothing ran it, so every audit that did not follow a manual or CI run
|
|
7
|
+
of the other tool reported the pillar as unmeasured — including every audit
|
|
8
|
+
through the chat door, which cannot run it at all. Decided 2026-09-13 with
|
|
9
|
+
Marshall: the pillar is complete, so the audit runs it.
|
|
10
|
+
|
|
11
|
+
**What the child writes.** Every report `secure-code-agent` can produce is
|
|
12
|
+
redirected into a temporary directory this process owns: the Markdown and
|
|
13
|
+
JSON reports, SARIF, the PR comment, the remediation prompt and the pillar
|
|
14
|
+
document itself. The one write that cannot be redirected is its append-only
|
|
15
|
+
trend, `.secure-code/history.jsonl` in the audited tree, which it writes on
|
|
16
|
+
every run from its own configuration. Turning that off would mean handing
|
|
17
|
+
it a configuration from outside the tree, and `secure-code-agent` trusts an
|
|
18
|
+
outside configuration to name executables in the tree — so the override
|
|
19
|
+
would launder repository content past the other tool's own boundary. The
|
|
20
|
+
history is therefore declared, not suppressed.
|
|
21
|
+
|
|
22
|
+
**How the child is started.** Through `_runner.run`, like every analyzer and
|
|
23
|
+
the opted-in test command, so architecture rule 7 still holds: the tree can
|
|
24
|
+
reach one execution path, not a new one per feature. The command is the
|
|
25
|
+
interpreter doing the auditing, the way D144 and D166 bound theirs, so the
|
|
26
|
+
pillar is measured by the `secure-code-agent` installed beside this package
|
|
27
|
+
rather than whichever one `PATH` finds. It gets the runner's stripped
|
|
28
|
+
environment and a neutral working directory: not a sandbox, and not claimed
|
|
29
|
+
as one.
|
|
30
|
+
|
|
31
|
+
A run that produces no trustworthy document says why. Absence is never
|
|
32
|
+
silent, because silence is exactly what ADR 007 says must not read as safety.
|
|
33
|
+
"""
|
|
34
|
+
from __future__ import annotations
|
|
35
|
+
|
|
36
|
+
import importlib.util
|
|
37
|
+
import shlex
|
|
38
|
+
import sys
|
|
39
|
+
import tempfile
|
|
40
|
+
from dataclasses import dataclass, field
|
|
41
|
+
from pathlib import Path
|
|
42
|
+
from typing import Any
|
|
43
|
+
|
|
44
|
+
from ._delegated_pillar import read_produced
|
|
45
|
+
from ._runner import Invocation, Outcome, run
|
|
46
|
+
|
|
47
|
+
#: The distribution the pillar requires, and the range this tool reads.
|
|
48
|
+
REQUIREMENT = "secure-code-agent>=0.10,<0.11"
|
|
49
|
+
|
|
50
|
+
#: How long the child may run before the pillar is reported as unmeasured.
|
|
51
|
+
DEFAULT_TIMEOUT_SECONDS = 300
|
|
52
|
+
|
|
53
|
+
_ENTRY = "import sys; from secure_code_audit.cli import main; sys.exit(main())"
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@dataclass(frozen=True)
|
|
57
|
+
class DelegateRun:
|
|
58
|
+
"""What one run of the delegate produced, and why when it produced nothing."""
|
|
59
|
+
|
|
60
|
+
document: dict[str, Any] | None
|
|
61
|
+
reason: str | None = None
|
|
62
|
+
environment: list[dict[str, str]] = field(default_factory=list)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _install_remedy(reason: str) -> dict[str, str]:
|
|
66
|
+
"""An environment work-order entry, bound to the auditing interpreter (D144)."""
|
|
67
|
+
python = shlex.quote(sys.executable)
|
|
68
|
+
return {
|
|
69
|
+
"tool": "secure-code-agent",
|
|
70
|
+
"reason": reason,
|
|
71
|
+
"install": f"{python} -m pip install '{REQUIREMENT}'",
|
|
72
|
+
"verify": f"{python} -m pip show secure-code-agent",
|
|
73
|
+
"concepts": "security",
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def run_security_delegate(
|
|
78
|
+
root: Path, *, changed_revspec: str | None = None,
|
|
79
|
+
timeout_seconds: int = DEFAULT_TIMEOUT_SECONDS,
|
|
80
|
+
) -> DelegateRun:
|
|
81
|
+
"""Run `secure-code-agent` over `root` and return its pillar document."""
|
|
82
|
+
if importlib.util.find_spec("secure_code_audit") is None:
|
|
83
|
+
reason = "secure-code-agent is not installed for the interpreter running this audit"
|
|
84
|
+
return DelegateRun(None, reason, [_install_remedy(reason)])
|
|
85
|
+
with tempfile.TemporaryDirectory(prefix="ma-security-") as scratch:
|
|
86
|
+
out = Path(scratch)
|
|
87
|
+
pillar = out / "security-pillar.json"
|
|
88
|
+
argv = [
|
|
89
|
+
sys.executable, "-c", _ENTRY, str(root),
|
|
90
|
+
"--security-pillar", str(pillar),
|
|
91
|
+
"--output", str(out / "report.md"),
|
|
92
|
+
"--json-output", str(out / "report.json"),
|
|
93
|
+
"--sarif-output", str(out / "report.sarif"),
|
|
94
|
+
"--comment-output", str(out / "comment.md"),
|
|
95
|
+
"--prompt-output", str(out / "prompt.md"),
|
|
96
|
+
]
|
|
97
|
+
if changed_revspec:
|
|
98
|
+
argv += ["--changed-only", changed_revspec]
|
|
99
|
+
# Exit 1 is the tool's gate verdict, not a failure to measure: the
|
|
100
|
+
# pillar document is still written, and the pillar reports the gate.
|
|
101
|
+
result = run("secure-code-agent", Invocation(
|
|
102
|
+
argv=tuple(argv), findings_exit_codes=(0, 1), cwd=out,
|
|
103
|
+
), timeout_seconds=timeout_seconds)
|
|
104
|
+
document = read_produced(pillar)
|
|
105
|
+
if document is not None:
|
|
106
|
+
return DelegateRun(document)
|
|
107
|
+
if result.outcome is Outcome.TIMED_OUT:
|
|
108
|
+
return DelegateRun(None, f"secure-code-agent did not finish within {timeout_seconds}s")
|
|
109
|
+
detail = _last_line(result.stderr) or _last_line(result.stdout) or result.detail
|
|
110
|
+
# No install remedy here: the tool is installed and ran. A rejected
|
|
111
|
+
# configuration or a crash is fixed in the repository or reported
|
|
112
|
+
# upstream, and an install command would send the reader to the
|
|
113
|
+
# wrong place.
|
|
114
|
+
reason = (f"secure-code-agent exited {result.exit_code} without a pillar document"
|
|
115
|
+
+ (f": {detail}" if detail else ""))
|
|
116
|
+
return DelegateRun(None, reason)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def _last_line(text: str | None) -> str:
|
|
120
|
+
lines = [line.strip() for line in (text or "").splitlines() if line.strip()]
|
|
121
|
+
return lines[-1][:200] if lines else ""
|
{maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/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.
|
|
23
|
+
VERSION = "3.7.0"
|
|
24
24
|
|
|
25
25
|
PROJECT_URL = "https://github.com/marshallguillory86/maintainability-agent"
|
|
26
26
|
|
{maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/mcp_server.py
RENAMED
|
@@ -4,10 +4,12 @@ This module is transport assembly: tool bindings, resources, prompts and
|
|
|
4
4
|
the stdio entry point. The audit tool's own logic — authorization,
|
|
5
5
|
tri-state resolution, history recording — lives in ``_mcp_audit`` and is
|
|
6
6
|
re-exported here so every consumer keeps one import path. Setup, the
|
|
7
|
-
loop record and baseline adoption may write only
|
|
7
|
+
loop record and baseline adoption may write only six local artifacts:
|
|
8
8
|
repository and user configuration, user state, the repository's scan
|
|
9
|
-
history,
|
|
10
|
-
|
|
9
|
+
history, the repository's baseline, and — because an audit runs
|
|
10
|
+
secure-code-agent for the security pillar (D177) — that tool's own
|
|
11
|
+
append-only trend. It never writes source or a report, accepts a command
|
|
12
|
+
string, or invokes a shell.
|
|
11
13
|
"""
|
|
12
14
|
|
|
13
15
|
from __future__ import annotations
|
|
@@ -66,11 +68,13 @@ SERVER_INSTRUCTIONS = (
|
|
|
66
68
|
"step: do not inspect configuration first and do not ask the user "
|
|
67
69
|
"which config to use — the tool resolves that itself. First contact with an "
|
|
68
70
|
"unconfigured repository elicits setup, and the audit records its scan "
|
|
69
|
-
"history and can adopt a baseline, so it may write exactly
|
|
71
|
+
"history and can adopt a baseline, so it may write exactly six local "
|
|
70
72
|
"artifacts: the repository's maintainability-agent.json, the user-level "
|
|
71
73
|
"config, the user state file, the repository's scan history "
|
|
72
|
-
"(.maintainability/history.jsonl by default),
|
|
73
|
-
"(.maintainability/baseline.json by default)
|
|
74
|
+
"(.maintainability/history.jsonl by default), a requested baseline "
|
|
75
|
+
"(.maintainability/baseline.json by default), and secure-code-agent's own "
|
|
76
|
+
"trend (.secure-code/history.jsonl), which that tool appends when the audit "
|
|
77
|
+
"runs it for the security pillar. Scan history rides the "
|
|
74
78
|
"record_history tri-state, where unset means an existing history file "
|
|
75
79
|
"appends and otherwise the persisted first-run consent decides, "
|
|
76
80
|
"true forces the write, and false suppresses it. Nothing is audited "
|
|
@@ -109,12 +113,14 @@ def server_info(roots: tuple[Path, ...] | None = None) -> dict[str, Any]:
|
|
|
109
113
|
"transport": "stdio",
|
|
110
114
|
"local": True,
|
|
111
115
|
# Not blanket read-only since D2/D5: setup, the loop record and
|
|
112
|
-
# baseline adoption write
|
|
113
|
-
#
|
|
116
|
+
# baseline adoption write the local artifacts listed below, and the
|
|
117
|
+
# security pillar's run of secure-code-agent appends that tool's own
|
|
118
|
+
# trend (D177). Never source and never a report.
|
|
114
119
|
"read_only": False,
|
|
115
120
|
"writes": [CONFIG_FILENAME, "user config", "user state",
|
|
116
121
|
f"scan history ({DEFAULT_HISTORY_PATH})",
|
|
117
|
-
"baseline (.maintainability/baseline.json)"
|
|
122
|
+
"baseline (.maintainability/baseline.json)",
|
|
123
|
+
"secure-code-agent history (.secure-code/history.jsonl)"],
|
|
118
124
|
"never_writes": ["source", "reports"],
|
|
119
125
|
"allowed_roots": [str(root) for root in authorized_roots],
|
|
120
126
|
# Stored grants this process will not honour. A hand-written
|
{maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/prompts.py
RENAMED
|
@@ -69,6 +69,7 @@ def render_ai_prompt(report: dict[str, Any]) -> str:
|
|
|
69
69
|
"",
|
|
70
70
|
])
|
|
71
71
|
lines.extend(prompt_analyzer_caveat(report))
|
|
72
|
+
lines.extend(prompt_security_pillar(report))
|
|
72
73
|
# The prompt is the product artifact (H1): its remedy follows the
|
|
73
74
|
# same report fact as every other skin, never a stale default.
|
|
74
75
|
lines.extend(view.remediation_note(
|
|
@@ -155,6 +156,7 @@ from ._prompt_sections import ( # noqa: E402,F401 - re-export after the split
|
|
|
155
156
|
prompt_focus_sections,
|
|
156
157
|
prompt_has_work,
|
|
157
158
|
prompt_pressure_section,
|
|
159
|
+
prompt_security_pillar,
|
|
158
160
|
prompt_semantic_section,
|
|
159
161
|
prompt_tdd_section,
|
|
160
162
|
prompt_work_order,
|
{maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/renderers.py
RENAMED
|
@@ -214,6 +214,12 @@ def _bounded_markdown(report: dict[str, Any], score: dict[str, Any],
|
|
|
214
214
|
lines.extend(summary)
|
|
215
215
|
lines.extend(render_grade_blockers(report))
|
|
216
216
|
lines.extend(score_table(score))
|
|
217
|
+
# The pillars, security among them, in the view most people read (D176).
|
|
218
|
+
# Rendered by the same function the complete report uses, so the two
|
|
219
|
+
# skins cannot disagree about a pillar (ADR 011); before this the chat
|
|
220
|
+
# view printed nothing about security at all, measured or not, and a
|
|
221
|
+
# missing pillar read exactly like a clean one (ADR 007).
|
|
222
|
+
lines.extend(pillars_markdown(report.get("pillars"), report.get("practice")))
|
|
217
223
|
lines.extend([
|
|
218
224
|
"---", "",
|
|
219
225
|
"This is the bounded UI view. The complete report — every finding, "
|
{maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/src/maintainability_audit/report.py
RENAMED
|
@@ -22,6 +22,7 @@ from ._economics import economic_context_from, economic_impact, reorder_by_expos
|
|
|
22
22
|
from ._metrics_types import FileMetric, FunctionMetric
|
|
23
23
|
from ._pillars import pillar_report
|
|
24
24
|
from ._practice import practice_level
|
|
25
|
+
from ._security_delegate import run_security_delegate
|
|
25
26
|
from ._semantic import semantic_findings
|
|
26
27
|
from ._semantic_policy import load_semantic_policy
|
|
27
28
|
from ._semantic_ts import discover_type_analysis
|
|
@@ -399,27 +400,42 @@ def _attach_semantics(
|
|
|
399
400
|
|
|
400
401
|
def _pillars_with_delegation(
|
|
401
402
|
report: dict[str, Any], root: Path, pillar_path: str | None = None,
|
|
403
|
+
changed_revspec: str | None = None,
|
|
402
404
|
) -> list[dict[str, Any]]:
|
|
403
|
-
"""The pillar block, with
|
|
404
|
-
|
|
405
|
-
ADR 007 §1 makes Security a delegated pillar naming
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
405
|
+
"""The pillar block, with the delegated security pillar measured.
|
|
406
|
+
|
|
407
|
+
ADR 007 §1 makes Security a delegated pillar naming `secure-code-agent`.
|
|
408
|
+
Until D177 that was a handoff: the entry carried the other tool's
|
|
409
|
+
measurement only when a `security-pillar.json` had been left in the tree,
|
|
410
|
+
so every audit nobody had prepared — and every audit through the chat
|
|
411
|
+
door — reported the pillar unmeasured.
|
|
412
|
+
|
|
413
|
+
**The audit runs the delegate (D177).** An operator who names a document
|
|
414
|
+
with `--security-pillar` — CI, which runs secure-code-agent as its own
|
|
415
|
+
gated step — has that document used as given. Otherwise this audit runs
|
|
416
|
+
secure-code-agent itself. A `security-pillar.json` sitting in the tree is
|
|
417
|
+
no longer read on its own authority: it is repository content, and a
|
|
418
|
+
repository may not report its own security posture in place of a
|
|
419
|
+
measurement. When nothing trustworthy comes back, the entry says why.
|
|
413
420
|
|
|
414
421
|
Its own function because `build_report` was at eighty lines against a
|
|
415
422
|
limit of eighty, and adding this inline took it to eighty-eight —
|
|
416
423
|
caught by this tool's gate on the commit that added it.
|
|
417
424
|
"""
|
|
418
|
-
|
|
419
|
-
|
|
425
|
+
if pillar_path:
|
|
426
|
+
handed_over = read_delegated(root, pillar_path)
|
|
427
|
+
reason = None if handed_over else (
|
|
428
|
+
f"the --security-pillar document {pillar_path} was absent or could not be trusted")
|
|
429
|
+
else:
|
|
430
|
+
run = run_security_delegate(root, changed_revspec=changed_revspec)
|
|
431
|
+
handed_over, reason = run.document, run.reason
|
|
432
|
+
if run.environment:
|
|
433
|
+
report["environment_work_order"] = [
|
|
434
|
+
*(report.get("environment_work_order") or []), *run.environment]
|
|
420
435
|
return pillar_report(
|
|
421
436
|
report["score"], report["practice"],
|
|
422
437
|
{"security": handed_over} if handed_over else None,
|
|
438
|
+
{"security": reason} if reason else None,
|
|
423
439
|
)
|
|
424
440
|
|
|
425
441
|
|
|
@@ -490,7 +506,7 @@ def build_report(
|
|
|
490
506
|
report["score"] = score_report(report, analyzer["pressures"])
|
|
491
507
|
# Condition rolls up aspects; practice stays a separate axis (ADR 007).
|
|
492
508
|
report["practice"] = practice_level(root, config).as_dict()
|
|
493
|
-
report["pillars"] = _pillars_with_delegation(report, root, security_pillar)
|
|
509
|
+
report["pillars"] = _pillars_with_delegation(report, root, security_pillar, changed_revspec)
|
|
494
510
|
_attach_semantics(report, root, config, only_paths)
|
|
495
511
|
# Last, because every item's delta is a rubric recomputation and the
|
|
496
512
|
# rubric needs the scored report to recompute against.
|
|
@@ -232,11 +232,16 @@ def test_baseline_results_are_exclusive_and_self_consult_is_empty(tmp_path: Path
|
|
|
232
232
|
assert result["new_findings"] == expected
|
|
233
233
|
|
|
234
234
|
|
|
235
|
-
def
|
|
236
|
-
"""Audit L1/L4: comments cannot resurrect four writes or universal Markdown.
|
|
235
|
+
def test_mcp_boundary_docstrings_describe_the_six_artifact_payload_contract() -> None:
|
|
236
|
+
"""Audit L1/L4: comments cannot resurrect four writes or universal Markdown.
|
|
237
|
+
|
|
238
|
+
Six since D177: the security pillar's run of secure-code-agent appends
|
|
239
|
+
that tool's own trend, and the boundary docstring has to say so.
|
|
240
|
+
"""
|
|
237
241
|
server_source = Path(mcp_server.__file__).read_text(encoding="utf-8")
|
|
238
242
|
module_doc = ast.get_docstring(ast.parse(server_source)) or ""
|
|
239
|
-
assert "
|
|
243
|
+
assert "six" in module_doc.lower() and "baseline" in module_doc.lower()
|
|
244
|
+
assert "secure-code-agent" in module_doc.lower()
|
|
240
245
|
assert "exactly these four" not in server_source.lower()
|
|
241
246
|
|
|
242
247
|
finish_doc = inspect.getdoc(_mcp_audit._finish_result) or ""
|
{maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_first_run_elicitation.py
RENAMED
|
@@ -393,7 +393,7 @@ def test_server_discloses_the_local_five_artifact_write_boundary(
|
|
|
393
393
|
|
|
394
394
|
assert "local" in lowered and "stdio" in lowered
|
|
395
395
|
assert info.get("read_only") is not True
|
|
396
|
-
assert len(info["writes"]) ==
|
|
396
|
+
assert len(info["writes"]) == 6
|
|
397
397
|
assert CONFIG_FILENAME in disclosure
|
|
398
398
|
assert "user" in lowered and "config" in lowered and "state" in lowered
|
|
399
399
|
assert DEFAULT_HISTORY_PATH in disclosure
|
{maintainability_agent-3.6.3 → maintainability_agent-3.7.0}/tests/test_mcp_baseline_payload.py
RENAMED
|
@@ -273,7 +273,7 @@ def test_server_discloses_five_artifacts_and_the_history_tristate(tmp_path: Path
|
|
|
273
273
|
info = server_info((tmp_path.resolve(),))
|
|
274
274
|
disclosure = f"{SERVER_INSTRUCTIONS}\n{json.dumps(info, sort_keys=True)}".lower()
|
|
275
275
|
|
|
276
|
-
assert len(info["writes"]) ==
|
|
276
|
+
assert len(info["writes"]) == 6
|
|
277
277
|
assert "baseline" in disclosure and str(DEFAULT_BASELINE_PATH) in disclosure
|
|
278
278
|
assert "source" in " ".join(info["never_writes"]).lower()
|
|
279
279
|
assert "report" in " ".join(info["never_writes"]).lower()
|
|
@@ -467,14 +467,18 @@ def test_cli_and_mcp_reports_agree_over_the_same_history(tmp_path: Path) -> None
|
|
|
467
467
|
)
|
|
468
468
|
|
|
469
469
|
|
|
470
|
-
def
|
|
471
|
-
"""History and
|
|
470
|
+
def test_server_discloses_the_six_artifact_write_boundary(tmp_path: Path) -> None:
|
|
471
|
+
"""History, baseline and the security delegate's trend join setup state (D177).
|
|
472
|
+
|
|
473
|
+
Source and report writes stay forbidden.
|
|
474
|
+
"""
|
|
472
475
|
info = server_info((tmp_path.resolve(),))
|
|
473
476
|
writes = info["writes"]
|
|
474
477
|
disclosure = f"{SERVER_INSTRUCTIONS}\n{json.dumps(info, sort_keys=True)}".lower()
|
|
475
478
|
|
|
476
|
-
assert len(writes) ==
|
|
479
|
+
assert len(writes) == 6
|
|
477
480
|
assert any("history" in str(item).lower() for item in writes)
|
|
481
|
+
assert ".secure-code/history.jsonl" in disclosure
|
|
478
482
|
assert any("baseline" in str(item).lower() for item in writes)
|
|
479
483
|
assert DEFAULT_HISTORY_PATH in disclosure
|
|
480
484
|
assert ".maintainability/baseline.json" in disclosure
|
|
@@ -233,7 +233,7 @@ def test_real_stdio_process_initializes_and_reports_its_boundary(tmp_path: Path)
|
|
|
233
233
|
assert info["allowed_roots"] == [str(tmp_path.resolve())]
|
|
234
234
|
assert info.get("read_only") is not True
|
|
235
235
|
boundary = json.dumps(info).lower()
|
|
236
|
-
assert len(info["writes"]) ==
|
|
236
|
+
assert len(info["writes"]) == 6
|
|
237
237
|
assert "maintainability-agent.json" in boundary
|
|
238
238
|
assert "user" in boundary and "config" in boundary and "state" in boundary
|
|
239
239
|
assert ".maintainability/history.jsonl" in boundary
|