maintainability-agent 2.10.0__tar.gz → 2.11.2__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 (352) hide show
  1. {maintainability_agent-2.10.0/src/maintainability_agent.egg-info → maintainability_agent-2.11.2}/PKG-INFO +83 -122
  2. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/README.md +81 -121
  3. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/pyproject.toml +21 -2
  4. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2/src/maintainability_agent.egg-info}/PKG-INFO +83 -122
  5. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_agent.egg-info/SOURCES.txt +16 -0
  6. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_agent.egg-info/requires.txt +1 -0
  7. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/__init__.py +1 -1
  8. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_anchor.py +1 -1
  9. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_assets/standard.md +4 -4
  10. maintainability_agent-2.11.2/src/maintainability_audit/_banner.py +96 -0
  11. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_config_defaults.py +4 -0
  12. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_discovery.py +47 -95
  13. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_economics.py +35 -15
  14. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_first_run.py +3 -3
  15. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_in_loop.py +116 -7
  16. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_in_loop_view.py +6 -1
  17. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_masking.py +176 -0
  18. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_mcp_audit.py +2 -1
  19. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_metrics_types.py +177 -5
  20. maintainability_agent-2.11.2/src/maintainability_audit/_operator_reads.py +100 -0
  21. maintainability_agent-2.11.2/src/maintainability_audit/_ranges_go.py +141 -0
  22. maintainability_agent-2.11.2/src/maintainability_audit/_ranges_php.py +126 -0
  23. maintainability_agent-2.11.2/src/maintainability_audit/_ranges_ruby.py +252 -0
  24. maintainability_agent-2.11.2/src/maintainability_audit/_ranges_rust.py +182 -0
  25. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_safe_write.py +3 -3
  26. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_scan_history.py +78 -37
  27. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_user_config.py +22 -2
  28. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/cli.py +58 -26
  29. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/config.py +10 -74
  30. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/declarations.py +57 -3
  31. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/sarif.py +30 -2
  32. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_bridge.py +2 -2
  33. maintainability_agent-2.11.2/tests/test_claimed_languages.py +356 -0
  34. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_declared_imports.py +9 -0
  35. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_fortran_metrics.py +17 -3
  36. maintainability_agent-2.11.2/tests/test_go_declarations.py +219 -0
  37. maintainability_agent-2.11.2/tests/test_grammar_constructs.py +464 -0
  38. maintainability_agent-2.11.2/tests/test_in_loop_budgets.py +263 -0
  39. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_in_loop_check.py +9 -3
  40. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_js_complexity_operators.py +9 -2
  41. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_operator_named_paths.py +2 -0
  42. maintainability_agent-2.11.2/tests/test_operator_named_reads.py +417 -0
  43. maintainability_agent-2.11.2/tests/test_php_declarations.py +220 -0
  44. maintainability_agent-2.11.2/tests/test_policy_claims.py +159 -0
  45. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_prove_falsifiers.py +11 -1
  46. maintainability_agent-2.11.2/tests/test_python_complexity.py +227 -0
  47. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_readme_claims.py +6 -1
  48. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_report_remedy_copy.py +3 -3
  49. maintainability_agent-2.11.2/tests/test_ruby_declarations.py +308 -0
  50. maintainability_agent-2.11.2/tests/test_rust_declarations.py +223 -0
  51. maintainability_agent-2.11.2/tests/test_sonar_resolve.py +129 -0
  52. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_source_index.py +39 -2
  53. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_unread_code.py +27 -17
  54. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_user_config_tier.py +20 -10
  55. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_written_record.py +80 -140
  56. maintainability_agent-2.10.0/tests/test_claimed_languages.py +0 -169
  57. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/LICENSE +0 -0
  58. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/setup.cfg +0 -0
  59. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
  60. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
  61. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_agent.egg-info/top_level.txt +0 -0
  62. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/__main__.py +0 -0
  63. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_adapters.py +0 -0
  64. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_analysis.py +0 -0
  65. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_arguments.py +0 -0
  66. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_aspects.py +0 -0
  67. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
  68. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_attestation.py +0 -0
  69. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_backfill.py +0 -0
  70. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_bands.py +0 -0
  71. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_built_ins.py +0 -0
  72. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_calibration.py +0 -0
  73. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_catalog.py +0 -0
  74. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_charts.py +0 -0
  75. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_cognitive.py +0 -0
  76. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_conformance.py +0 -0
  77. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_corroborate.py +0 -0
  78. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_coverage_notes.py +0 -0
  79. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_derive.py +0 -0
  80. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_documents.py +0 -0
  81. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_economics_view.py +0 -0
  82. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_environment.py +0 -0
  83. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_evidence_view.py +0 -0
  84. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_finding_match.py +0 -0
  85. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_formula.py +0 -0
  86. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_gates.py +0 -0
  87. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_generic.py +0 -0
  88. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_grant_ledger.py +0 -0
  89. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_history_view.py +0 -0
  90. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_hostile_prompt.py +0 -0
  91. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_hotspots.py +0 -0
  92. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_html_report_sections.py +0 -0
  93. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_html_view.py +0 -0
  94. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_identity.py +0 -0
  95. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_jvm_adapters.py +0 -0
  96. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_markdown_sections.py +0 -0
  97. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_mcp_gate.py +0 -0
  98. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_mcp_grants.py +0 -0
  99. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_mcp_refusals.py +0 -0
  100. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_mcp_resources.py +0 -0
  101. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_mcp_setup.py +0 -0
  102. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_metric_adapters.py +0 -0
  103. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_pillars.py +0 -0
  104. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_practice.py +0 -0
  105. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_precommit.py +0 -0
  106. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_precommit_install.py +0 -0
  107. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_precommit_view.py +0 -0
  108. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_pressures.py +0 -0
  109. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ranges_c.py +0 -0
  110. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ranges_cobol.py +0 -0
  111. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ranges_core.py +0 -0
  112. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ranges_cpp.py +0 -0
  113. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ranges_csharp.py +0 -0
  114. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ranges_fortran.py +0 -0
  115. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ranges_java.py +0 -0
  116. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ranges_js.py +0 -0
  117. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ranges_swift.py +0 -0
  118. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_ratchet.py +0 -0
  119. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_recurrence.py +0 -0
  120. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_run_comparison.py +0 -0
  121. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_runner.py +0 -0
  122. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_scan_view.py +0 -0
  123. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_second_source.py +0 -0
  124. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_selection.py +0 -0
  125. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_semantic.py +0 -0
  126. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_semantic_policy.py +0 -0
  127. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_semantic_ts.py +0 -0
  128. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_semantic_view.py +0 -0
  129. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_setup_errors.py +0 -0
  130. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_setup_persist.py +0 -0
  131. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
  132. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
  133. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
  134. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
  135. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
  136. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
  137. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_skill_install.py +0 -0
  138. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_stored_grants.py +0 -0
  139. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_tdd_view.py +0 -0
  140. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_test_commands.py +0 -0
  141. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_test_execution.py +0 -0
  142. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_test_pairing.py +0 -0
  143. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_tokens.py +0 -0
  144. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_tool_adapters.py +0 -0
  145. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_trends.py +0 -0
  146. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_verdict_adapters.py +0 -0
  147. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_verification.py +0 -0
  148. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_work_order.py +0 -0
  149. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_work_order_view.py +0 -0
  150. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_work_order_weights.py +0 -0
  151. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/_xml.py +0 -0
  152. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/baseline.py +0 -0
  153. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/deadcode.py +0 -0
  154. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/duplication.py +0 -0
  155. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/evidence.py +0 -0
  156. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/git_tools.py +0 -0
  157. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/history.py +0 -0
  158. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/idioms.py +0 -0
  159. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/instructions.py +0 -0
  160. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/mcp_server.py +0 -0
  161. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/metrics.py +0 -0
  162. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/prompts.py +0 -0
  163. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/renderers.py +0 -0
  164. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/report.py +0 -0
  165. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/scoring.py +0 -0
  166. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/similarity.py +0 -0
  167. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/src/maintainability_audit/source.py +0 -0
  168. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_acquisition_trust.py +0 -0
  169. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_adapter_docs.py +0 -0
  170. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_adapter_recordings.py +0 -0
  171. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_adapters.py +0 -0
  172. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_added_lines.py +0 -0
  173. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analysis_coverage.py +0 -0
  174. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analysis_execution.py +0 -0
  175. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_config_isolation.py +0 -0
  176. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_estimate_claims.py +0 -0
  177. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_pinning.py +0 -0
  178. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_primary_estimate.py +0 -0
  179. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_provenance.py +0 -0
  180. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_provenance_exclusions.py +0 -0
  181. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_scoring_path.py +0 -0
  182. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_spread_range.py +0 -0
  183. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_analyzer_xml_bounds.py +0 -0
  184. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_anchor_and_mode.py +0 -0
  185. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_anchor_disclosure.py +0 -0
  186. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_annotations_match_behaviour.py +0 -0
  187. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_anticipated_refusals.py +0 -0
  188. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_architecture.py +0 -0
  189. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_artifact_write_route_class.py +0 -0
  190. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_aspect_coverage.py +0 -0
  191. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_asset_snapshot_class.py +0 -0
  192. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_ast_reading_resolves_spellings.py +0 -0
  193. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_attestation.py +0 -0
  194. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_audit_components.py +0 -0
  195. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_authorization_freshness.py +0 -0
  196. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_authorship_gates.py +0 -0
  197. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_backfill.py +0 -0
  198. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_band_concealment_class.py +0 -0
  199. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_band_concealment_p3.py +0 -0
  200. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_band_pressures.py +0 -0
  201. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_bands.py +0 -0
  202. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_body_or_signature_class.py +0 -0
  203. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_c_declarations.py +0 -0
  204. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_calibration_corpus.py +0 -0
  205. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_calibration_drift.py +0 -0
  206. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_calibration_tooling.py +0 -0
  207. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_catalog_selection.py +0 -0
  208. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_catalog_tier_promise.py +0 -0
  209. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_chat_primary_docs.py +0 -0
  210. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_checkstyle_adapter.py +0 -0
  211. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_checkstyle_catalog.py +0 -0
  212. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_ci_history_recipe.py +0 -0
  213. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
  214. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_cli.py +0 -0
  215. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_clone_group_class.py +0 -0
  216. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_cobol_declarations.py +0 -0
  217. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_cognitive_complexity.py +0 -0
  218. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_cohort_statistics.py +0 -0
  219. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_concealment_properties.py +0 -0
  220. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_config_shape.py +0 -0
  221. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_consent_and_grant.py +0 -0
  222. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_consumer_migration.py +0 -0
  223. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_contract_claims.py +0 -0
  224. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_corroborate.py +0 -0
  225. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_coverage_by_language.py +0 -0
  226. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_cpp_declarations.py +0 -0
  227. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_csharp_declarations.py +0 -0
  228. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_d15_composition.py +0 -0
  229. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_d15_goal_directed.py +0 -0
  230. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_dead_code.py +0 -0
  231. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_declaration_edge_cases.py +0 -0
  232. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_declaration_grading.py +0 -0
  233. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_declaration_ranges.py +0 -0
  234. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_declaration_source.py +0 -0
  235. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_declared_authorship.py +0 -0
  236. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_derivation_mix.py +0 -0
  237. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_determinism.py +0 -0
  238. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_dimension_ratchet.py +0 -0
  239. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_direct_runner_availability_class.py +0 -0
  240. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_discovery.py +0 -0
  241. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_doc_claims.py +0 -0
  242. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_docs_links.py +0 -0
  243. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_economic_context.py +0 -0
  244. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_empty_output_not_clean.py +0 -0
  245. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_empty_output_not_clean_adapters.py +0 -0
  246. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_environment_work_order.py +0 -0
  247. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_evidence_invariants.py +0 -0
  248. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_evidence_normalization.py +0 -0
  249. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_evidence_properties.py +0 -0
  250. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_exclusion_dialects.py +0 -0
  251. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_falsifier_standard.py +0 -0
  252. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_file_list_cap_class.py +0 -0
  253. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_finding_identity.py +0 -0
  254. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_first_run_elicitation.py +0 -0
  255. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_first_run_prompt.py +0 -0
  256. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_first_run_reelicitation.py +0 -0
  257. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_fix_breadth_window.py +0 -0
  258. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_fixed_form_fortran.py +0 -0
  259. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_format_ask.py +0 -0
  260. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_fortran_declarations.py +0 -0
  261. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_fortran_practice.py +0 -0
  262. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_git_argv.py +0 -0
  263. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_git_read_only.py +0 -0
  264. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_git_readonly_class.py +0 -0
  265. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_grant_only_user_tier.py +0 -0
  266. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_history.py +0 -0
  267. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_history_boundary.py +0 -0
  268. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_history_manifest.py +0 -0
  269. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_history_schema2.py +0 -0
  270. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_history_window.py +0 -0
  271. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_hostile_prompt.py +0 -0
  272. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_html_executive.py +0 -0
  273. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_html_section_parity_class.py +0 -0
  274. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_identity_docs.py +0 -0
  275. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_identity_resolution.py +0 -0
  276. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_idiom_divergence.py +0 -0
  277. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_installed_wheel_runtime.py +0 -0
  278. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_instruction_targets.py +0 -0
  279. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_java_range_guard.py +0 -0
  280. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_java_ranges.py +0 -0
  281. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_java_scored.py +0 -0
  282. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_java_wiring.py +0 -0
  283. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_js_declarations.py +0 -0
  284. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_language_coverage.py +0 -0
  285. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_mcp_baseline_payload.py +0 -0
  286. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_mcp_history.py +0 -0
  287. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_mcp_server.py +0 -0
  288. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_migration_1_0.py +0 -0
  289. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_near_duplicates.py +0 -0
  290. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_network_disclosure.py +0 -0
  291. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_one_setup_across_surfaces_class.py +0 -0
  292. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_pattern_budget.py +0 -0
  293. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_phase6_claims.py +0 -0
  294. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_pillars_and_practice.py +0 -0
  295. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_platform_claim.py +0 -0
  296. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_pmd_adapter.py +0 -0
  297. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_pmd_audit_closures.py +0 -0
  298. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_pool_runs_by_config.py +0 -0
  299. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_population_floors.py +0 -0
  300. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_practice_nested_gates_class.py +0 -0
  301. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_precommit_staged.py +0 -0
  302. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_presentation_refusals.py +0 -0
  303. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_promises.py +0 -0
  304. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_prompt_escalation_once.py +0 -0
  305. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_prompt_honesty.py +0 -0
  306. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_prompt_location_escalation_class.py +0 -0
  307. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_python_declarations.py +0 -0
  308. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_read_boundary.py +0 -0
  309. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_recurrence.py +0 -0
  310. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_release_plan.py +0 -0
  311. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_release_plan_status.py +0 -0
  312. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_roles_recorded.py +0 -0
  313. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_root_grants.py +0 -0
  314. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_rubric_ignores_project_lint_config.py +0 -0
  315. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_run_comparison.py +0 -0
  316. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_runner.py +0 -0
  317. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_sarif.py +0 -0
  318. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_scan_history.py +0 -0
  319. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_scan_scope.py +0 -0
  320. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_scanner_unsafe_direction.py +0 -0
  321. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_scanning.py +0 -0
  322. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_schema_fidelity.py +0 -0
  323. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_scope_conformance.py +0 -0
  324. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_scoring_calibration.py +0 -0
  325. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_semantic_policy.py +0 -0
  326. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_setup_gate_completeness.py +0 -0
  327. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_setup_gate_independent_contract.py +0 -0
  328. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_setup_precondition.py +0 -0
  329. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_skill_install.py +0 -0
  330. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_spotbugs_adapter.py +0 -0
  331. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_spotbugs_catalog.py +0 -0
  332. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_stage8_contract.py +0 -0
  333. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_suite_isolation.py +0 -0
  334. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_swift_declarations.py +0 -0
  335. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_tdd_structure.py +0 -0
  336. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_test_commands.py +0 -0
  337. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_test_execution_class.py +0 -0
  338. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_three_presentations.py +0 -0
  339. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_tree_chosen_spawn.py +0 -0
  340. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_trends.py +0 -0
  341. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_type_fields_not_functions_class.py +0 -0
  342. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_uat_falsifiers.py +0 -0
  343. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_verification_audit_closures.py +0 -0
  344. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_verified_grade.py +0 -0
  345. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_version_claim.py +0 -0
  346. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_wheel_contents.py +0 -0
  347. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_work_order.py +0 -0
  348. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_work_order_items.py +0 -0
  349. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_work_order_selection.py +0 -0
  350. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_workflow_supply_chain.py +0 -0
  351. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_write_boundary.py +0 -0
  352. {maintainability_agent-2.10.0 → maintainability_agent-2.11.2}/tests/test_write_route_class.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maintainability-agent
