maintainability-agent 2.6.0__tar.gz → 2.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.
Files changed (322) hide show
  1. {maintainability_agent-2.6.0/src/maintainability_agent.egg-info → maintainability_agent-2.7.0}/PKG-INFO +44 -44
  2. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/README.md +43 -43
  3. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/pyproject.toml +1 -1
  4. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0/src/maintainability_agent.egg-info}/PKG-INFO +44 -44
  5. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/SOURCES.txt +2 -0
  6. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/__init__.py +1 -1
  7. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_cognitive.py +57 -0
  8. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_config_defaults.py +1 -0
  9. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_discovery.py +1 -1
  10. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_metrics_types.py +35 -0
  11. maintainability_agent-2.7.0/src/maintainability_audit/_ranges_cobol.py +274 -0
  12. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/config.py +1 -1
  13. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/declarations.py +13 -1
  14. maintainability_agent-2.7.0/tests/test_cobol_declarations.py +385 -0
  15. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_language_coverage.py +52 -2
  16. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/LICENSE +0 -0
  17. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/setup.cfg +0 -0
  18. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
  19. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
  20. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/requires.txt +0 -0
  21. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
  22. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/__main__.py +0 -0
  23. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_adapters.py +0 -0
  24. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_analysis.py +0 -0
  25. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_arguments.py +0 -0
  26. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_aspects.py +0 -0
  27. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
  28. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_assets/standard.md +0 -0
  29. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_attestation.py +0 -0
  30. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_backfill.py +0 -0
  31. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_bands.py +0 -0
  32. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_built_ins.py +0 -0
  33. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_calibration.py +0 -0
  34. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_catalog.py +0 -0
  35. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_charts.py +0 -0
  36. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_conformance.py +0 -0
  37. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_corroborate.py +0 -0
  38. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_coverage_notes.py +0 -0
  39. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_derive.py +0 -0
  40. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_documents.py +0 -0
  41. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_economics.py +0 -0
  42. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_economics_view.py +0 -0
  43. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_environment.py +0 -0
  44. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_evidence_view.py +0 -0
  45. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_finding_match.py +0 -0
  46. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_first_run.py +0 -0
  47. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_formula.py +0 -0
  48. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_gates.py +0 -0
  49. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_generic.py +0 -0
  50. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_grant_ledger.py +0 -0
  51. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_history_view.py +0 -0
  52. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
  53. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_hotspots.py +0 -0
  54. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_html_report_sections.py +0 -0
  55. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_html_view.py +0 -0
  56. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_identity.py +0 -0
  57. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_jvm_adapters.py +0 -0
  58. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_markdown_sections.py +0 -0
  59. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_masking.py +0 -0
  60. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_audit.py +0 -0
  61. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_gate.py +0 -0
  62. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_grants.py +0 -0
  63. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
  64. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_resources.py +0 -0
  65. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_mcp_setup.py +0 -0
  66. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_metric_adapters.py +0 -0
  67. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_pillars.py +0 -0
  68. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_practice.py +0 -0
  69. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_pressures.py +0 -0
  70. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_c.py +0 -0
  71. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_core.py +0 -0
  72. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
  73. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
  74. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
  75. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_java.py +0 -0
  76. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_js.py +0 -0
  77. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ranges_swift.py +0 -0
  78. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_ratchet.py +0 -0
  79. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_recurrence.py +0 -0
  80. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_run_comparison.py +0 -0
  81. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_runner.py +0 -0
  82. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_safe_write.py +0 -0
  83. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_scan_history.py +0 -0
  84. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_scan_view.py +0 -0
  85. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_second_source.py +0 -0
  86. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_selection.py +0 -0
  87. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_semantic.py +0 -0
  88. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_semantic_policy.py +0 -0
  89. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_semantic_ts.py +0 -0
  90. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_semantic_view.py +0 -0
  91. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_setup_errors.py +0 -0
  92. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_setup_persist.py +0 -0
  93. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
  94. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
  95. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
  96. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
  97. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
  98. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
  99. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_skill_install.py +0 -0
  100. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_stored_grants.py +0 -0
  101. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_tdd_view.py +0 -0
  102. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_test_commands.py +0 -0
  103. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_test_execution.py +0 -0
  104. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_test_pairing.py +0 -0
  105. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_tokens.py +0 -0
  106. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_tool_adapters.py +0 -0
  107. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_trends.py +0 -0
  108. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_user_config.py +0 -0
  109. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_verdict_adapters.py +0 -0
  110. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_verification.py +0 -0
  111. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_work_order.py +0 -0
  112. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_work_order_view.py +0 -0
  113. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_work_order_weights.py +0 -0
  114. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/_xml.py +0 -0
  115. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/baseline.py +0 -0
  116. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/cli.py +0 -0
  117. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/deadcode.py +0 -0
  118. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/duplication.py +0 -0
  119. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/evidence.py +0 -0
  120. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/git_tools.py +0 -0
  121. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/history.py +0 -0
  122. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/idioms.py +0 -0
  123. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/instructions.py +0 -0
  124. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/mcp_server.py +0 -0
  125. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/metrics.py +0 -0
  126. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/prompts.py +0 -0
  127. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/renderers.py +0 -0
  128. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/report.py +0 -0
  129. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/sarif.py +0 -0
  130. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/scoring.py +0 -0
  131. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/similarity.py +0 -0
  132. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/src/maintainability_audit/source.py +0 -0
  133. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_acquisition_trust.py +0 -0
  134. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_adapter_docs.py +0 -0
  135. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_adapter_recordings.py +0 -0
  136. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_adapters.py +0 -0
  137. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_added_lines.py +0 -0
  138. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analysis_coverage.py +0 -0
  139. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analysis_execution.py +0 -0
  140. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_bridge.py +0 -0
  141. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_config_isolation.py +0 -0
  142. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_estimate_claims.py +0 -0
  143. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_pinning.py +0 -0
  144. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_primary_estimate.py +0 -0
  145. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_provenance.py +0 -0
  146. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
  147. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_scoring_path.py +0 -0
  148. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_spread_range.py +0 -0
  149. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_analyzer_xml_bounds.py +0 -0
  150. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_annotations_match_behaviour.py +0 -0
  151. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_anticipated_refusals.py +0 -0
  152. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_architecture.py +0 -0
  153. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_artifact_write_route_class.py +0 -0
  154. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_aspect_coverage.py +0 -0
  155. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_asset_snapshot_class.py +0 -0
  156. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
  157. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_attestation.py +0 -0
  158. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_audit_components.py +0 -0
  159. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_authorization_freshness.py +0 -0
  160. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_authorship_gates.py +0 -0
  161. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_backfill.py +0 -0
  162. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_band_concealment_class.py +0 -0
  163. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_band_concealment_p3.py +0 -0
  164. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_band_pressures.py +0 -0
  165. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_bands.py +0 -0
  166. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_body_or_signature_class.py +0 -0
  167. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_c_declarations.py +0 -0
  168. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_calibration_corpus.py +0 -0
  169. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_calibration_drift.py +0 -0
  170. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_calibration_tooling.py +0 -0
  171. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_catalog_selection.py +0 -0
  172. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_catalog_tier_promise.py +0 -0
  173. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_chat_primary_docs.py +0 -0
  174. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_checkstyle_adapter.py +0 -0
  175. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_checkstyle_catalog.py +0 -0
  176. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_ci_history_recipe.py +0 -0
  177. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
  178. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_claimed_languages.py +0 -0
  179. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_cli.py +0 -0
  180. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_clone_group_class.py +0 -0
  181. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_cognitive_complexity.py +0 -0
  182. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_cohort_statistics.py +0 -0
  183. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_concealment_properties.py +0 -0
  184. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_config_shape.py +0 -0
  185. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_consent_and_grant.py +0 -0
  186. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_consumer_migration.py +0 -0
  187. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_contract_claims.py +0 -0
  188. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_corroborate.py +0 -0
  189. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_coverage_by_language.py +0 -0
  190. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_cpp_declarations.py +0 -0
  191. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_csharp_declarations.py +0 -0
  192. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_d15_composition.py +0 -0
  193. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_d15_goal_directed.py +0 -0
  194. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_dead_code.py +0 -0
  195. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declaration_edge_cases.py +0 -0
  196. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declaration_grading.py +0 -0
  197. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declaration_ranges.py +0 -0
  198. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declaration_source.py +0 -0
  199. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declared_authorship.py +0 -0
  200. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_declared_imports.py +0 -0
  201. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_derivation_mix.py +0 -0
  202. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_determinism.py +0 -0
  203. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_dimension_ratchet.py +0 -0
  204. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_direct_runner_availability_class.py +0 -0
  205. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_discovery.py +0 -0
  206. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_doc_claims.py +0 -0
  207. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_docs_links.py +0 -0
  208. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_economic_context.py +0 -0
  209. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_empty_output_not_clean.py +0 -0
  210. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
  211. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_environment_work_order.py +0 -0
  212. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_evidence_invariants.py +0 -0
  213. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_evidence_normalization.py +0 -0
  214. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_evidence_properties.py +0 -0
  215. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_exclusion_dialects.py +0 -0
  216. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_falsifier_standard.py +0 -0
  217. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_file_list_cap_class.py +0 -0
  218. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_finding_identity.py +0 -0
  219. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_first_run_elicitation.py +0 -0
  220. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_first_run_prompt.py +0 -0
  221. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_first_run_reelicitation.py +0 -0
  222. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fix_breadth_window.py +0 -0
  223. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fixed_form_fortran.py +0 -0
  224. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_format_ask.py +0 -0
  225. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fortran_declarations.py +0 -0
  226. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fortran_metrics.py +0 -0
  227. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_fortran_practice.py +0 -0
  228. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_git_argv.py +0 -0
  229. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_git_read_only.py +0 -0
  230. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_git_readonly_class.py +0 -0
  231. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_grant_only_user_tier.py +0 -0
  232. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history.py +0 -0
  233. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history_boundary.py +0 -0
  234. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history_manifest.py +0 -0
  235. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history_schema2.py +0 -0
  236. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_history_window.py +0 -0
  237. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_hostile_prompt.py +0 -0
  238. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_html_executive.py +0 -0
  239. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_html_section_parity_class.py +0 -0
  240. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_identity_docs.py +0 -0
  241. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_identity_resolution.py +0 -0
  242. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_idiom_divergence.py +0 -0
  243. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_installed_wheel_runtime.py +0 -0
  244. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_instruction_targets.py +0 -0
  245. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_java_range_guard.py +0 -0
  246. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_java_ranges.py +0 -0
  247. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_java_scored.py +0 -0
  248. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_java_wiring.py +0 -0
  249. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_js_complexity_operators.py +0 -0
  250. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_js_declarations.py +0 -0
  251. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_mcp_baseline_payload.py +0 -0
  252. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_mcp_history.py +0 -0
  253. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_mcp_server.py +0 -0
  254. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_migration_1_0.py +0 -0
  255. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_near_duplicates.py +0 -0
  256. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_network_disclosure.py +0 -0
  257. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
  258. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pattern_budget.py +0 -0
  259. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_phase6_claims.py +0 -0
  260. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pillars_and_practice.py +0 -0
  261. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_platform_claim.py +0 -0
  262. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pmd_adapter.py +0 -0
  263. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pmd_audit_closures.py +0 -0
  264. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_pool_runs_by_config.py +0 -0
  265. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_population_floors.py +0 -0
  266. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_practice_nested_gates_class.py +0 -0
  267. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_presentation_refusals.py +0 -0
  268. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_promises.py +0 -0
  269. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_prompt_escalation_once.py +0 -0
  270. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_prompt_honesty.py +0 -0
  271. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_prompt_location_escalation_class.py +0 -0
  272. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_prove_falsifiers.py +0 -0
  273. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_python_declarations.py +0 -0
  274. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_read_boundary.py +0 -0
  275. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_readme_claims.py +0 -0
  276. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_recurrence.py +0 -0
  277. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_release_plan.py +0 -0
  278. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_release_plan_status.py +0 -0
  279. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_report_remedy_copy.py +0 -0
  280. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_roles_recorded.py +0 -0
  281. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_root_grants.py +0 -0
  282. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
  283. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_run_comparison.py +0 -0
  284. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_runner.py +0 -0
  285. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_sarif.py +0 -0
  286. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scan_history.py +0 -0
  287. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scan_scope.py +0 -0
  288. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scanning.py +0 -0
  289. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_schema_fidelity.py +0 -0
  290. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scope_conformance.py +0 -0
  291. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_scoring_calibration.py +0 -0
  292. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_semantic_policy.py +0 -0
  293. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_setup_gate_completeness.py +0 -0
  294. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_setup_gate_independent_contract.py +0 -0
  295. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_setup_precondition.py +0 -0
  296. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_skill_install.py +0 -0
  297. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_source_index.py +0 -0
  298. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_spotbugs_adapter.py +0 -0
  299. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_spotbugs_catalog.py +0 -0
  300. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_stage8_contract.py +0 -0
  301. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_suite_isolation.py +0 -0
  302. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_swift_declarations.py +0 -0
  303. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_tdd_structure.py +0 -0
  304. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_test_commands.py +0 -0
  305. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_test_execution_class.py +0 -0
  306. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_three_presentations.py +0 -0
  307. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_trends.py +0 -0
  308. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_type_fields_not_functions_class.py +0 -0
  309. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_uat_falsifiers.py +0 -0
  310. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_unread_code.py +0 -0
  311. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_user_config_tier.py +0 -0
  312. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_verification_audit_closures.py +0 -0
  313. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_verified_grade.py +0 -0
  314. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_version_claim.py +0 -0
  315. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_wheel_contents.py +0 -0
  316. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_work_order.py +0 -0
  317. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_work_order_items.py +0 -0
  318. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_work_order_selection.py +0 -0
  319. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_workflow_supply_chain.py +0 -0
  320. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_write_boundary.py +0 -0
  321. {maintainability_agent-2.6.0 → maintainability_agent-2.7.0}/tests/test_write_route_class.py +0 -0
  322. {maintainability_agent-2.6.0 → maintainability_agent-2.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: 2.6.0
3
+ Version: 2.7.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.6.0**.
47
+ Version **2.7.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
@@ -78,9 +78,11 @@ What 1.0 guarantees:
78
78
  - **Deterministic and local.** Same tree, config, pinned analyzer versions and
79
79
  history in → same evidence, findings and score out. The analysis performs no
80
80
  network access and invokes no LLM, and **this agent does not transmit your
81
- source.** Third-party analyzers it may spawn (eslint, jscpd, lizard) are
82
- **not network-sandboxed** — this process does not police whether *they* phone
83
- home; install them yourself for an air-gapped run.
81
+ source.** Every report states what it examined and produced — files,
82
+ declarations, findings, bounded work items — **all computed with no model
83
+ call**: work a metered agent never has to do. Third-party analyzers it may
84
+ spawn (eslint, jscpd, lizard) are **not network-sandboxed** — this process does
85
+ not police whether *they* phone home; install them for an air-gapped run.
84
86
  - **One uniform rubric**, readable in source, applied to every repository —
85
87
  so "better" and "worse" are not an argument. Calibrated against a
86
88
  query-selected corpus of mature open-source projects; the corpus median
@@ -183,9 +185,8 @@ policy, history consent, economics, test-suite execution, and presentation, and
183
185
  no report. A configured repository returns `choice_needed` (`run` or
184
186
  `reconfigure`), also without a report. Answering setup does not start an audit.
185
187
  `action="run"` returns the report and its bounded remediation prompt to the
186
- conversation. `record_history=None` follows the persisted first-run history
187
- consent and always appends to an existing history, while an explicit `true`
188
- or `false` wins.
188
+ conversation. `record_history=None` follows the persisted first-run consent and
189
+ always appends to an existing history; an explicit `true` or `false` wins.
189
190
 
190
191
  ```bash
191
192
  python3 -m pip install "maintainability-agent[mcp]"
@@ -193,10 +194,10 @@ maintainability-agent mcp --allow-root /absolute/path/to/repository
193
194
  ```
194
195
 
195
196
  Presentation is exactly three choices — **chat**, a **Markdown** file, or a
196
- single-file **HTML** report — and where to save a file is asked only after a
197
- file format is chosen. No report file is written without that choice. See
198
- [chat workflow help](docs/help/README.md) and
199
- [IDE and agent integration](docs/ide-agent-integration.md).
197
+ single-file **HTML** report. Where to save is asked only after a file format is
198
+ chosen, and no report file is written without that choice. See
199
+ [chat workflow help](docs/help/README.md) and [IDE and agent
200
+ integration](docs/ide-agent-integration.md).
200
201
 
201
202
  ## Automation / CI: CLI
202
203
 
@@ -290,14 +291,13 @@ SonarQube, Qlty) rather than replacing them — their SARIF folds in via
290
291
 
