maintainability-agent 2.7.0__tar.gz → 2.8.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-2.7.0/src/maintainability_agent.egg-info → maintainability_agent-2.8.0}/PKG-INFO +4 -4
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/README.md +3 -3
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/pyproject.toml +1 -1
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0/src/maintainability_agent.egg-info}/PKG-INFO +4 -4
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_agent.egg-info/SOURCES.txt +4 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/__init__.py +1 -1
- maintainability_agent-2.8.0/src/maintainability_audit/_anchor.py +49 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_assets/standard.md +16 -4
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_cognitive.py +16 -6
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_evidence_view.py +30 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_html_view.py +11 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_masking.py +44 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ranges_cobol.py +15 -5
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ranges_swift.py +6 -1
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_semantic_ts.py +32 -16
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/config.py +1 -1
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/prompts.py +4 -3
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/renderers.py +1 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/scoring.py +5 -1
- maintainability_agent-2.8.0/tests/test_anchor_disclosure.py +176 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_direct_runner_availability_class.py +15 -7
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_platform_claim.py +70 -5
- maintainability_agent-2.8.0/tests/test_scanner_unsafe_direction.py +147 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_stage8_contract.py +15 -7
- maintainability_agent-2.8.0/tests/test_tree_chosen_spawn.py +171 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_verified_grade.py +5 -4
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/LICENSE +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/setup.cfg +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_agent.egg-info/requires.txt +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/__main__.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_adapters.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_analysis.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_arguments.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_aspects.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_attestation.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_backfill.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_bands.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_built_ins.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_calibration.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_catalog.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_charts.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_config_defaults.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_conformance.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_corroborate.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_coverage_notes.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_derive.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_discovery.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_documents.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_economics.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_economics_view.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_environment.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_finding_match.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_first_run.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_formula.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_gates.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_generic.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_grant_ledger.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_history_view.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_hotspots.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_html_report_sections.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_identity.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_jvm_adapters.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_markdown_sections.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_mcp_audit.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_mcp_gate.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_mcp_grants.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_mcp_resources.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_mcp_setup.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_metric_adapters.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_metrics_types.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_pillars.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_practice.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_pressures.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ranges_c.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ranges_core.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ranges_java.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ranges_js.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_ratchet.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_recurrence.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_run_comparison.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_runner.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_safe_write.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_scan_history.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_scan_view.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_second_source.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_selection.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_semantic.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_semantic_policy.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_semantic_view.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_setup_errors.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_setup_persist.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_skill_install.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_stored_grants.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_tdd_view.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_test_commands.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_test_execution.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_test_pairing.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_tokens.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_tool_adapters.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_trends.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_user_config.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_verdict_adapters.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_verification.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_work_order.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_work_order_view.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_work_order_weights.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_xml.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/baseline.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/cli.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/deadcode.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/declarations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/duplication.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/evidence.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/git_tools.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/history.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/idioms.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/instructions.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/mcp_server.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/metrics.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/report.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/sarif.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/similarity.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/source.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_acquisition_trust.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_adapter_docs.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_adapter_recordings.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_adapters.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_added_lines.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analysis_coverage.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analysis_execution.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_bridge.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_config_isolation.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_estimate_claims.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_pinning.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_primary_estimate.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_provenance.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_scoring_path.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_spread_range.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_analyzer_xml_bounds.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_annotations_match_behaviour.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_anticipated_refusals.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_architecture.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_artifact_write_route_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_aspect_coverage.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_asset_snapshot_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_attestation.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_audit_components.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_authorization_freshness.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_authorship_gates.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_backfill.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_band_concealment_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_band_concealment_p3.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_band_pressures.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_bands.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_body_or_signature_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_c_declarations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_calibration_corpus.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_calibration_drift.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_calibration_tooling.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_catalog_selection.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_catalog_tier_promise.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_chat_primary_docs.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_checkstyle_adapter.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_checkstyle_catalog.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_ci_history_recipe.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_claimed_languages.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_cli.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_clone_group_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_cobol_declarations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_cognitive_complexity.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_cohort_statistics.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_concealment_properties.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_config_shape.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_consent_and_grant.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_consumer_migration.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_contract_claims.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_corroborate.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_coverage_by_language.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_cpp_declarations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_csharp_declarations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_d15_composition.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_d15_goal_directed.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_dead_code.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_declaration_edge_cases.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_declaration_grading.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_declaration_ranges.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_declaration_source.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_declared_authorship.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_declared_imports.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_derivation_mix.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_determinism.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_dimension_ratchet.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_discovery.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_doc_claims.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_docs_links.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_economic_context.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_empty_output_not_clean.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_environment_work_order.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_evidence_invariants.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_evidence_normalization.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_evidence_properties.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_exclusion_dialects.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_falsifier_standard.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_file_list_cap_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_finding_identity.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_first_run_elicitation.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_first_run_prompt.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_first_run_reelicitation.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_fix_breadth_window.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_fixed_form_fortran.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_format_ask.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_fortran_declarations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_fortran_metrics.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_fortran_practice.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_git_argv.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_git_read_only.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_git_readonly_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_grant_only_user_tier.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_history.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_history_boundary.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_history_manifest.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_history_schema2.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_history_window.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_hostile_prompt.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_html_executive.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_html_section_parity_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_identity_docs.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_identity_resolution.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_idiom_divergence.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_installed_wheel_runtime.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_instruction_targets.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_java_range_guard.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_java_ranges.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_java_scored.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_java_wiring.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_js_complexity_operators.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_js_declarations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_language_coverage.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_mcp_baseline_payload.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_mcp_history.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_mcp_server.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_migration_1_0.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_near_duplicates.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_network_disclosure.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_pattern_budget.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_phase6_claims.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_pillars_and_practice.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_pmd_adapter.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_pmd_audit_closures.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_pool_runs_by_config.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_population_floors.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_practice_nested_gates_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_presentation_refusals.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_promises.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_prompt_escalation_once.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_prompt_honesty.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_prompt_location_escalation_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_prove_falsifiers.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_python_declarations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_read_boundary.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_readme_claims.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_recurrence.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_release_plan.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_release_plan_status.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_report_remedy_copy.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_roles_recorded.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_root_grants.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_run_comparison.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_runner.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_sarif.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_scan_history.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_scan_scope.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_scanning.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_schema_fidelity.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_scope_conformance.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_scoring_calibration.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_semantic_policy.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_setup_gate_completeness.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_setup_gate_independent_contract.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_setup_precondition.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_skill_install.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_source_index.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_spotbugs_adapter.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_spotbugs_catalog.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_suite_isolation.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_swift_declarations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_tdd_structure.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_test_commands.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_test_execution_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_three_presentations.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_trends.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_type_fields_not_functions_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_uat_falsifiers.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_unread_code.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_user_config_tier.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_verification_audit_closures.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_version_claim.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_wheel_contents.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_work_order.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_work_order_items.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_work_order_selection.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_workflow_supply_chain.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_write_boundary.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/tests/test_write_route_class.py +0 -0
- {maintainability_agent-2.7.0 → maintainability_agent-2.8.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: 2.
|
|
3
|
+
Version: 2.8.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -44,7 +44,7 @@ Dynamic: license-file
|
|
|
44
44
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
45
45
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
46
46
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
47
|
-
Version **2.
|
|
47
|
+
Version **2.8.0**.
|
|
48
48
|
|
|
49
49
|
**Languages parsed:** Python, Java, C, C++, C#, Swift, Fortran (free-form
|
|
50
50
|
*and* fixed-form), and the JS/TS family — each by a scanner written for it, and
|
|
@@ -383,8 +383,8 @@ Based on ISO/IEC 25010 maintainability — modularity, reusability,
|
|
|
383
383
|
analyzability, modifiability, testability. Scores are **rates calibrated
|
|
384
384
|
against real code**, not counts: every pressure is normalized against the
|
|
385
385
|
median a pinned 112-repo corpus of mature projects actually carries —
|
|
386
|
-
|
|
387
|
-
ghidra, LAPACK, …). How that corpus was selected, what each language actually
|
|
386
|
+
eight of the ten parsed languages (django, angular, spring-framework,
|
|
387
|
+
ghidra, LAPACK, …); Swift and COBOL are parsed but unanchored. How that corpus was selected, what each language actually
|
|
388
388
|
reads, and what the numbers do *not* establish:
|
|
389
389
|
[the calibration study](docs/calibration-2.0-study.md), so `2.5x` means
|
|
390
390
|
"two and a half times what well-maintained real code shows." The corpus median
|
|
@@ -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 **2.
|
|
8
|
+
Version **2.8.0**.
|
|
9
9
|
|
|
10
10
|
**Languages parsed:** Python, Java, C, C++, C#, Swift, Fortran (free-form
|
|
11
11
|
*and* fixed-form), and the JS/TS family — each by a scanner written for it, and
|
|
@@ -344,8 +344,8 @@ Based on ISO/IEC 25010 maintainability — modularity, reusability,
|
|
|
344
344
|
analyzability, modifiability, testability. Scores are **rates calibrated
|
|
345
345
|
against real code**, not counts: every pressure is normalized against the
|
|
346
346
|
median a pinned 112-repo corpus of mature projects actually carries —
|
|
347
|
-
|
|
348
|
-
ghidra, LAPACK, …). How that corpus was selected, what each language actually
|
|
347
|
+
eight of the ten parsed languages (django, angular, spring-framework,
|
|
348
|
+
ghidra, LAPACK, …); Swift and COBOL are parsed but unanchored. How that corpus was selected, what each language actually
|
|
349
349
|
reads, and what the numbers do *not* establish:
|
|
350
350
|
[the calibration study](docs/calibration-2.0-study.md), so `2.5x` means
|
|
351
351
|
"two and a half times what well-maintained real code shows." The corpus median
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "maintainability-agent"
|
|
7
|
-
version = "2.
|
|
7
|
+
version = "2.8.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
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: maintainability-agent
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.8.0
|
|
4
4
|
Summary: Maintainability gate and AI remediation prompt generator for CI.
|
|
5
5
|
Author: Marshall Guillory
|
|
6
6
|
License: MIT
|
|
@@ -44,7 +44,7 @@ Dynamic: license-file
|
|
|
44
44
|
**A deterministic, offline maintainability audit whose output is a _bounded
|
|
45
45
|
work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
|
|
46
46
|
says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
|
|
47
|
-
Version **2.
|
|
47
|
+
Version **2.8.0**.
|
|
48
48
|
|
|
49
49
|
**Languages parsed:** Python, Java, C, C++, C#, Swift, Fortran (free-form
|
|
50
50
|
*and* fixed-form), and the JS/TS family — each by a scanner written for it, and
|
|
@@ -383,8 +383,8 @@ Based on ISO/IEC 25010 maintainability — modularity, reusability,
|
|
|
383
383
|
analyzability, modifiability, testability. Scores are **rates calibrated
|
|
384
384
|
against real code**, not counts: every pressure is normalized against the
|
|
385
385
|
median a pinned 112-repo corpus of mature projects actually carries —
|
|
386
|
-
|
|
387
|
-
ghidra, LAPACK, …). How that corpus was selected, what each language actually
|
|
386
|
+
eight of the ten parsed languages (django, angular, spring-framework,
|
|
387
|
+
ghidra, LAPACK, …); Swift and COBOL are parsed but unanchored. How that corpus was selected, what each language actually
|
|
388
388
|
reads, and what the numbers do *not* establish:
|
|
389
389
|
[the calibration study](docs/calibration-2.0-study.md), so `2.5x` means
|
|
390
390
|
"two and a half times what well-maintained real code shows." The corpus median
|
|
@@ -11,6 +11,7 @@ src/maintainability_audit/__init__.py
|
|
|
11
11
|
src/maintainability_audit/__main__.py
|
|
12
12
|
src/maintainability_audit/_adapters.py
|
|
13
13
|
src/maintainability_audit/_analysis.py
|
|
14
|
+
src/maintainability_audit/_anchor.py
|
|
14
15
|
src/maintainability_audit/_arguments.py
|
|
15
16
|
src/maintainability_audit/_aspects.py
|
|
16
17
|
src/maintainability_audit/_attestation.py
|
|
@@ -143,6 +144,7 @@ tests/test_analyzer_provenance_exclusions.py
|
|
|
143
144
|
tests/test_analyzer_scoring_path.py
|
|
144
145
|
tests/test_analyzer_spread_range.py
|
|
145
146
|
tests/test_analyzer_xml_bounds.py
|
|
147
|
+
tests/test_anchor_disclosure.py
|
|
146
148
|
tests/test_annotations_match_behaviour.py
|
|
147
149
|
tests/test_anticipated_refusals.py
|
|
148
150
|
tests/test_architecture.py
|
|
@@ -283,6 +285,7 @@ tests/test_runner.py
|
|
|
283
285
|
tests/test_sarif.py
|
|
284
286
|
tests/test_scan_history.py
|
|
285
287
|
tests/test_scan_scope.py
|
|
288
|
+
tests/test_scanner_unsafe_direction.py
|
|
286
289
|
tests/test_scanning.py
|
|
287
290
|
tests/test_schema_fidelity.py
|
|
288
291
|
tests/test_scope_conformance.py
|
|
@@ -302,6 +305,7 @@ tests/test_tdd_structure.py
|
|
|
302
305
|
tests/test_test_commands.py
|
|
303
306
|
tests/test_test_execution_class.py
|
|
304
307
|
tests/test_three_presentations.py
|
|
308
|
+
tests/test_tree_chosen_spawn.py
|
|
305
309
|
tests/test_trends.py
|
|
306
310
|
tests/test_type_fields_not_functions_class.py
|
|
307
311
|
tests/test_uat_falsifiers.py
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"""What the reference corpus does not hold, and how to say it.
|
|
2
|
+
|
|
3
|
+
Rubric data, like `_calibration`: a fact about the anchor rather than a
|
|
4
|
+
computation over a repository. It lives beside the constant it qualifies
|
|
5
|
+
because the two go stale together — a recalibration that adds Swift and
|
|
6
|
+
COBOL to the corpus empties this in the same commit that moves
|
|
7
|
+
`CALIBRATION_C`.
|
|
8
|
+
|
|
9
|
+
**Unanchored is policy, not an oversight.** Under the corpus policy
|
|
10
|
+
decided with 2.4.1, a language ships parsed and the corpus is re-measured
|
|
11
|
+
once after the remaining scanners land: adding a scanner moves
|
|
12
|
+
`scanner_fingerprint` and invalidates every stored measurement, so paying
|
|
13
|
+
per language means paying in full, repeatedly, for an anchor that is
|
|
14
|
+
obsolete again at the next one.
|
|
15
|
+
|
|
16
|
+
What is *not* policy is silence about it where the grade is read. The
|
|
17
|
+
report carried `score.reference` and the note said the corpus spanned
|
|
18
|
+
"every language this scanner parses" — which was true when it was written
|
|
19
|
+
and false from 2.4.0 onward, for three releases. A Grok audit on
|
|
20
|
+
2026-09-04 named it as the second instance of a shape this project had
|
|
21
|
+
already shipped once: a limit disclosed only in JSON is disclosed nowhere
|
|
22
|
+
that matters.
|
|
23
|
+
"""
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
#: Parsed by a scanner, absent from the reference corpus.
|
|
27
|
+
#:
|
|
28
|
+
#: Stated rather than derived. `tools/calibration/corpus.json` is a
|
|
29
|
+
#: repository file and does not ship in the wheel, so a runtime read would
|
|
30
|
+
#: be unavailable exactly where a user reads a grade.
|
|
31
|
+
#: `test_anchor_disclosure` recomputes `parsed - corpus` from both sources
|
|
32
|
+
#: and fails if this stops matching, so the list cannot quietly go stale.
|
|
33
|
+
UNANCHORED_LANGUAGES: tuple[str, ...] = ("Swift", "COBOL")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def unanchored_names() -> str:
|
|
37
|
+
"""The languages, joined for a sentence. Empty when there are none."""
|
|
38
|
+
return " and ".join(UNANCHORED_LANGUAGES)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def unanchored_sentence() -> str:
|
|
42
|
+
"""One sentence naming what the anchor omits, for the corpus note."""
|
|
43
|
+
if not UNANCHORED_LANGUAGES:
|
|
44
|
+
return ""
|
|
45
|
+
return (
|
|
46
|
+
f"{unanchored_names()} are parsed but absent from it, so their "
|
|
47
|
+
"findings are as good as their parser while their grade is "
|
|
48
|
+
"provisional."
|
|
49
|
+
)
|
|
@@ -132,10 +132,22 @@ about LAPACK relative to mature OSS *web* code, and not a statement about
|
|
|
132
132
|
typical Fortran, because no typical Fortran was in the comparison set.
|
|
133
133
|
|
|
134
134
|
**2.0.0 extended the corpus rather than the caveat.** It is now 112
|
|
135
|
-
repositories spanning
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
135
|
+
repositories spanning eight languages: Python, TypeScript, JavaScript,
|
|
136
|
+
Java, C, C++, C# and Fortran. The original 40 rows are unchanged and still
|
|
137
|
+
pinned to the commits they were measured at, so what moved the constants
|
|
138
|
+
is the languages added and nothing else.
|
|
139
|
+
|
|
140
|
+
**Two parsed languages are not in it.** Swift (2.4.0) and COBOL (2.7.0)
|
|
141
|
+
shipped after that measurement and are **unanchored**: a scanner reads
|
|
142
|
+
them, and the medians their rates are compared against were measured on
|
|
143
|
+
other languages. This is the corpus policy decided with 2.4.1 — a
|
|
144
|
+
language ships parsed, and the corpus is re-measured once after the
|
|
145
|
+
remaining scanners land, because a new scanner moves
|
|
146
|
+
`scanner_fingerprint` and invalidates every stored row. The cost is
|
|
147
|
+
disclosed rather than absorbed: findings in those languages are as good
|
|
148
|
+
as their parser, their grade is provisional, and every surface that
|
|
149
|
+
prints a grade says so. This sentence read "every language this scanner
|
|
150
|
+
parses" for three releases after it stopped being true.
|
|
139
151
|
|
|
140
152
|
Three limits remain, and they are narrower than the one they replace:
|
|
141
153
|
|
{maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_cognitive.py
RENAMED
|
@@ -35,11 +35,11 @@ import re
|
|
|
35
35
|
|
|
36
36
|
from ._masking import mask_fortran_lines, mask_lines
|
|
37
37
|
|
|
38
|
-
#
|
|
39
|
-
#
|
|
40
|
-
#
|
|
41
|
-
#
|
|
42
|
-
|
|
38
|
+
# No COBOL masker is imported here, deliberately: `cobol_cognitive` takes
|
|
39
|
+
# lines that are already masked. COBOL's mask is the only file-level one —
|
|
40
|
+
# what a line means depends on which division it sits in — so re-masking
|
|
41
|
+
# the paragraph slice `detect_functions` hands over blanked it entirely
|
|
42
|
+
# and scored every COBOL paragraph 0. See `cobol_cognitive`.
|
|
43
43
|
|
|
44
44
|
# Constructs that both cost a point and deepen the nesting for whatever
|
|
45
45
|
# they contain.
|
|
@@ -207,8 +207,18 @@ def cobol_cognitive(lines: list[str]) -> int:
|
|
|
207
207
|
a call and opens nothing; `PERFORM UNTIL DONE` is a loop and does.
|
|
208
208
|
Counting every `PERFORM` as nesting would make an ordinary
|
|
209
209
|
call-per-line paragraph read as deeply nested.
|
|
210
|
+
|
|
211
|
+
**Takes lines that are already masked, and does not mask them again.**
|
|
212
|
+
Every other reader here may re-mask freely because its masker is
|
|
213
|
+
line-local; COBOL's is the only file-level one, since deciding what a
|
|
214
|
+
line means requires knowing which division it sits in. `detect_functions`
|
|
215
|
+
hands this a *slice* of the masked file, and a paragraph slice contains
|
|
216
|
+
no `PROCEDURE DIVISION` — so re-masking blanked the whole thing and
|
|
217
|
+
every COBOL paragraph in production scored exactly 0, including deeply
|
|
218
|
+
nested ones. The souvenir test passed throughout because it called this
|
|
219
|
+
with a whole file. Found by a Grok audit on 2026-09-04.
|
|
210
220
|
"""
|
|
211
|
-
masked =
|
|
221
|
+
masked = lines
|
|
212
222
|
score = 0
|
|
213
223
|
depth = 0
|
|
214
224
|
for line in masked:
|
|
@@ -339,3 +339,33 @@ def test_suite_lines(block: dict[str, Any] | None) -> list[str]:
|
|
|
339
339
|
if detail and not block.get("passed"):
|
|
340
340
|
lines.append(f"Detail: {detail}")
|
|
341
341
|
return lines
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
def unanchored_languages(score: dict[str, Any]) -> tuple[str, ...]:
|
|
345
|
+
"""Parsed languages the reference corpus does not hold, from the report.
|
|
346
|
+
|
|
347
|
+
Read off `score.reference` rather than imported from `_anchor`, so a
|
|
348
|
+
report rendered from stored JSON discloses what *that* run's anchor
|
|
349
|
+
omitted rather than what today's build omits.
|
|
350
|
+
"""
|
|
351
|
+
return tuple((score.get("reference") or {}).get("unanchored_languages") or ())
|
|
352
|
+
|
|
353
|
+
|
|
354
|
+
def unanchored_caveat(score: dict[str, Any]) -> list[str]:
|
|
355
|
+
"""The anchor's gap, in one sentence, for any skin that prints a grade.
|
|
356
|
+
|
|
357
|
+
Lives here because all three skins were about to carry their own copy
|
|
358
|
+
of the same lookup and the same sentence. `score.reference` rides on
|
|
359
|
+
the JSON report, and the JSON is not what most people read — a limit
|
|
360
|
+
disclosed only there is disclosed nowhere that matters, which is the
|
|
361
|
+
shape this project already shipped once as F1.
|
|
362
|
+
"""
|
|
363
|
+
names = unanchored_languages(score)
|
|
364
|
+
if not names:
|
|
365
|
+
return []
|
|
366
|
+
return ["", (
|
|
367
|
+
f"*{' and '.join(names)} are parsed but are not in the reference "
|
|
368
|
+
"corpus, so a grade or multiple reported for code in them is "
|
|
369
|
+
"provisional: the findings are as good as the parser, the rate "
|
|
370
|
+
"they are compared against was measured on other languages.*"
|
|
371
|
+
), ""]
|
{maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_html_view.py
RENAMED
|
@@ -89,6 +89,16 @@ def render_html(report: dict[str, Any], records: list[Any]) -> str:
|
|
|
89
89
|
return "\n".join(parts)
|
|
90
90
|
|
|
91
91
|
|
|
92
|
+
def _unanchored_html(score: dict[str, Any]) -> list[str]:
|
|
93
|
+
"""The anchor's gap, beside the letter rather than only in the JSON."""
|
|
94
|
+
names = view.unanchored_languages(score)
|
|
95
|
+
if not names:
|
|
96
|
+
return []
|
|
97
|
+
return [f"<div class='caveat'>{escape(' and '.join(names))} are parsed but "
|
|
98
|
+
"are not in the reference corpus, so a grade for code in them is "
|
|
99
|
+
"provisional.</div>"]
|
|
100
|
+
|
|
101
|
+
|
|
92
102
|
def _executive_strip(report: dict[str, Any], score: dict[str, Any],
|
|
93
103
|
records: list[Any]) -> list[str]:
|
|
94
104
|
"""The result, the gate, the finding counts, the direction. First."""
|
|
@@ -110,6 +120,7 @@ def _executive_strip(report: dict[str, Any], score: dict[str, Any],
|
|
|
110
120
|
f"Source: {escape(view.estimate_source(score))}</div>",
|
|
111
121
|
f"<div>{escape(view.status_sentence(score, report.get('analyzer_coverage') is not None))}</div>",
|
|
112
122
|
f"<div>{gate}</div>",
|
|
123
|
+
*_unanchored_html(score),
|
|
113
124
|
f"<div>{escape(_direction_sentence(records))}</div>",
|
|
114
125
|
"<table><tr><th>Severity</th><th>Findings</th></tr>",
|
|
115
126
|
*count_rows,
|
{maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/_masking.py
RENAMED
|
@@ -254,3 +254,47 @@ def mask_lines(lines: list[str]) -> list[str]:
|
|
|
254
254
|
text, in_block, in_template = _mask_line(line, in_block, in_template)
|
|
255
255
|
masked.append(text)
|
|
256
256
|
return masked
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
#: Swift's multiline literal, in both spellings: `"""` and the raw form
|
|
260
|
+
#: `#"""` … `"""#` (any number of `#`). Matched loosely on purpose — the
|
|
261
|
+
#: delimiter is what matters, not how many hashes surround it.
|
|
262
|
+
_SWIFT_MULTILINE_RE = re.compile(r'#*"""#*')
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
def mask_swift_lines(lines: list[str]) -> list[str]:
|
|
266
|
+
"""Swift, with multiline string literals blanked before anything reads it.
|
|
267
|
+
|
|
268
|
+
`mask_lines` is line-local: it blanks `"a"` on the line it appears on
|
|
269
|
+
and knows nothing about a literal that spans lines. Swift's
|
|
270
|
+
triple-quoted block therefore survived it, and every line between the
|
|
271
|
+
delimiters was read as code — so a `func` written inside a
|
|
272
|
+
documentation string came back as a declaration, with a name, a length
|
|
273
|
+
and a complexity nobody wrote.
|
|
274
|
+
|
|
275
|
+
`_ranges_java` discloses exactly this hole for Java text blocks. It is
|
|
276
|
+
disclosed there and closed here rather than copied: Swift's multiline
|
|
277
|
+
strings carry sample code far more often than Java's, and a
|
|
278
|
+
declaration invented out of documentation is the P7 failure — a number
|
|
279
|
+
a reader with the file in front of them would call absurd.
|
|
280
|
+
|
|
281
|
+
The delimiter lines keep their own text up to and after the marker, so
|
|
282
|
+
`let a = \"\"\"` still reads as an assignment. Length is preserved per
|
|
283
|
+
line, as everywhere else here, or every range after the literal would
|
|
284
|
+
shift.
|
|
285
|
+
"""
|
|
286
|
+
masked: list[str] = []
|
|
287
|
+
inside = False
|
|
288
|
+
for line in lines:
|
|
289
|
+
out = []
|
|
290
|
+
position = 0
|
|
291
|
+
for match in _SWIFT_MULTILINE_RE.finditer(line):
|
|
292
|
+
segment = line[position:match.start()]
|
|
293
|
+
out.append(" " * len(segment) if inside else segment)
|
|
294
|
+
out.append(match.group(0))
|
|
295
|
+
inside = not inside
|
|
296
|
+
position = match.end()
|
|
297
|
+
rest = line[position:]
|
|
298
|
+
out.append(" " * len(rest) if inside else rest)
|
|
299
|
+
masked.append("".join(out))
|
|
300
|
+
return mask_lines(masked)
|
|
@@ -72,11 +72,21 @@ _SECTION_RE = re.compile(r"^\s{0,3}([A-Za-z0-9][A-Za-z0-9-]*)\s+SECTION\s*\.", r
|
|
|
72
72
|
#: paragraph headers in columns 8-11 (Area A) and statements in 12-72
|
|
73
73
|
#: (Area B); after the sequence and indicator columns are stripped, Area A
|
|
74
74
|
#: is offset 0-3 and Area B begins at offset 4 — which is why the bound is
|
|
75
|
-
#: three spaces and not four.
|
|
76
|
-
#:
|
|
77
|
-
#:
|
|
78
|
-
#:
|
|
79
|
-
|
|
75
|
+
#: three spaces and not four. Written `{0,4}` first, and a masked
|
|
76
|
+
#: `DISPLAY "A".` sitting at column 12 came straight back as a declaration
|
|
77
|
+
#: named DISPLAY — one per statement in the file.
|
|
78
|
+
#:
|
|
79
|
+
#: **The period abuts the name**, and that is the load-bearing half. Area A
|
|
80
|
+
#: only separates a header from an *indented* statement; free-form COBOL
|
|
81
|
+
#: writes statements in column 1 too, and once `"A"` is blanked to spaces
|
|
82
|
+
#: `DISPLAY "A".` is a word, a gap, and a period — the exact shape of a
|
|
83
|
+
#: header. The gap is what gives it away, because a real header has
|
|
84
|
+
#: nothing between its name and its period. That rejects the whole class
|
|
85
|
+
#: of operand-bearing statements (`CALL "SUB".`, `MOVE 1 TO X.`) rather
|
|
86
|
+
#: than a list of verbs, which would need a new entry per verb forever.
|
|
87
|
+
#: `_STATEMENT_WORDS` still covers the operand-*less* ones, where no gap
|
|
88
|
+
#: exists to see.
|
|
89
|
+
_PARAGRAPH_RE = re.compile(r"^\s{0,3}([A-Za-z0-9][A-Za-z0-9-]*)\.\s*$")
|
|
80
90
|
_DIVISION_RE = re.compile(r"^\s*[A-Za-z0-9-]+\s+DIVISION\s*\.", re.I)
|
|
81
91
|
_PROCEDURE_RE = re.compile(r"^\s*PROCEDURE\s+DIVISION\b", re.I)
|
|
82
92
|
_END_PROGRAM_RE = re.compile(r"^\s*END\s+PROGRAM\b", re.I)
|
|
@@ -41,6 +41,7 @@ from __future__ import annotations
|
|
|
41
41
|
|
|
42
42
|
import re
|
|
43
43
|
|
|
44
|
+
from ._masking import mask_swift_lines
|
|
44
45
|
from ._metrics_types import DeclRange
|
|
45
46
|
from ._ranges_core import _mask_generics, scan_bounded
|
|
46
47
|
|
|
@@ -160,7 +161,11 @@ def swift_declaration_ranges(lines: list[str]) -> tuple[list[DeclRange], list[st
|
|
|
160
161
|
disabled `#if` arm still counts.
|
|
161
162
|
"""
|
|
162
163
|
ranges, masked = scan_bounded(
|
|
163
|
-
lines, _swift_declaration, descend=("class",), skip_preprocessor=True
|
|
164
|
+
lines, _swift_declaration, descend=("class",), skip_preprocessor=True,
|
|
165
|
+
# Multiline literals are blanked before anything reads a line. The
|
|
166
|
+
# default line-local mask left a `func` inside a `"""` block
|
|
167
|
+
# looking like a declaration — see `mask_swift_lines`.
|
|
168
|
+
mask=mask_swift_lines,
|
|
164
169
|
)
|
|
165
170
|
return _qualify_extension_members(ranges, masked), masked
|
|
166
171
|
|
|
@@ -66,10 +66,11 @@ def local_tsc_analysis(root: Path) -> dict[str, Any] | None:
|
|
|
66
66
|
Runs across the repository root *and* any workspace beneath it that
|
|
67
67
|
carries a `tsconfig.json` — TS monorepos keep the config in `web/` or
|
|
68
68
|
`packages/*`, not the root, and a root-only check went blind on exactly
|
|
69
|
-
the repos this is for. Uses a `tsc`
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
the repos this is for. Uses a `tsc` **this machine** already provides,
|
|
70
|
+
found on PATH. Never installs, never runs `npx --yes`, never touches
|
|
71
|
+
the network — and never the audited tree's own
|
|
72
|
+
`node_modules/.bin/tsc`, which would let the repository choose the
|
|
73
|
+
binary this process runs (Decision 9; see `_tsc_on_path`).
|
|
73
74
|
|
|
74
75
|
An absent checker, or a `tsc` that cannot run usably, leaves coverage
|
|
75
76
|
*unknown*, not clean: a config error (FAILED, exit 3+) or a findings
|
|
@@ -81,13 +82,14 @@ def local_tsc_analysis(root: Path) -> dict[str, Any] | None:
|
|
|
81
82
|
"""
|
|
82
83
|
diagnostics: list[dict[str, Any]] = []
|
|
83
84
|
ran = False
|
|
85
|
+
if not _tsc_on_path():
|
|
86
|
+
return None
|
|
84
87
|
for project in _tsconfig_project_dirs(root):
|
|
85
|
-
tsc = _resolve_tsc(root, project)
|
|
86
|
-
if tsc is None:
|
|
87
|
-
continue
|
|
88
88
|
result = run(
|
|
89
89
|
"typescript",
|
|
90
|
-
|
|
90
|
+
# A constant, resolved by PATH. Never a path built from the
|
|
91
|
+
# audited tree — see `_tsc_on_path`.
|
|
92
|
+
Invocation(argv=("tsc", "--noEmit", "--pretty", "false"),
|
|
91
93
|
findings_exit_codes=(0, 1, 2)),
|
|
92
94
|
cwd=project,
|
|
93
95
|
)
|
|
@@ -125,14 +127,28 @@ def _tsconfig_project_dirs(root: Path) -> list[Path]:
|
|
|
125
127
|
return sorted(dirs)
|
|
126
128
|
|
|
127
129
|
|
|
128
|
-
def
|
|
129
|
-
"""
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
130
|
+
def _tsc_on_path() -> bool:
|
|
131
|
+
"""Whether a `tsc` **this machine** provides is available.
|
|
132
|
+
|
|
133
|
+
PATH only, and that is the whole point. This preferred the audited
|
|
134
|
+
tree's own `node_modules/.bin/tsc` and fell back to PATH, which let
|
|
135
|
+
the repository under audit choose the binary this process executes —
|
|
136
|
+
a `tsconfig.json` and a writable `node_modules/.bin/tsc` are all a
|
|
137
|
+
hostile tree needs, and it does not even have to contain TypeScript.
|
|
138
|
+
|
|
139
|
+
SECURITY.md says the sole path by which this agent executes code from
|
|
140
|
+
the tree is the operator's opt-in test command (Decision 9). That was
|
|
141
|
+
false while this function existed, so the resolution is deleted
|
|
142
|
+
rather than guarded: there is no safe way to run a binary whose
|
|
143
|
+
identity the audited repository controls.
|
|
144
|
+
|
|
145
|
+
The cost is disclosed and small. A project whose only compiler is
|
|
146
|
+
project-local now leaves type coverage **unknown** rather than clean,
|
|
147
|
+
which is the honest fallback the evidence model already has a word
|
|
148
|
+
for — and reading an absent checker as a clean one is the
|
|
149
|
+
absence-as-a-pass this module's own docstring forbids.
|
|
150
|
+
"""
|
|
151
|
+
return locate("tsc") is not None
|
|
136
152
|
|
|
137
153
|
|
|
138
154
|
def _parse_diagnostics(stdout: str, prefix: Path) -> list[dict[str, Any]]:
|
{maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/config.py
RENAMED
|
@@ -11,7 +11,7 @@ from ._config_defaults import DEFAULT_CONFIG, DEFAULT_IDIOM_GROUPS
|
|
|
11
11
|
# still the door every caller comes through.
|
|
12
12
|
__all__ = ["DEFAULT_CONFIG", "DEFAULT_IDIOM_GROUPS", "PROJECT_URL", "VERSION"]
|
|
13
13
|
|
|
14
|
-
VERSION = "2.
|
|
14
|
+
VERSION = "2.8.0"
|
|
15
15
|
|
|
16
16
|
PROJECT_URL = "https://github.com/marshallguillory86/maintainability-agent"
|
|
17
17
|
|
{maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/prompts.py
RENAMED
|
@@ -258,13 +258,14 @@ def prompt_pressure_section(score: dict[str, Any]) -> list[str]:
|
|
|
258
258
|
if value is not None and value > 1.0),
|
|
259
259
|
key=lambda item: -item[1],
|
|
260
260
|
)
|
|
261
|
-
|
|
261
|
+
# Unanchored languages are provisional here too, elevated or not.
|
|
262
|
+
lines: list[str] = view.unanchored_caveat(score)
|
|
262
263
|
if elevated:
|
|
263
264
|
lines.extend(
|
|
264
265
|
[
|
|
265
266
|
"Where this repo is worse than typical real-world code",
|
|
266
|
-
"(1.0x = the median of a mature open-source corpus of
|
|
267
|
-
"
|
|
267
|
+
"(1.0x = the median of a mature open-source corpus of eight "
|
|
268
|
+
"of the ten parsed languages; elevated dimensions only):",
|
|
268
269
|
"",
|
|
269
270
|
]
|
|
270
271
|
)
|
{maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/renderers.py
RENAMED
|
@@ -63,6 +63,7 @@ def summary_table(summary: dict[str, int], score: dict[str, Any],
|
|
|
63
63
|
f"| Duplicate blocks | {summary['duplicate_blocks']} |",
|
|
64
64
|
f"| Risk findings | {summary['risk_findings']} |",
|
|
65
65
|
f"| Hard gate failures | {summary['hard_gate_failures']} |",
|
|
66
|
+
*view.unanchored_caveat(score),
|
|
66
67
|
]
|
|
67
68
|
|
|
68
69
|
|
{maintainability_agent-2.7.0 → maintainability_agent-2.8.0}/src/maintainability_audit/scoring.py
RENAMED
|
@@ -37,6 +37,7 @@ from __future__ import annotations
|
|
|
37
37
|
from math import inf
|
|
38
38
|
from typing import Any
|
|
39
39
|
|
|
40
|
+
from ._anchor import UNANCHORED_LANGUAGES, unanchored_sentence
|
|
40
41
|
from ._aspects import (
|
|
41
42
|
aspect_scores,
|
|
42
43
|
evidence_aspect_scores,
|
|
@@ -415,9 +416,12 @@ def _reference_block() -> dict[str, object]:
|
|
|
415
416
|
"corpus_languages": [
|
|
416
417
|
"Python", "TypeScript", "JavaScript", "Java", "C", "C++", "C#", "Fortran",
|
|
417
418
|
],
|
|
419
|
+
# Parsed by a scanner, absent from the anchor — see `_anchor`.
|
|
420
|
+
"unanchored_languages": UNANCHORED_LANGUAGES,
|
|
418
421
|
"corpus_note": (
|
|
419
422
|
"Reference medians are drawn from 112 mature repositories across "
|
|
420
|
-
"
|
|
423
|
+
"eight of the ten languages this scanner parses. "
|
|
424
|
+
f"{unanchored_sentence()} Fortran entered at a lower "
|
|
421
425
|
"star threshold than the rest, because its ecosystem has none "
|
|
422
426
|
"above theirs; see docs/standard.md#the-reference-corpus."
|
|
423
427
|
),
|