3
- Version: 2.10.0
3
+ Version: 2.11.2
4
4
  Summary: Maintainability gate and AI remediation prompt generator for CI.
5
5
  Author: Marshall Guillory
6
6
  License: MIT
@@ -35,6 +35,7 @@ Requires-Dist: pip-audit>=2.7; extra == "dev"
35
35
  Requires-Dist: mcp<3,>=2; extra == "dev"
36
36
  Requires-Dist: PyYAML>=6; extra == "dev"
37
37
  Requires-Dist: setuptools>=70; extra == "dev"
38
+ Requires-Dist: lizard>=1.17; extra == "dev"
38
39
  Dynamic: license-file
39
40
 
40
41
  # Maintainability Agent
@@ -44,11 +45,18 @@ Dynamic: license-file
44
45
  **A deterministic, offline maintainability audit whose output is a _bounded
45
46
  work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
46
47
  says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
47
- Version **2.10.0**.
48
-
49
- **Languages parsed:** Python, Java, C, C++, C#, Swift, Fortran (free-form
50
- *and* fixed-form), and the JS/TS family — each by a scanner written for it, and
51
- measured with that language's own reading of what a branch is.
48
+ Version **2.11.2**.
49
+
50
+ **Planned, not shipped:** the audit tool will become `maintainability-audit`;
51
+ a new `maintainability-agent` companion will run it and automate human-selected
52
+ work orders within the user's agent chat. The installation commands below
53
+ still describe the current product. See the [planned split](docs/product-intent.md#planned-product-split-and-companion-workflow).
54
+
55
+ **Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
56
+ COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
57
+ by a scanner written for it, and measured with that language's own reading of
58
+ what a branch is, checked construct-by-construct against an independent
59
+ implementation.
52
60
  [What that means per language](#language-support).
53
61
 
54
62
  ```bash
@@ -103,50 +111,22 @@ differ.
103
111
 
104
112
  ## Why this exists
105
113
 
106
- The ratio of code-written to code-reviewed has collapsed. Unmaintainable code
107
- that used to accumulate over years can now accumulate in an afternoon:
108
- duplicated helpers, oversized files, speculative abstractions — the same slop
109
- hand-written codebases always accrued, now at machine speed.
110
-
111
- The same speed is the way out. An agent pointed at specific, deterministic
112
- findings can fix them at the rate they appear. The loop this tool closes:
113
-
114
- 1. **Measure** pressure points deterministically, with no LLM involved.
115
- 2. **Score** with one uniform standard, so the verdict is not a debate.
116
- 3. **Emit** a prompt scoped to *those findings only*, with explicit
117
- instructions not to refactor beyond them.
118
- 4. **Hand it to the agent.** Review a scoped diff instead of a speculative
119
- rewrite.
120
-
121
- Step 3 is the product; steps 1 and 2 are in service of it. Every other tool in
122
- this space stops at "here's a list of findings."
114
+ The ratio of code-written to code-reviewed has collapsed, and the same speed is
115
+ the way out: an agent pointed at specific, deterministic findings can fix them
116
+ at the rate they appear. The loop is **measure** with no model involved,
117
+ **score** against one uniform standard, **emit a prompt scoped to those findings
118
+ only**, and hand it over. Step three is the product.
123
119
 
124
120
  **Who does the checking matters as much as what it checks.** An author is never
125
121
  the independent check on their own work, so a platform that generates code and
126
- grades it is producing a self-assessment — a property of the arrangement, not a
127
- criticism of any one of them. This writes nothing and runs no model, which is
128
- what lets its verdict be evidence ([the principle](docs/philosophy.md#principles)).
129
- Since 2.1.0 the work order is also **checked**: `--conformance` compares the
130
- returned diff against the paths the report named, `--fail-on-regression`
131
- ratchets the dimension scores, and `--attestation-output` composes them into one
132
- record ([how that hole was closed](docs/roadmap.md#the-remediation-hole-closed-in-210-through-230)).
133
- The limit, stated in the same breath: those checks read the diff's **shape**,
134
- never its correctness — whether the change works is not a claim this tool makes.
135
-
136
- One pre-registered experiment has tested the bounded prompt.
137
- Generic prompting made 2 of 6 repositories worse; bounded prompting made 1 of 6 worse and improved 5 of 6, under this tool's own finding count.
138
- The *registered* hypothesis was narrower diffs, which did not hold, so the
139
- registered verdict stands at **INCONCLUSIVE**. Method, limits and raw data:
140
- [docs/studies.md](docs/studies.md#does-the-bounded-prompt-work-controlled-experiment-pre-registered).
141
-
142
- ### Who it's for
143
-
144
- - Teams running AI agents in the dev loop, tired of unbounded cleanup PRs, who
145
- want a CI gate that actively constrains follow-up scope.
146
- - Repos that want a maintainability gate without a SaaS analyzer or shipping
147
- code to a third party.
148
- - Solo devs who want a single deterministic audit to pin in a Makefile,
149
- pre-commit, or local CI script.
122
+ grades it is producing a self-assessment. This writes nothing and runs no model,
123
+ which is what lets its verdict count as evidence. Since 2.1.0 the work order is
124
+ itself checked — scope conformance, a dimension ratchet, and an attestation
125
+ record — and those checks read a diff's **shape**, never whether it works.
126
+
127
+ The full argument, including what this deliberately does not compete on:
128
+ [why this exists](docs/why-this-exists.md) and
129
+ [philosophy](docs/philosophy.md).
150
130
 
151
131
  ## The road to 1.0
152
132
 
@@ -225,8 +205,8 @@ withheld and the scope is named as the reason.
225
205
  ### Checking that the agent did the work
226
206
 
227
207
  The work order tells an agent to fix exactly these findings and refactor nothing
228
- else. These flags check that the diff obeyed it — they read its _shape_, not its
229
- correctness:
208
+ else. Four flags check that the diff obeyed it — reading its _shape_, never
209
+ whether it works:
230
210
 
231
211
  ```bash
232
212
  maintainability-agent \
@@ -237,30 +217,19 @@ maintainability-agent \
237
217
  --attestation-output maintainability-attestation.md
238
218
  ```
239
219
 
240
- - **`--conformance <revspec>`** compares the diff against the paths the report
241
- named, and answers two questions separately: did it **stay in scope**, and did
242
- it **silence nothing**. They stay separate because a change can obey the work
243
- order and still add a `# noqa` to a finding inside it. A test added for a fix
244
- stays in scope even though the work order never named the test file.
245
- - **`--fail-on-out-of-scope`** turns that into a CI failure.
246
- - **`--fail-on-regression`** ratchets the _dimension_ scores against scan
247
- history, catching a change that improves one dimension while silently
248
- regressing another. It has three outcomes, not two — held, regressed, and
249
- **not comparable**, because two scans taken under different calibration cannot
250
- be differenced.
251
- - **`--attestation-output`** writes the three into one per-change record: what
252
- was measured, what the agent was told to change, whether it stayed inside the
253
- work order, and what moved. It is reproducible and **not signed** — nothing
254
- here holds a key, and the document says so in its own text. A check nobody ran
255
- renders as _not asked_, never as passed.
256
- - **`--transformation NAME`** names the class of work a scan followed and
257
- reports how this run of it compares with earlier ones. **A report, never a
258
- gate.** It says one run "moved further" than another, never that it was
259
- _better_ — two runs of one codemod land on different code — and it measures
260
- the interval, not the transformation.
261
-
262
- The [roadmap](docs/roadmap.md#the-remediation-hole-closed-in-210-through-230)
263
- has the history of why this was the hole under the product's central claim.
220
+ `--conformance` answers two questions separately — did the diff **stay in
221
+ scope**, and did it **silence nothing** — because a change can obey the work
222
+ order and still add a `# noqa` to a finding inside it. `--fail-on-out-of-scope`
223
+ turns that into a CI failure. `--fail-on-regression` ratchets the _dimension_
224
+ scores against history, with three outcomes rather than two: held, regressed,
225
+ and **not comparable**, because two scans taken under different calibration
226
+ cannot be differenced. `--attestation-output` composes them into one per-change
227
+ record, reproducible and **not signed** — a check nobody ran renders as _not
228
+ asked_, never as passed.
229
+
230
+ Each flag in full, including `--transformation`:
231
+ [docs/cli.md](docs/cli.md). Why this was the hole under the product's central
232
+ claim: [the roadmap](docs/roadmap.md#the-remediation-hole-closed-in-210-through-230).
264
233
 
265
234
  ### During the loop, not only after it
266
235
 
@@ -275,10 +244,16 @@ maintainability-agent --install-precommit-hook # before committing
275
244
 
276
245
  **`--check PATH`** answers about content on stdin. No repository, no git, no
277
246
  scan; `PATH` names the content and is never opened. Pass file content, not a
278
- diff — content that does not parse says so rather than reading as clean, as
279
- does a language with no scanner. In text it is **silent while you have room**
280
- and speaks once a declaration nears its limit; `--format json` carries the
281
- remaining budget for every declaration whether or not it is close.
247
+ diff — **a piped diff is refused in every language**, by its format rather
248
+ than by a parser, and says so rather than reading as clean; so does a
249
+ language with no scanner. Beyond that, only Python's content is parsed:
250
+ a brace language's invalid source is not detected, because zero
251
+ declarations is not evidence of a parse failure and marking valid files
252
+ unparsed would be worse than the silence. In text it is **silent while you have room**
253
+ and speaks once a declaration nears its limit — on *any* budget it can be
254
+ failed on, length or cyclomatic or cognitive, not length alone.
255
+ `--format json` carries the remaining budget for every declaration whether
256
+ or not it is close, per budget rather than as one number.
282
257
 
283
258
  **`--staged`** scans the git index. Stage half a file with `git add -p`, keep
284
259
  typing, and what gets measured is what the commit will actually contain —
@@ -297,9 +272,12 @@ The deterministic scanner reads code from your repo (no LLM calls) and produces
297
272
  signals on:
298
273
 
299
274
  - largest files (configurable warn/fail thresholds)
300
- - function size and complexity — exact ranges for Python via `ast`,
301
- brace-bounded for JS/TS/JSX/TSX/HTML — plus **cognitive complexity**
302
- (nesting-weighted reading cost)
275
+ - function size and complexity — exact ranges for Python via `ast`, and
276
+ bounded ranges for every other parsed language, each measured with that
277
+ language's own reading of what a branch is ([Language
278
+ support](#language-support) is the list, so this sentence cannot drift
279
+ out of step with it) — plus **cognitive complexity** (nesting-weighted
280
+ reading cost)
303
281
  - class size, against its own budget (`max_class_lines`)
304
282
  - duplicate blocks, and **near-duplicate declarations** compared structurally so
305
283
  renaming can't hide a copy, each paired with the original to reuse
@@ -325,9 +303,9 @@ SonarQube, Qlty) rather than replacing them — their SARIF folds in via
325
303
  **Be clear-eyed: the tool does not support every language equally, and on an
326
304
  unrecognized language it under-reports rather than fails.** Coverage has two layers.
327
305
 
328
- Ten languages are parsed as of **2.7.0**: Python (1.0), Java (1.0), C (1.1),
306
+ Fourteen languages are parsed as of **2.11.0**: Python (1.0), Java (1.0), C (1.1),
329
307
  C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
330
- COBOL (2.7), the JS/TS family, and HTML. Each has a scanner written for it and a
308
+ COBOL (2.7), Go (2.11), Rust (2.11), PHP (2.11), Ruby (2.11), the JS/TS family, and HTML. Each has a scanner written for it and a
331
309
  documented list of what it misses — a language is claimed only when both exist.
332
310
 
333
311
  **Built-in scanner (always on, no dependencies)** — reads function/class
@@ -342,6 +320,10 @@ these:
342
320
  | C++ (`.cpp`, `.hpp`, `.cc`, `.cxx`, `.hh`) | dedicated brace-bounded scanner — functions, class members, namespaces, templates | Bounded; bodyless declarations are not definitions |
343
321
  | C# (`.cs`) | dedicated brace-bounded scanner — methods, constructors, `class`/`interface`/`struct`/`record`/`enum` | Bounded; properties are not declarations |
344
322
  | 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 |
323
+ | Go (`.go`) | dedicated brace-bounded scanner — functions, methods, `type`/`struct`/`interface` | Bounded; methods carry their receiver type, interface methods are requirements, function literals inside a body are not seen |
324
+ | Rust (`.rs`) | dedicated brace-bounded scanner — functions, `impl` and `trait` members, `struct`/`enum`/`trait`/`union` | Bounded; methods carry the type their `impl` names, trait requirements mint nothing, closures and macro bodies are not read |
325
+ | PHP (`.php`, `.phtml`) | dedicated brace-bounded scanner — functions, methods, `class`/`interface`/`trait`/`enum`; markup outside `<?php` is blanked | Bounded; methods carry their class, bodyless members mint nothing, heredoc bodies are not masked |
326
+ | Ruby (`.rb`, `.rake`, `.gemspec`) | dedicated scanner — methods, classes and modules bounded by `end`, counted by openers | Bounded by depth; methods carry their class, blocks and modifier forms discounted, metaprogrammed methods are not seen |
345
327
  | 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 |
346
328
  | 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 |
347
329
  | 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 |
@@ -349,7 +331,7 @@ these:
349
331
  | HTML (`.html`) | same brace scanner (inline `<script>`) | Bounded |
350
332
  | TypeScript (semantic) | a recorded analysis or a locally-installed `tsc`, workspace projects included | Type-level facts; `unknown` when no checker is present |
351
333
 
352
- Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin, and the rest —
334
+ Any language **not** in that table — Kotlin, Scala, Elixir, Zig, and the rest —
353
335
  is **not parsed for declarations by the built-in scanner.** Its files still count
354
336
  toward repo size, but the built-ins produce no function-size, complexity,
355
337
  duplication or dead-code findings for them, and the estimate leans on whatever
@@ -384,54 +366,33 @@ report — so a payload cap can never truncate the prompt.
384
366
 
385
367
  ## Scoring standard
386
368
 
387
- Based on ISO/IEC 25010 maintainability — modularity, reusability,
388
- analyzability, modifiability, testability. Scores are **rates calibrated
389
- against real code**, not counts: every pressure is normalized against the
390
- median a pinned 112-repo corpus of mature projects actually carries —
391
- eight of the ten parsed languages (django, angular, spring-framework,
392
- ghidra, LAPACK, …); Swift and COBOL are parsed but unanchored. How that corpus was selected, what each language actually
393
- reads, and what the numbers do *not* establish:
394
- [the calibration study](docs/calibration-2.0-study.md), so `2.5x` means
395
- "two and a half times what well-maintained real code shows." The corpus median
396
- earns a **B**; **A+ is gated**, requiring every dimension clean.
397
-
398
- The corpus is **selected by query, not taste** — `stars:>3000
399
- created:<2021-01-01 pushed:>2026-01-01` across Python, TypeScript and
400
- JavaScript, then filtered to repositories that contain code. The calibration is
401
- reproducible, not asserted: `python3 tools/calibration/measure.py --check`
402
- re-measures and fails on drift, and `tests/test_calibration_corpus.py`
403
- re-derives the constants offline from checked-in measurements. See
404
- [docs/standard.md](docs/standard.md).
369
+ One rubric, applied uniformly, published in full at
370
+ [docs/standard.md](docs/standard.md): the aspects, their weights, the
371
+ calibration method, and the reference corpus. A score is withheld rather than
372
+ guessed when the evidence does not support one, and the report says which tier
373
+ the evidence came from.
405
374
 
406
375
  ## Self-audit
407
376
 
408
- This repo eats its own dogfood — the tool runs against this codebase in CI, and
409
- a report is checked in at [docs/self-audit.md](docs/self-audit.md), **stamped
410
- with the exact source commit it was generated against** (a provenance record,
411
- not a claim about HEAD). These figures mirror that stamped report row for row:
377
+ The tool runs against this codebase in CI, and the report is checked in at
378
+ [docs/self-audit.md](docs/self-audit.md), stamped with the exact source commit
379
+ it was generated against — a provenance record, not a claim about HEAD.
412
380
 
413
381
  | Metric | Value |
414
382
  |---|---:|
415
- | Maintainability estimate | 4.1 / 5 |
383
+ | Maintainability estimate | 4.2 / 5 |
416
384
  | Verified grade | B |
417
- | Files scanned | 391 |
418
- | File warnings | 120 |
419
- | File failures | 0 |
420
- | Function warnings | 65 |
421
- | Function failures | 0 |
422
- | Duplicate blocks | 0 |
423
- | Risk findings | 0 |
385
+ | Files scanned | 476 |
424
386
  | Hard gate failures | 0 |
425
387
 
426
- Yes, a **B** — demoted from the A band because warning rates exceed the
427
- A-grade ceilings, against thresholds this repo sets stricter than the shipped
428
- defaults. The grade is gated (A+ needs every dimension clean; a
429
- repo with production code and zero test files cannot earn an A-grade) and banded
430
- from the evidence floor, so withholding evidence never buys a better letter.
431
- Every threshold gate — file, function, duplication — is opted **on** for this
432
- repo's own CI, so drifting below the bar fails the build rather than the README.
433
- (CI note: `actions/checkout` defaults to `fetch-depth: 1`, which hides history
434
- and costs roughly a grade — use `fetch-depth: 0`.)
388
+ A **B**, and the report says why: the grade is verified against the evidence
389
+ *floor* of 4.1 rather than the 4.2 point estimate, because an unmeasured aspect
390
+ prices at 0 when a grade has to be defended; and testability is capped at 4.0 by
391
+ an unpaired production unit in the fail band. Those are measured against
392
+ thresholds this repo sets stricter than the shipped defaults, and every threshold
393
+ gate is opted **on** for its own CI, so drifting below the bar fails the build
394
+ rather than the README. The full stamped table — warnings, duplication, risk
395
+ findings — is in the report itself.
435
396
 
436
397
  ## Platform support
437
398
 
@@ -5,11 +5,18 @@
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.10.0**.
9
-
10
- **Languages parsed:** Python, Java, C, C++, C#, Swift, Fortran (free-form
11
- *and* fixed-form), and the JS/TS family — each by a scanner written for it, and
12
- measured with that language's own reading of what a branch is.
8
+ Version **2.11.2**.
9
+
10
+ **Planned, not shipped:** the audit tool will become `maintainability-audit`;
11
+ a new `maintainability-agent` companion will run it and automate human-selected
12
+ work orders within the user's agent chat. The installation commands below
13
+ still describe the current product. See the [planned split](docs/product-intent.md#planned-product-split-and-companion-workflow).
14
+
15
+ **Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
16
+ COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
17
+ by a scanner written for it, and measured with that language's own reading of
18
+ what a branch is, checked construct-by-construct against an independent
19
+ implementation.
13
20
  [What that means per language](#language-support).
14
21
 
15
22
  ```bash
@@ -64,50 +71,22 @@ differ.
64
71
 
65
72
  ## Why this exists
66
73
 
67
- The ratio of code-written to code-reviewed has collapsed. Unmaintainable code
68
- that used to accumulate over years can now accumulate in an afternoon:
69
- duplicated helpers, oversized files, speculative abstractions — the same slop
70
- hand-written codebases always accrued, now at machine speed.
71
-
72
- The same speed is the way out. An agent pointed at specific, deterministic
73
- findings can fix them at the rate they appear. The loop this tool closes:
74
-
75
- 1. **Measure** pressure points deterministically, with no LLM involved.
76
- 2. **Score** with one uniform standard, so the verdict is not a debate.
77
- 3. **Emit** a prompt scoped to *those findings only*, with explicit
78
- instructions not to refactor beyond them.
79
- 4. **Hand it to the agent.** Review a scoped diff instead of a speculative
80
- rewrite.
81
-
82
- Step 3 is the product; steps 1 and 2 are in service of it. Every other tool in
83
- this space stops at "here's a list of findings."
74
+ The ratio of code-written to code-reviewed has collapsed, and the same speed is
75
+ the way out: an agent pointed at specific, deterministic findings can fix them
76
+ at the rate they appear. The loop is **measure** with no model involved,
77
+ **score** against one uniform standard, **emit a prompt scoped to those findings
78
+ only**, and hand it over. Step three is the product.
84
79
 
85
80
  **Who does the checking matters as much as what it checks.** An author is never
86
81
  the independent check on their own work, so a platform that generates code and
87
- grades it is producing a self-assessment — a property of the arrangement, not a
88
- criticism of any one of them. This writes nothing and runs no model, which is
89
- what lets its verdict be evidence ([the principle](docs/philosophy.md#principles)).
90
- Since 2.1.0 the work order is also **checked**: `--conformance` compares the
91
- returned diff against the paths the report named, `--fail-on-regression`
92
- ratchets the dimension scores, and `--attestation-output` composes them into one
93
- record ([how that hole was closed](docs/roadmap.md#the-remediation-hole-closed-in-210-through-230)).
94
- The limit, stated in the same breath: those checks read the diff's **shape**,
95
- never its correctness — whether the change works is not a claim this tool makes.
96
-
97
- One pre-registered experiment has tested the bounded prompt.
98
- Generic prompting made 2 of 6 repositories worse; bounded prompting made 1 of 6 worse and improved 5 of 6, under this tool's own finding count.
99
- The *registered* hypothesis was narrower diffs, which did not hold, so the
100
- registered verdict stands at **INCONCLUSIVE**. Method, limits and raw data:
101
- [docs/studies.md](docs/studies.md#does-the-bounded-prompt-work-controlled-experiment-pre-registered).
102
-
103
- ### Who it's for
104
-
105
- - Teams running AI agents in the dev loop, tired of unbounded cleanup PRs, who
106
- want a CI gate that actively constrains follow-up scope.
107
- - Repos that want a maintainability gate without a SaaS analyzer or shipping
108
- code to a third party.
109
- - Solo devs who want a single deterministic audit to pin in a Makefile,
110
- pre-commit, or local CI script.
82
+ grades it is producing a self-assessment. This writes nothing and runs no model,
83
+ which is what lets its verdict count as evidence. Since 2.1.0 the work order is
84
+ itself checked — scope conformance, a dimension ratchet, and an attestation
85
+ record — and those checks read a diff's **shape**, never whether it works.
86
+
87
+ The full argument, including what this deliberately does not compete on:
88
+ [why this exists](docs/why-this-exists.md) and
89
+ [philosophy](docs/philosophy.md).
111
90
 
112
91
  ## The road to 1.0
113
92
 
@@ -186,8 +165,8 @@ withheld and the scope is named as the reason.
186
165
  ### Checking that the agent did the work
187
166
 
188
167
  The work order tells an agent to fix exactly these findings and refactor nothing
189
- else. These flags check that the diff obeyed it — they read its _shape_, not its
190
- correctness:
168
+ else. Four flags check that the diff obeyed it — reading its _shape_, never
169
+ whether it works:
191
170
 
192
171
  ```bash
193
172
  maintainability-agent \
@@ -198,30 +177,19 @@ maintainability-agent \
198
177
  --attestation-output maintainability-attestation.md
199
178
  ```
200
179
 
201
- - **`--conformance <revspec>`** compares the diff against the paths the report
202
- named, and answers two questions separately: did it **stay in scope**, and did
203
- it **silence nothing**. They stay separate because a change can obey the work
204
- order and still add a `# noqa` to a finding inside it. A test added for a fix
205
- stays in scope even though the work order never named the test file.
206
- - **`--fail-on-out-of-scope`** turns that into a CI failure.
207
- - **`--fail-on-regression`** ratchets the _dimension_ scores against scan
208
- history, catching a change that improves one dimension while silently
209
- regressing another. It has three outcomes, not two — held, regressed, and
210
- **not comparable**, because two scans taken under different calibration cannot
211
- be differenced.
212
- - **`--attestation-output`** writes the three into one per-change record: what
213
- was measured, what the agent was told to change, whether it stayed inside the
214
- work order, and what moved. It is reproducible and **not signed** — nothing
215
- here holds a key, and the document says so in its own text. A check nobody ran
216
- renders as _not asked_, never as passed.
217
- - **`--transformation NAME`** names the class of work a scan followed and
218
- reports how this run of it compares with earlier ones. **A report, never a
219
- gate.** It says one run "moved further" than another, never that it was
220
- _better_ — two runs of one codemod land on different code — and it measures
221
- the interval, not the transformation.
222
-
223
- The [roadmap](docs/roadmap.md#the-remediation-hole-closed-in-210-through-230)
224
- has the history of why this was the hole under the product's central claim.
180
+ `--conformance` answers two questions separately — did the diff **stay in
181
+ scope**, and did it **silence nothing** — because a change can obey the work
182
+ order and still add a `# noqa` to a finding inside it. `--fail-on-out-of-scope`
183
+ turns that into a CI failure. `--fail-on-regression` ratchets the _dimension_
184
+ scores against history, with three outcomes rather than two: held, regressed,
185
+ and **not comparable**, because two scans taken under different calibration
186
+ cannot be differenced. `--attestation-output` composes them into one per-change
187
+ record, reproducible and **not signed** — a check nobody ran renders as _not
188
+ asked_, never as passed.
189
+
190
+ Each flag in full, including `--transformation`:
191
+ [docs/cli.md](docs/cli.md). Why this was the hole under the product's central
192
+ claim: [the roadmap](docs/roadmap.md#the-remediation-hole-closed-in-210-through-230).
225
193
 
226
194
  ### During the loop, not only after it
227
195
 
@@ -236,10 +204,16 @@ maintainability-agent --install-precommit-hook # before committing
236
204
 
237
205
  **`--check PATH`** answers about content on stdin. No repository, no git, no
238
206
  scan; `PATH` names the content and is never opened. Pass file content, not a
239
- diff — content that does not parse says so rather than reading as clean, as
240
- does a language with no scanner. In text it is **silent while you have room**
241
- and speaks once a declaration nears its limit; `--format json` carries the
242
- remaining budget for every declaration whether or not it is close.
207
+ diff — **a piped diff is refused in every language**, by its format rather
208
+ than by a parser, and says so rather than reading as clean; so does a
209
+ language with no scanner. Beyond that, only Python's content is parsed:
210
+ a brace language's invalid source is not detected, because zero
211
+ declarations is not evidence of a parse failure and marking valid files
212
+ unparsed would be worse than the silence. In text it is **silent while you have room**
213
+ and speaks once a declaration nears its limit — on *any* budget it can be
214
+ failed on, length or cyclomatic or cognitive, not length alone.
215
+ `--format json` carries the remaining budget for every declaration whether
216
+ or not it is close, per budget rather than as one number.
243
217
 
244
218
  **`--staged`** scans the git index. Stage half a file with `git add -p`, keep
245
219
  typing, and what gets measured is what the commit will actually contain —
@@ -258,9 +232,12 @@ The deterministic scanner reads code from your repo (no LLM calls) and produces
258
232
  signals on:
259
233
 
260
234
  - largest files (configurable warn/fail thresholds)
261
- - function size and complexity — exact ranges for Python via `ast`,
262
- brace-bounded for JS/TS/JSX/TSX/HTML — plus **cognitive complexity**
263
- (nesting-weighted reading cost)
235
+ - function size and complexity — exact ranges for Python via `ast`, and
236
+ bounded ranges for every other parsed language, each measured with that
237
+ language's own reading of what a branch is ([Language
238
+ support](#language-support) is the list, so this sentence cannot drift
239
+ out of step with it) — plus **cognitive complexity** (nesting-weighted
240
+ reading cost)
264
241
  - class size, against its own budget (`max_class_lines`)
265
242
  - duplicate blocks, and **near-duplicate declarations** compared structurally so
266
243
  renaming can't hide a copy, each paired with the original to reuse
@@ -286,9 +263,9 @@ SonarQube, Qlty) rather than replacing them — their SARIF folds in via
286
263
  **Be clear-eyed: the tool does not support every language equally, and on an
287
264
  unrecognized language it under-reports rather than fails.** Coverage has two layers.
288
265
 
289
- Ten languages are parsed as of **2.7.0**: Python (1.0), Java (1.0), C (1.1),
266
+ Fourteen languages are parsed as of **2.11.0**: Python (1.0), Java (1.0), C (1.1),
290
267
  C++ (1.2), C# (1.3), Fortran (free-form 1.4, fixed-form 1.6), Swift (2.4),
291
- COBOL (2.7), the JS/TS family, and HTML. Each has a scanner written for it and a
268
+ COBOL (2.7), Go (2.11), Rust (2.11), PHP (2.11), Ruby (2.11), the JS/TS family, and HTML. Each has a scanner written for it and a
292
269
  documented list of what it misses — a language is claimed only when both exist.
293
270
 
294
271
  **Built-in scanner (always on, no dependencies)** — reads function/class
@@ -303,6 +280,10 @@ these:
303
280
  | C++ (`.cpp`, `.hpp`, `.cc`, `.cxx`, `.hh`) | dedicated brace-bounded scanner — functions, class members, namespaces, templates | Bounded; bodyless declarations are not definitions |
304
281
  | C# (`.cs`) | dedicated brace-bounded scanner — methods, constructors, `class`/`interface`/`struct`/`record`/`enum` | Bounded; properties are not declarations |
305
282
  | 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 |
283
+ | Go (`.go`) | dedicated brace-bounded scanner — functions, methods, `type`/`struct`/`interface` | Bounded; methods carry their receiver type, interface methods are requirements, function literals inside a body are not seen |
284
+ | Rust (`.rs`) | dedicated brace-bounded scanner — functions, `impl` and `trait` members, `struct`/`enum`/`trait`/`union` | Bounded; methods carry the type their `impl` names, trait requirements mint nothing, closures and macro bodies are not read |
285
+ | PHP (`.php`, `.phtml`) | dedicated brace-bounded scanner — functions, methods, `class`/`interface`/`trait`/`enum`; markup outside `<?php` is blanked | Bounded; methods carry their class, bodyless members mint nothing, heredoc bodies are not masked |
286
+ | Ruby (`.rb`, `.rake`, `.gemspec`) | dedicated scanner — methods, classes and modules bounded by `end`, counted by openers | Bounded by depth; methods carry their class, blocks and modifier forms discounted, metaprogrammed methods are not seen |
306
287
  | 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 |
307
288
  | 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 |
308
289
  | 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 |
@@ -310,7 +291,7 @@ these:
310
291
  | HTML (`.html`) | same brace scanner (inline `<script>`) | Bounded |
311
292
  | TypeScript (semantic) | a recorded analysis or a locally-installed `tsc`, workspace projects included | Type-level facts; `unknown` when no checker is present |
312
293
 
313
- Any language **not** in that table — Go, Rust, Ruby, PHP, Kotlin, and the rest —
294
+ Any language **not** in that table — Kotlin, Scala, Elixir, Zig, and the rest —
314
295
  is **not parsed for declarations by the built-in scanner.** Its files still count
315
296
  toward repo size, but the built-ins produce no function-size, complexity,
316
297
  duplication or dead-code findings for them, and the estimate leans on whatever
@@ -345,54 +326,33 @@ report — so a payload cap can never truncate the prompt.
345
326
 
346
327
  ## Scoring standard
347
328
 
348
- Based on ISO/IEC 25010 maintainability — modularity, reusability,
349
- analyzability, modifiability, testability. Scores are **rates calibrated
350
- against real code**, not counts: every pressure is normalized against the
351
- median a pinned 112-repo corpus of mature projects actually carries —
352
- eight of the ten parsed languages (django, angular, spring-framework,
353
- ghidra, LAPACK, …); Swift and COBOL are parsed but unanchored. How that corpus was selected, what each language actually
354
- reads, and what the numbers do *not* establish:
355
- [the calibration study](docs/calibration-2.0-study.md), so `2.5x` means
356
- "two and a half times what well-maintained real code shows." The corpus median
357
- earns a **B**; **A+ is gated**, requiring every dimension clean.
358
-
359
- The corpus is **selected by query, not taste** — `stars:>3000
360
- created:<2021-01-01 pushed:>2026-01-01` across Python, TypeScript and
361
- JavaScript, then filtered to repositories that contain code. The calibration is
362
- reproducible, not asserted: `python3 tools/calibration/measure.py --check`
363
- re-measures and fails on drift, and `tests/test_calibration_corpus.py`
364
- re-derives the constants offline from checked-in measurements. See
365
- [docs/standard.md](docs/standard.md).
329
+ One rubric, applied uniformly, published in full at
330
+ [docs/standard.md](docs/standard.md): the aspects, their weights, the
331
+ calibration method, and the reference corpus. A score is withheld rather than
332
+ guessed when the evidence does not support one, and the report says which tier
333
+ the evidence came from.
366
334
 
367
335
  ## Self-audit
368
336
 
369
- This repo eats its own dogfood — the tool runs against this codebase in CI, and
370
- a report is checked in at [docs/self-audit.md](docs/self-audit.md), **stamped
371
- with the exact source commit it was generated against** (a provenance record,
372
- not a claim about HEAD). These figures mirror that stamped report row for row:
337
+ The tool runs against this codebase in CI, and the report is checked in at
338
+ [docs/self-audit.md](docs/self-audit.md), stamped with the exact source commit
339
+ it was generated against — a provenance record, not a claim about HEAD.
373
340
 
374
341
  | Metric | Value |
375
342
  |---|---:|
376
- | Maintainability estimate | 4.1 / 5 |
343
+ | Maintainability estimate | 4.2 / 5 |
377
344
  | Verified grade | B |
378
- | Files scanned | 391 |
379
- | File warnings | 120 |
380
- | File failures | 0 |
381
- | Function warnings | 65 |
382
- | Function failures | 0 |
383
- | Duplicate blocks | 0 |
384
- | Risk findings | 0 |
345
+ | Files scanned | 476 |
385
346
  | Hard gate failures | 0 |
386
347
 
387
- Yes, a **B** — demoted from the A band because warning rates exceed the
388
- A-grade ceilings, against thresholds this repo sets stricter than the shipped
389
- defaults. The grade is gated (A+ needs every dimension clean; a
390
- repo with production code and zero test files cannot earn an A-grade) and banded
391
- from the evidence floor, so withholding evidence never buys a better letter.
392
- Every threshold gate — file, function, duplication — is opted **on** for this
393
- repo's own CI, so drifting below the bar fails the build rather than the README.
394
- (CI note: `actions/checkout` defaults to `fetch-depth: 1`, which hides history
395
- and costs roughly a grade — use `fetch-depth: 0`.)
348
+ A **B**, and the report says why: the grade is verified against the evidence
349
+ *floor* of 4.1 rather than the 4.2 point estimate, because an unmeasured aspect
350
+ prices at 0 when a grade has to be defended; and testability is capped at 4.0 by
351
+ an unpaired production unit in the fail band. Those are measured against
352
+ thresholds this repo sets stricter than the shipped defaults, and every threshold
353
+ gate is opted **on** for its own CI, so drifting below the bar fails the build
354
+ rather than the README. The full stamped table — warnings, duplication, risk
355
+ findings — is in the report itself.
396
356
 
397
357
  ## Platform support
398
358