291
292
  ## Language support
292
293
 
293
- **Be clear-eyed about this: the tool does not support every language equally,
294
- and on an unrecognized language it will quietly under-report rather than fail.**
295
- Coverage comes from two layers.
294
+ **Be clear-eyed: the tool does not support every language equally, and on an
295
+ unrecognized language it under-reports rather than fails.** Coverage has two layers.
296
296
 
297
- Nine languages are parsed as of **2.4.0**: Python (1.0), Java (1.0), C (1.1),
298
- C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4), the
299
- JS/TS family, and HTML. Each has a scanner written for it and a documented list of what it
300
- misses — a language is claimed here only when both exist.
297
+ Ten languages are parsed as of **2.7.0**: Python (1.0), Java (1.0), C (1.1),
298
+ C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
299
+ COBOL (2.7), the JS/TS family, and HTML. Each has a scanner written for it and a
300
+ documented list of what it misses — a language is claimed only when both exist.
301
301
 
302
302
  **Built-in scanner (always on, no dependencies)** — reads function/class
303
303
  declarations, sizes and complexity for a fixed set of languages, and **only**
@@ -311,18 +311,19 @@ these:
311
311
  | C++ (`.cpp`, `.hpp`, `.cc`, `.cxx`, `.hh`) | dedicated brace-bounded scanner — functions, class members, namespaces, templates | Bounded; bodyless declarations are not definitions |
312
312
  | C# (`.cs`) | dedicated brace-bounded scanner — methods, constructors, `class`/`interface`/`struct`/`record`/`enum` | Bounded; properties are not declarations |
313
313
  | Swift (`.swift`) | dedicated brace-bounded scanner — functions, initialisers, subscripts, `class`/`struct`/`enum`/`protocol`/`actor` | Bounded; extension members carry their type, protocol requirements and computed properties are not declarations |
314
+ | COBOL (`.cbl`, `.cob`, `.cpy`, and `.CBL`/`.COB`/`.CPY`) | dedicated scanner — PROCEDURE DIVISION paragraphs, bounded by the start of whatever follows; fixed-form card columns read where the layout carries them | Bounded by the next header; level numbers and container programs/sections are not declarations |
314
315
  | Fortran, free-form (`.f90`, `.f95`, `.f03`, `.f08`, `.F90`, `.F95`, `.F03`, `.F08`, `.pf`) | dedicated **keyword**-bounded scanner — modules, subroutines, functions, derived types | Bounded by `end`; measured with Fortran's own branch and nesting reading |
315
316
  | Fortran, fixed-form (`.f`, `.for`, `.ftn`, `.F`, `.FOR`, `.FTN`) | the same scanner over card-column source; continuations joined, labelled `DO` loops understood | Bounded by `end` or by the loop's label |
316
317
  | JS / TS / JSX / TSX (`.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`) | brace/paren depth over a masked copy | Bounded by the declaration's own braces |
317
318
  | HTML (`.html`) | same brace scanner (inline `<script>`) | Bounded |
318
319
  | TypeScript (semantic) | a recorded analysis or a locally-installed `tsc`, workspace projects included | Type-level facts; `unknown` when no checker is present |
319
320
 
320
- Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin,
321
- Swift, and the rest — is **not parsed for declarations by the built-in
322
- scanner.** Its files still count toward repo size, but the built-ins produce no
323
- function-size, complexity, duplication or dead-code findings for them, and the
324
- estimate leans on whatever evidence *is* available (which is why the report
325
- discloses its evidence tier and can withhold the grade).
321
+ Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin, and the rest —
322
+ is **not parsed for declarations by the built-in scanner.** Its files still count
323
+ toward repo size, but the built-ins produce no function-size, complexity,
324
+ duplication or dead-code findings for them, and the estimate leans on whatever
325
+ evidence *is* available (which is why the report discloses its evidence tier and
326
+ can withhold the grade).
326
327
 
327
328
  **Which analyzer covers which language** (the opt-in pool, when installed):
328
329
 
@@ -332,13 +333,14 @@ discloses its evidence tier and can withhold the grade).
332
333
  | Java | dedicated scanner | lizard, PMD, Checkstyle, SpotBugs |
333
334
  | C / C++ / C# | dedicated scanners | lizard, multimetric |
334
335
  | **Fortran** (free- and fixed-form) | dedicated scanner | **fortitude** — 100+ rules; **lizard** — complexity, NLOC, params |
336
+ | **COBOL** | dedicated scanner | **none** — no offline analyzer in the catalog reads it |
335
337
  | JS / TS / JSX / TSX | brace scanner | ESLint, lizard, jscpd |
336
338
 
337
- Fortran reached parity in 1.6.0. lizard measures it — this project's
338
- catalog row for lizard was stale and said otherwise, so lizard came out
339
- `not-applicable` on every Fortran repository and never ran — and
340
- fortitude adds 100+ lint rules beside it. A lint now fails the build if
341
- any parsed language has no analyzer that measures complexity.
339
+ Fortran reached parity in 1.6.0: lizard had read it for years behind a
340
+ stale catalog row, so it came out `not-applicable` and never ran. A lint fails
341
+ the build if a parsed language has no analyzer measuring complexity — **COBOL is
342
+ the one disclosed exemption**, because the tooling that reads it is licensed and
343
+ host-resident, so its external tier is empty and the report says so.
342
344
 
343
345
  **External analyzer adapters (opt-in pool)** — this is how coverage extends
344
346
  beyond the built-in set. When you enable the analyzer pool, the tool shells out
@@ -350,12 +352,11 @@ selected *and* installed (acquisition is opt-in and off by default), and where
350
352
  they measured a full concept set they become the *primary* evidence, with the
351
353
  built-ins as the fallback.
352
354
 
353
- So: **first-class today is Python** (and TypeScript for semantics); Java, C, C++,
354
- C#, free-form Fortran and the JS/TS family are bounded-but-real; every other language is only as covered as
355
- the external analyzer you point at it — and with no analyzer, it is
356
- under-reported by design. The per-language accuracy, the exact parsed set, and
357
- the known limitations are documented in
358
- [docs/language-support.md](docs/language-support.md); the adapter catalog is in
355
+ So: **first-class today is Python** (and TypeScript for semantics); every other
356
+ parsed language is bounded-but-real; anything outside the table is only as
357
+ covered as the analyzer you point at it, and with none it is under-reported by
358
+ design. Per-language accuracy and limits:
359
+ [docs/language-support.md](docs/language-support.md); the adapter catalog:
359
360
  [docs/adapters.md](docs/adapters.md).
360
361
 
361
362
  ## What it produces
@@ -423,10 +424,9 @@ defaults. The grade is gated (A+ needs every dimension clean; a
423
424
  repo with production code and zero test files cannot earn an A-grade) and banded
424
425
  from the evidence floor, so withholding evidence never buys a better letter.
425
426
  Every threshold gate — file, function, duplication — is opted **on** for this
426
- repo's own CI, against thresholds stricter than the shipped defaults, so
427
- drifting below the bar fails the build rather than the README. (CI note:
428
- `actions/checkout` defaults to `fetch-depth: 1`, which hides history and costs
429
- roughly a grade — use `fetch-depth: 0`.)
427
+ repo's own CI, so drifting below the bar fails the build rather than the README.
428
+ (CI note: `actions/checkout` defaults to `fetch-depth: 1`, which hides history
429
+ and costs roughly a grade — use `fetch-depth: 0`.)
430
430
 
431
431
  ## Platform support
432
432
 
@@ -517,14 +517,14 @@ gate, and the self-audit — is in
517
517
 
518
518
  ## Support this work
519
519
 
520
- This is a single-maintainer, MIT-licensed project — free to use, and built on
521
- a lot of unpaid hours. If it saves you or your team time, please consider
520
+ This is a single-maintainer, MIT-licensed project — free to use, and built on a
521
+ lot of unpaid hours. If it saves you or your team time, please consider
522
522
  sponsoring its continued development:
523
523
 
524
524
  **❤️ [Sponsor on GitHub](https://github.com/sponsors/marshallguillory86)**
525
525
 
526
- Sponsorship is entirely optional and never gates a feature, a fix, or support —
527
- the whole tool stays free and open. It just helps keep the work going.
526
+ Sponsorship is optional and never gates a feature, a fix, or support — the whole
527
+ tool stays free and open. It just helps keep the work going.
528
528
 
529
529
  ## Acknowledgements
530
530
 
@@ -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.6.0**.
8
+ Version **2.7.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
@@ -39,9 +39,11 @@ What 1.0 guarantees:
39
39
  - **Deterministic and local.** Same tree, config, pinned analyzer versions and
40
40
  history in → same evidence, findings and score out. The analysis performs no
41
41
  network access and invokes no LLM, and **this agent does not transmit your
42
- source.** Third-party analyzers it may spawn (eslint, jscpd, lizard) are
43
- **not network-sandboxed** — this process does not police whether *they* phone
44
- home; install them yourself for an air-gapped run.
42
+ source.** Every report states what it examined and produced — files,
43
+ declarations, findings, bounded work items — **all computed with no model
44
+ call**: work a metered agent never has to do. Third-party analyzers it may
45
+ spawn (eslint, jscpd, lizard) are **not network-sandboxed** — this process does
46
+ not police whether *they* phone home; install them for an air-gapped run.
45
47
  - **One uniform rubric**, readable in source, applied to every repository —
46
48
  so "better" and "worse" are not an argument. Calibrated against a
47
49
  query-selected corpus of mature open-source projects; the corpus median
@@ -144,9 +146,8 @@ policy, history consent, economics, test-suite execution, and presentation, and
144
146
  no report. A configured repository returns `choice_needed` (`run` or
145
147
  `reconfigure`), also without a report. Answering setup does not start an audit.
146
148
  `action="run"` returns the report and its bounded remediation prompt to the
147
- conversation. `record_history=None` follows the persisted first-run history
148
- consent and always appends to an existing history, while an explicit `true`
149
- or `false` wins.
149
+ conversation. `record_history=None` follows the persisted first-run consent and
150
+ always appends to an existing history; an explicit `true` or `false` wins.
150
151
 
151
152
  ```bash
152
153
  python3 -m pip install "maintainability-agent[mcp]"
@@ -154,10 +155,10 @@ maintainability-agent mcp --allow-root /absolute/path/to/repository
154
155
  ```
155
156
 
156
157
  Presentation is exactly three choices — **chat**, a **Markdown** file, or a
157
- single-file **HTML** report — and where to save a file is asked only after a
158
- file format is chosen. No report file is written without that choice. See
159
- [chat workflow help](docs/help/README.md) and
160
- [IDE and agent integration](docs/ide-agent-integration.md).
158
+ single-file **HTML** report. Where to save is asked only after a file format is
159
+ chosen, and no report file is written without that choice. See
160
+ [chat workflow help](docs/help/README.md) and [IDE and agent
161
+ integration](docs/ide-agent-integration.md).
161
162
 
162
163
  ## Automation / CI: CLI
163
164
 
@@ -251,14 +252,13 @@ SonarQube, Qlty) rather than replacing them — their SARIF folds in via
251
252
 
252
253
  ## Language support
253
254
 
254
- **Be clear-eyed about this: the tool does not support every language equally,
255
- and on an unrecognized language it will quietly under-report rather than fail.**
256
- Coverage comes from two layers.
255
+ **Be clear-eyed: the tool does not support every language equally, and on an
256
+ unrecognized language it under-reports rather than fails.** Coverage has two layers.
257
257
 
258
- Nine languages are parsed as of **2.4.0**: Python (1.0), Java (1.0), C (1.1),
259
- C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4), the
260
- JS/TS family, and HTML. Each has a scanner written for it and a documented list of what it
261
- misses — a language is claimed here only when both exist.
258
+ Ten languages are parsed as of **2.7.0**: Python (1.0), Java (1.0), C (1.1),
259
+ C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
260
+ COBOL (2.7), the JS/TS family, and HTML. Each has a scanner written for it and a
261
+ documented list of what it misses — a language is claimed only when both exist.
262
262
 
263
263
  **Built-in scanner (always on, no dependencies)** — reads function/class
264
264
  declarations, sizes and complexity for a fixed set of languages, and **only**
@@ -272,18 +272,19 @@ these:
272
272
  | C++ (`.cpp`, `.hpp`, `.cc`, `.cxx`, `.hh`) | dedicated brace-bounded scanner — functions, class members, namespaces, templates | Bounded; bodyless declarations are not definitions |
273
273
  | C# (`.cs`) | dedicated brace-bounded scanner — methods, constructors, `class`/`interface`/`struct`/`record`/`enum` | Bounded; properties are not declarations |
274
274
  | Swift (`.swift`) | dedicated brace-bounded scanner — functions, initialisers, subscripts, `class`/`struct`/`enum`/`protocol`/`actor` | Bounded; extension members carry their type, protocol requirements and computed properties are not declarations |
275
+ | COBOL (`.cbl`, `.cob`, `.cpy`, and `.CBL`/`.COB`/`.CPY`) | dedicated scanner — PROCEDURE DIVISION paragraphs, bounded by the start of whatever follows; fixed-form card columns read where the layout carries them | Bounded by the next header; level numbers and container programs/sections are not declarations |
275
276
  | Fortran, free-form (`.f90`, `.f95`, `.f03`, `.f08`, `.F90`, `.F95`, `.F03`, `.F08`, `.pf`) | dedicated **keyword**-bounded scanner — modules, subroutines, functions, derived types | Bounded by `end`; measured with Fortran's own branch and nesting reading |
276
277
  | Fortran, fixed-form (`.f`, `.for`, `.ftn`, `.F`, `.FOR`, `.FTN`) | the same scanner over card-column source; continuations joined, labelled `DO` loops understood | Bounded by `end` or by the loop's label |
277
278
  | JS / TS / JSX / TSX (`.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`) | brace/paren depth over a masked copy | Bounded by the declaration's own braces |
278
279
  | HTML (`.html`) | same brace scanner (inline `<script>`) | Bounded |
279
280
  | TypeScript (semantic) | a recorded analysis or a locally-installed `tsc`, workspace projects included | Type-level facts; `unknown` when no checker is present |
280
281
 
281
- Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin,
282
- Swift, and the rest — is **not parsed for declarations by the built-in
283
- scanner.** Its files still count toward repo size, but the built-ins produce no
284
- function-size, complexity, duplication or dead-code findings for them, and the
285
- estimate leans on whatever evidence *is* available (which is why the report
286
- discloses its evidence tier and can withhold the grade).
282
+ Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin, and the rest —
283
+ is **not parsed for declarations by the built-in scanner.** Its files still count
284
+ toward repo size, but the built-ins produce no function-size, complexity,
285
+ duplication or dead-code findings for them, and the estimate leans on whatever
286
+ evidence *is* available (which is why the report discloses its evidence tier and
287
+ can withhold the grade).
287
288
 
288
289
  **Which analyzer covers which language** (the opt-in pool, when installed):
289
290
 
@@ -293,13 +294,14 @@ discloses its evidence tier and can withhold the grade).
293
294
  | Java | dedicated scanner | lizard, PMD, Checkstyle, SpotBugs |
294
295
  | C / C++ / C# | dedicated scanners | lizard, multimetric |
295
296
  | **Fortran** (free- and fixed-form) | dedicated scanner | **fortitude** — 100+ rules; **lizard** — complexity, NLOC, params |
297
+ | **COBOL** | dedicated scanner | **none** — no offline analyzer in the catalog reads it |
296
298
  | JS / TS / JSX / TSX | brace scanner | ESLint, lizard, jscpd |
297
299
 
298
- Fortran reached parity in 1.6.0. lizard measures it — this project's
299
- catalog row for lizard was stale and said otherwise, so lizard came out
300
- `not-applicable` on every Fortran repository and never ran — and
301
- fortitude adds 100+ lint rules beside it. A lint now fails the build if
302
- any parsed language has no analyzer that measures complexity.
300
+ Fortran reached parity in 1.6.0: lizard had read it for years behind a
301
+ stale catalog row, so it came out `not-applicable` and never ran. A lint fails
302
+ the build if a parsed language has no analyzer measuring complexity — **COBOL is
303
+ the one disclosed exemption**, because the tooling that reads it is licensed and
304
+ host-resident, so its external tier is empty and the report says so.
303
305
 
304
306
  **External analyzer adapters (opt-in pool)** — this is how coverage extends
305
307
  beyond the built-in set. When you enable the analyzer pool, the tool shells out
@@ -311,12 +313,11 @@ selected *and* installed (acquisition is opt-in and off by default), and where
311
313
  they measured a full concept set they become the *primary* evidence, with the
312
314
  built-ins as the fallback.
313
315
 
314
- So: **first-class today is Python** (and TypeScript for semantics); Java, C, C++,
315
- C#, free-form Fortran and the JS/TS family are bounded-but-real; every other language is only as covered as
316
- the external analyzer you point at it — and with no analyzer, it is
317
- under-reported by design. The per-language accuracy, the exact parsed set, and
318
- the known limitations are documented in
319
- [docs/language-support.md](docs/language-support.md); the adapter catalog is in
316
+ So: **first-class today is Python** (and TypeScript for semantics); every other
317
+ parsed language is bounded-but-real; anything outside the table is only as
318
+ covered as the analyzer you point at it, and with none it is under-reported by
319
+ design. Per-language accuracy and limits:
320
+ [docs/language-support.md](docs/language-support.md); the adapter catalog:
320
321
  [docs/adapters.md](docs/adapters.md).
321
322
 
322
323
  ## What it produces
@@ -384,10 +385,9 @@ defaults. The grade is gated (A+ needs every dimension clean; a
384
385
  repo with production code and zero test files cannot earn an A-grade) and banded
385
386
  from the evidence floor, so withholding evidence never buys a better letter.
386
387
  Every threshold gate — file, function, duplication — is opted **on** for this
387
- repo's own CI, against thresholds stricter than the shipped defaults, so
388
- drifting below the bar fails the build rather than the README. (CI note:
389
- `actions/checkout` defaults to `fetch-depth: 1`, which hides history and costs
390
- roughly a grade — use `fetch-depth: 0`.)
388
+ repo's own CI, so drifting below the bar fails the build rather than the README.
389
+ (CI note: `actions/checkout` defaults to `fetch-depth: 1`, which hides history
390
+ and costs roughly a grade — use `fetch-depth: 0`.)
391
391
 
392
392
  ## Platform support
393
393
 
@@ -478,14 +478,14 @@ gate, and the self-audit — is in
478
478
 
479
479
  ## Support this work
480
480
 
481
- This is a single-maintainer, MIT-licensed project — free to use, and built on
482
- a lot of unpaid hours. If it saves you or your team time, please consider
481
+ This is a single-maintainer, MIT-licensed project — free to use, and built on a
482
+ lot of unpaid hours. If it saves you or your team time, please consider
483
483
  sponsoring its continued development:
484
484
 
485
485
  **❤️ [Sponsor on GitHub](https://github.com/sponsors/marshallguillory86)**
486
486
 
487
- Sponsorship is entirely optional and never gates a feature, a fix, or support —
488
- the whole tool stays free and open. It just helps keep the work going.
487
+ Sponsorship is optional and never gates a feature, a fix, or support — the whole
488
+ tool stays free and open. It just helps keep the work going.
489
489
 
490
490
  ## Acknowledgements
491
491
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "maintainability-agent"
7
- version = "2.6.0"
7
+ version = "2.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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maintainability-agent
3
- Version: 2.6.0
3
+ Version: 2.7.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.6.0**.
47
+ Version **2.7.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
@@ -78,9 +78,11 @@ What 1.0 guarantees:
78
78
  - **Deterministic and local.** Same tree, config, pinned analyzer versions and
79
79
  history in → same evidence, findings and score out. The analysis performs no
80
80
  network access and invokes no LLM, and **this agent does not transmit your
81
- source.** Third-party analyzers it may spawn (eslint, jscpd, lizard) are
82
- **not network-sandboxed** — this process does not police whether *they* phone
83
- home; install them yourself for an air-gapped run.
81
+ source.** Every report states what it examined and produced — files,
82
+ declarations, findings, bounded work items — **all computed with no model
83
+ call**: work a metered agent never has to do. Third-party analyzers it may
84
+ spawn (eslint, jscpd, lizard) are **not network-sandboxed** — this process does
85
+ not police whether *they* phone home; install them for an air-gapped run.
84
86
  - **One uniform rubric**, readable in source, applied to every repository —
85
87
  so "better" and "worse" are not an argument. Calibrated against a
86
88
  query-selected corpus of mature open-source projects; the corpus median
@@ -183,9 +185,8 @@ policy, history consent, economics, test-suite execution, and presentation, and
183
185
  no report. A configured repository returns `choice_needed` (`run` or
184
186
  `reconfigure`), also without a report. Answering setup does not start an audit.
185
187
  `action="run"` returns the report and its bounded remediation prompt to the
186
- conversation. `record_history=None` follows the persisted first-run history
187
- consent and always appends to an existing history, while an explicit `true`
188
- or `false` wins.
188
+ conversation. `record_history=None` follows the persisted first-run consent and
189
+ always appends to an existing history; an explicit `true` or `false` wins.
189
190
 
190
191
  ```bash
191
192
  python3 -m pip install "maintainability-agent[mcp]"
@@ -193,10 +194,10 @@ maintainability-agent mcp --allow-root /absolute/path/to/repository
193
194
  ```
194
195
 
195
196
  Presentation is exactly three choices — **chat**, a **Markdown** file, or a
196
- single-file **HTML** report — and where to save a file is asked only after a
197
- file format is chosen. No report file is written without that choice. See
198
- [chat workflow help](docs/help/README.md) and
199
- [IDE and agent integration](docs/ide-agent-integration.md).
197
+ single-file **HTML** report. Where to save is asked only after a file format is
198
+ chosen, and no report file is written without that choice. See
199
+ [chat workflow help](docs/help/README.md) and [IDE and agent
200
+ integration](docs/ide-agent-integration.md).
200
201
 
201
202
  ## Automation / CI: CLI
202
203
 
@@ -290,14 +291,13 @@ SonarQube, Qlty) rather than replacing them — their SARIF folds in via
290
291
 
291
292
  ## Language support
292
293
 
293
- **Be clear-eyed about this: the tool does not support every language equally,
294
- and on an unrecognized language it will quietly under-report rather than fail.**
295
- Coverage comes from two layers.
294
+ **Be clear-eyed: the tool does not support every language equally, and on an
295
+ unrecognized language it under-reports rather than fails.** Coverage has two layers.
296
296
 
297
- Nine languages are parsed as of **2.4.0**: Python (1.0), Java (1.0), C (1.1),
298
- C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4), the
299
- JS/TS family, and HTML. Each has a scanner written for it and a documented list of what it
300
- misses — a language is claimed here only when both exist.
297
+ Ten languages are parsed as of **2.7.0**: Python (1.0), Java (1.0), C (1.1),
298
+ C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
299
+ COBOL (2.7), the JS/TS family, and HTML. Each has a scanner written for it and a
300
+ documented list of what it misses — a language is claimed only when both exist.
301
301
 
302
302
  **Built-in scanner (always on, no dependencies)** — reads function/class
303
303
  declarations, sizes and complexity for a fixed set of languages, and **only**
@@ -311,18 +311,19 @@ these:
311
311
  | C++ (`.cpp`, `.hpp`, `.cc`, `.cxx`, `.hh`) | dedicated brace-bounded scanner — functions, class members, namespaces, templates | Bounded; bodyless declarations are not definitions |
312
312
  | C# (`.cs`) | dedicated brace-bounded scanner — methods, constructors, `class`/`interface`/`struct`/`record`/`enum` | Bounded; properties are not declarations |
313
313
  | Swift (`.swift`) | dedicated brace-bounded scanner — functions, initialisers, subscripts, `class`/`struct`/`enum`/`protocol`/`actor` | Bounded; extension members carry their type, protocol requirements and computed properties are not declarations |
314
+ | COBOL (`.cbl`, `.cob`, `.cpy`, and `.CBL`/`.COB`/`.CPY`) | dedicated scanner — PROCEDURE DIVISION paragraphs, bounded by the start of whatever follows; fixed-form card columns read where the layout carries them | Bounded by the next header; level numbers and container programs/sections are not declarations |
314
315
  | Fortran, free-form (`.f90`, `.f95`, `.f03`, `.f08`, `.F90`, `.F95`, `.F03`, `.F08`, `.pf`) | dedicated **keyword**-bounded scanner — modules, subroutines, functions, derived types | Bounded by `end`; measured with Fortran's own branch and nesting reading |
315
316
  | Fortran, fixed-form (`.f`, `.for`, `.ftn`, `.F`, `.FOR`, `.FTN`) | the same scanner over card-column source; continuations joined, labelled `DO` loops understood | Bounded by `end` or by the loop's label |
316
317
  | JS / TS / JSX / TSX (`.js`, `.jsx`, `.mjs`, `.cjs`, `.ts`, `.tsx`) | brace/paren depth over a masked copy | Bounded by the declaration's own braces |
317
318
  | HTML (`.html`) | same brace scanner (inline `<script>`) | Bounded |
318
319
  | TypeScript (semantic) | a recorded analysis or a locally-installed `tsc`, workspace projects included | Type-level facts; `unknown` when no checker is present |
319
320
 
320
- Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin,
321
- Swift, and the rest — is **not parsed for declarations by the built-in
322
- scanner.** Its files still count toward repo size, but the built-ins produce no
323
- function-size, complexity, duplication or dead-code findings for them, and the
324
- estimate leans on whatever evidence *is* available (which is why the report
325
- discloses its evidence tier and can withhold the grade).
321
+ Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin, and the rest —
322
+ is **not parsed for declarations by the built-in scanner.** Its files still count
323
+ toward repo size, but the built-ins produce no function-size, complexity,
324
+ duplication or dead-code findings for them, and the estimate leans on whatever
325
+ evidence *is* available (which is why the report discloses its evidence tier and
326
+ can withhold the grade).
326
327
 
327
328
  **Which analyzer covers which language** (the opt-in pool, when installed):
328
329
 
@@ -332,13 +333,14 @@ discloses its evidence tier and can withhold the grade).
332
333
  | Java | dedicated scanner | lizard, PMD, Checkstyle, SpotBugs |
333
334
  | C / C++ / C# | dedicated scanners | lizard, multimetric |
334
335
  | **Fortran** (free- and fixed-form) | dedicated scanner | **fortitude** — 100+ rules; **lizard** — complexity, NLOC, params |
336
+ | **COBOL** | dedicated scanner | **none** — no offline analyzer in the catalog reads it |
335
337
  | JS / TS / JSX / TSX | brace scanner | ESLint, lizard, jscpd |
336
338
 
337
- Fortran reached parity in 1.6.0. lizard measures it — this project's
338
- catalog row for lizard was stale and said otherwise, so lizard came out
339
- `not-applicable` on every Fortran repository and never ran — and
340
- fortitude adds 100+ lint rules beside it. A lint now fails the build if
341
- any parsed language has no analyzer that measures complexity.
339
+ Fortran reached parity in 1.6.0: lizard had read it for years behind a
340
+ stale catalog row, so it came out `not-applicable` and never ran. A lint fails
341
+ the build if a parsed language has no analyzer measuring complexity — **COBOL is
342
+ the one disclosed exemption**, because the tooling that reads it is licensed and
343
+ host-resident, so its external tier is empty and the report says so.
342
344
 
343
345
  **External analyzer adapters (opt-in pool)** — this is how coverage extends
344
346
  beyond the built-in set. When you enable the analyzer pool, the tool shells out
@@ -350,12 +352,11 @@ selected *and* installed (acquisition is opt-in and off by default), and where
350
352
  they measured a full concept set they become the *primary* evidence, with the
351
353
  built-ins as the fallback.
352
354
 
353
- So: **first-class today is Python** (and TypeScript for semantics); Java, C, C++,
354
- C#, free-form Fortran and the JS/TS family are bounded-but-real; every other language is only as covered as
355
- the external analyzer you point at it — and with no analyzer, it is
356
- under-reported by design. The per-language accuracy, the exact parsed set, and
357
- the known limitations are documented in
358
- [docs/language-support.md](docs/language-support.md); the adapter catalog is in
355
+ So: **first-class today is Python** (and TypeScript for semantics); every other
356
+ parsed language is bounded-but-real; anything outside the table is only as
357
+ covered as the analyzer you point at it, and with none it is under-reported by
358
+ design. Per-language accuracy and limits:
359
+ [docs/language-support.md](docs/language-support.md); the adapter catalog:
359
360
  [docs/adapters.md](docs/adapters.md).
360
361
 
361
362
  ## What it produces
@@ -423,10 +424,9 @@ defaults. The grade is gated (A+ needs every dimension clean; a
423
424
  repo with production code and zero test files cannot earn an A-grade) and banded
424
425
  from the evidence floor, so withholding evidence never buys a better letter.
425
426
  Every threshold gate — file, function, duplication — is opted **on** for this
426
- repo's own CI, against thresholds stricter than the shipped defaults, so
427
- drifting below the bar fails the build rather than the README. (CI note:
428
- `actions/checkout` defaults to `fetch-depth: 1`, which hides history and costs
429
- roughly a grade — use `fetch-depth: 0`.)
427
+ repo's own CI, so drifting below the bar fails the build rather than the README.
428
+ (CI note: `actions/checkout` defaults to `fetch-depth: 1`, which hides history
429
+ and costs roughly a grade — use `fetch-depth: 0`.)
430
430
 
431
431
  ## Platform support
432
432
 
@@ -517,14 +517,14 @@ gate, and the self-audit — is in
517
517
 
518
518
  ## Support this work
519
519
 
520
- This is a single-maintainer, MIT-licensed project — free to use, and built on
521
- a lot of unpaid hours. If it saves you or your team time, please consider
520
+ This is a single-maintainer, MIT-licensed project — free to use, and built on a
521
+ lot of unpaid hours. If it saves you or your team time, please consider
522
522
  sponsoring its continued development:
523
523
 
524
524
  **❤️ [Sponsor on GitHub](https://github.com/sponsors/marshallguillory86)**
525
525
 
526
- Sponsorship is entirely optional and never gates a feature, a fix, or support —
527
- the whole tool stays free and open. It just helps keep the work going.
526
+ Sponsorship is optional and never gates a feature, a fix, or support — the whole
527
+ tool stays free and open. It just helps keep the work going.
528
528
 
529
529
  ## Acknowledgements
530
530
 
@@ -59,6 +59,7 @@ src/maintainability_audit/_pillars.py
59
59
  src/maintainability_audit/_practice.py
60
60
  src/maintainability_audit/_pressures.py
61
61
  src/maintainability_audit/_ranges_c.py
62
+ src/maintainability_audit/_ranges_cobol.py
62
63
  src/maintainability_audit/_ranges_core.py
63
64
  src/maintainability_audit/_ranges_cpp.py
64
65
  src/maintainability_audit/_ranges_csharp.py
@@ -173,6 +174,7 @@ tests/test_ci_installs_the_analyzer_pool.py
173
174
  tests/test_claimed_languages.py
174
175
  tests/test_cli.py
175
176
  tests/test_clone_group_class.py
177
+ tests/test_cobol_declarations.py
176
178
  tests/test_cognitive_complexity.py
177
179
  tests/test_cohort_statistics.py
178
180
  tests/test_concealment_properties.py
@@ -1,3 +1,3 @@
1
1
  """Maintainability Audit CI."""
2
2
 
3
- __version__ = "2.6.0"
3
+ __version__ = "2.7.0"
@@ -35,6 +35,12 @@ import re
35
35
 
36
36
  from ._masking import mask_fortran_lines, mask_lines
37
37
 
38
+ # Both live in `parsing`, and `_ranges_core` reaches nothing here, so this
39
+ # is a sibling import rather than a cycle. COBOL's mask is not in
40
+ # `_masking` with the others because it needs the whole file to know which
41
+ # division a line is in — see `_ranges_cobol.mask_cobol_lines`.
42
+ from ._ranges_cobol import mask_cobol_lines
43
+
38
44
  # Constructs that both cost a point and deepen the nesting for whatever
39
45
  # they contain.
40
46
  _NESTING_NODES = (ast.If, ast.For, ast.AsyncFor, ast.While, ast.ExceptHandler, ast.IfExp)
@@ -175,6 +181,57 @@ def fortran_cognitive(lines: list[str]) -> int:
175
181
  return score
176
182
 
177
183
 
184
+ _CB_CLOSES_RE = re.compile(r"\bEND-(?:IF|EVALUATE|PERFORM|SEARCH|READ|STRING)\b", re.I)
185
+ _CB_OPENS_RE = re.compile(
186
+ r"\bIF\b|\bEVALUATE\b|\bPERFORM\b(?=[^.]*\b(?:UNTIL|VARYING|TIMES)\b)|\bSEARCH\b",
187
+ re.I,
188
+ )
189
+ _CB_ELSE_RE = re.compile(r"^\s*ELSE\b|\bWHEN\b", re.I) # noqa: S5850 - alternation is intended
190
+ _CB_BOOLEAN_RE = re.compile(r"\b(?:AND|OR)\b", re.I)
191
+ _CB_CONTROL_RE = re.compile(r"\b(?:IF|EVALUATE|UNTIL|VARYING|TIMES|SEARCH)\b", re.I)
192
+
193
+
194
+ def cobol_cognitive(lines: list[str]) -> int:
195
+ """Cognitive complexity for a COBOL paragraph.
196
+
197
+ Nesting is read from the constructs themselves, as in Fortran, since
198
+ COBOL has no braces either. What COBOL adds is a second way to close
199
+ every open scope at once: **a period ends the sentence and with it
200
+ every construct the sentence opened.** Classic COBOL leans on that
201
+ entirely — `IF X DISPLAY Y.` opens and closes an `IF` with no
202
+ `END-IF` anywhere — and a reader that only counted `END-` terminators
203
+ would let depth climb monotonically through a paragraph and charge
204
+ the last statement for every branch above it.
205
+
206
+ The `PERFORM` lookahead is the other judgment. `PERFORM SOME-PARA` is
207
+ a call and opens nothing; `PERFORM UNTIL DONE` is a loop and does.
208
+ Counting every `PERFORM` as nesting would make an ordinary
209
+ call-per-line paragraph read as deeply nested.
210
+ """
211
+ masked = mask_cobol_lines(lines)
212
+ score = 0
213
+ depth = 0
214
+ for line in masked:
215
+ statement = line.rstrip()
216
+ if not statement.strip():
217
+ continue
218
+ if _CB_CLOSES_RE.search(statement):
219
+ depth = max(0, depth - len(_CB_CLOSES_RE.findall(statement)))
220
+ body = _CB_CLOSES_RE.sub(" ", statement)
221
+ if _CB_ELSE_RE.search(body):
222
+ score += 1
223
+ score += len(_CB_BOOLEAN_RE.findall(body))
224
+ else:
225
+ for _ in _CB_CONTROL_RE.finditer(body):
226
+ score += 1 + depth
227
+ score += len(_CB_BOOLEAN_RE.findall(body))
228
+ depth += len(_CB_OPENS_RE.findall(body))
229
+ if statement.rstrip().endswith("."):
230
+ # The sentence ended, and with it every scope it opened.
231
+ depth = 0
232
+ return score
233
+
234
+
178
235
  def brace_cognitive(lines: list[str], control: re.Pattern[str] | None = None) -> int:
179
236
  """Approximate cognitive complexity for a C-family declaration body.
180
237