maintainability-agent 3.4.0__tar.gz → 3.6.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 (381) hide show
  1. {maintainability_agent-3.4.0/src/maintainability_agent.egg-info → maintainability_agent-3.6.0}/PKG-INFO +59 -25
  2. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/README.md +57 -24
  3. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/pyproject.toml +2 -2
  4. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0/src/maintainability_agent.egg-info}/PKG-INFO +59 -25
  5. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_agent.egg-info/SOURCES.txt +5 -0
  6. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_agent.egg-info/requires.txt +1 -0
  7. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/__init__.py +1 -1
  8. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_prompt_sections.py +50 -5
  9. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_scan_history.py +37 -14
  10. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_work_order.py +74 -2
  11. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/cli.py +71 -10
  12. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/config.py +1 -1
  13. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/mcp_server.py +7 -3
  14. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/prompts.py +20 -3
  15. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/renderers.py +49 -13
  16. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_backfill.py +1 -1
  17. maintainability_agent-3.6.0/tests/test_chat_leads_with_the_work_order.py +171 -0
  18. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_child_sandbox.py +1 -1
  19. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_ci_installs_the_analyzer_pool.py +48 -0
  20. maintainability_agent-3.6.0/tests/test_demo_tree.py +172 -0
  21. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_determinism.py +1 -1
  22. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_dimension_ratchet.py +1 -1
  23. maintainability_agent-3.6.0/tests/test_example_config_opens_claimed_languages.py +57 -0
  24. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_finding_identity.py +56 -0
  25. maintainability_agent-3.6.0/tests/test_mcp_format_contract.py +81 -0
  26. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_operator_named_reads.py +15 -0
  27. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_platform_claim.py +9 -1
  28. maintainability_agent-3.6.0/tests/test_prompt_does_not_issue_rates_when_unscored.py +53 -0
  29. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_prove_falsifiers.py +59 -0
  30. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_recurrence.py +1 -1
  31. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_run_comparison.py +9 -3
  32. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_scan_history.py +54 -4
  33. maintainability_agent-3.6.0/tests/test_stdout_outputs.py +130 -0
  34. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_trends.py +1 -1
  35. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_write_boundary.py +1 -1
  36. maintainability_agent-3.4.0/tests/test_mcp_format_contract.py +0 -22
  37. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/LICENSE +0 -0
  38. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/setup.cfg +0 -0
  39. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
  40. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
  41. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_agent.egg-info/top_level.txt +0 -0
  42. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/__main__.py +0 -0
  43. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_adapters.py +0 -0
  44. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_analysis.py +0 -0
  45. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_analyzer_sections.py +0 -0
  46. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_anchor.py +0 -0
  47. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_arguments.py +0 -0
  48. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_aspects.py +0 -0
  49. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
  50. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_assets/standard.md +0 -0
  51. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_attestation.py +0 -0
  52. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_backfill.py +0 -0
  53. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_bands.py +0 -0
  54. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_banner.py +0 -0
  55. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_built_ins.py +0 -0
  56. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_calibration.py +0 -0
  57. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_catalog.py +0 -0
  58. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_charts.py +0 -0
  59. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_cognitive.py +0 -0
  60. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_config_defaults.py +0 -0
  61. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_conformance.py +0 -0
  62. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_corroborate.py +0 -0
  63. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_coverage_notes.py +0 -0
  64. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_criteria_scope.py +0 -0
  65. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_delegated_pillar.py +0 -0
  66. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_derive.py +0 -0
  67. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_discovery.py +0 -0
  68. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_documents.py +0 -0
  69. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_economics.py +0 -0
  70. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_economics_view.py +0 -0
  71. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_environment.py +0 -0
  72. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_evidence_reader.py +0 -0
  73. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_evidence_view.py +0 -0
  74. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_finding_match.py +0 -0
  75. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_first_run.py +0 -0
  76. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_formula.py +0 -0
  77. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_gates.py +0 -0
  78. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_generic.py +0 -0
  79. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_grammar.py +0 -0
  80. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_grant_ledger.py +0 -0
  81. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_history_view.py +0 -0
  82. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_hostile_prompt.py +0 -0
  83. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_hotspots.py +0 -0
  84. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_html_report_sections.py +0 -0
  85. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_html_view.py +0 -0
  86. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_identity.py +0 -0
  87. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_in_loop.py +0 -0
  88. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_in_loop_view.py +0 -0
  89. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_jvm_adapters.py +0 -0
  90. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_markdown_sections.py +0 -0
  91. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_masking.py +0 -0
  92. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_mcp_audit.py +0 -0
  93. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_mcp_gate.py +0 -0
  94. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_mcp_grants.py +0 -0
  95. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_mcp_refusals.py +0 -0
  96. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_mcp_resources.py +0 -0
  97. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_mcp_setup.py +0 -0
  98. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_metric_adapters.py +0 -0
  99. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_metrics_types.py +0 -0
  100. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_operator_reads.py +0 -0
  101. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_pillars.py +0 -0
  102. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_practice.py +0 -0
  103. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_precommit.py +0 -0
  104. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_precommit_install.py +0 -0
  105. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_precommit_view.py +0 -0
  106. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_pressures.py +0 -0
  107. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_c.py +0 -0
  108. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_cobol.py +0 -0
  109. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_core.py +0 -0
  110. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_cpp.py +0 -0
  111. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_csharp.py +0 -0
  112. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_fortran.py +0 -0
  113. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_go.py +0 -0
  114. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_java.py +0 -0
  115. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_js.py +0 -0
  116. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_php.py +0 -0
  117. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_ruby.py +0 -0
  118. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_rust.py +0 -0
  119. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ranges_swift.py +0 -0
  120. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ratchet.py +0 -0
  121. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_ratio_adapters.py +0 -0
  122. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_recurrence.py +0 -0
  123. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_run_comparison.py +0 -0
  124. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_runner.py +0 -0
  125. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_safe_write.py +0 -0
  126. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_scan_view.py +0 -0
  127. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_second_source.py +0 -0
  128. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_selection.py +0 -0
  129. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_semantic.py +0 -0
  130. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_semantic_policy.py +0 -0
  131. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_semantic_ts.py +0 -0
  132. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_semantic_view.py +0 -0
  133. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_setup_errors.py +0 -0
  134. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_setup_persist.py +0 -0
  135. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
  136. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
  137. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
  138. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
  139. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
  140. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
  141. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_skill_install.py +0 -0
  142. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_stored_grants.py +0 -0
  143. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_tdd_view.py +0 -0
  144. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_test_commands.py +0 -0
  145. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_test_execution.py +0 -0
  146. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_test_pairing.py +0 -0
  147. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_tokens.py +0 -0
  148. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_tool_adapters.py +0 -0
  149. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_trends.py +0 -0
  150. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_user_config.py +0 -0
  151. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_verdict_adapters.py +0 -0
  152. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_verification.py +0 -0
  153. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_work_order_view.py +0 -0
  154. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_work_order_weights.py +0 -0
  155. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/_xml.py +0 -0
  156. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/baseline.py +0 -0
  157. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/deadcode.py +0 -0
  158. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/declarations.py +0 -0
  159. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/duplication.py +0 -0
  160. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/evidence.py +0 -0
  161. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/git_tools.py +0 -0
  162. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/history.py +0 -0
  163. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/idioms.py +0 -0
  164. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/instructions.py +0 -0
  165. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/metrics.py +0 -0
  166. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/report.py +0 -0
  167. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/sarif.py +0 -0
  168. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/scoring.py +0 -0
  169. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/similarity.py +0 -0
  170. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/src/maintainability_audit/source.py +0 -0
  171. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_acquisition_trust.py +0 -0
  172. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_adapter_docs.py +0 -0
  173. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_adapter_recordings.py +0 -0
  174. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_adapters.py +0 -0
  175. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_added_lines.py +0 -0
  176. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analysis_coverage.py +0 -0
  177. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analysis_execution.py +0 -0
  178. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_bridge.py +0 -0
  179. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_config_isolation.py +0 -0
  180. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_estimate_claims.py +0 -0
  181. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_pinning.py +0 -0
  182. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_primary_estimate.py +0 -0
  183. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_provenance.py +0 -0
  184. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_provenance_exclusions.py +0 -0
  185. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_scoring_path.py +0 -0
  186. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_spread_range.py +0 -0
  187. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_analyzer_xml_bounds.py +0 -0
  188. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_anchor_and_mode.py +0 -0
  189. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_anchor_disclosure.py +0 -0
  190. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_annotations_match_behaviour.py +0 -0
  191. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_anticipated_refusals.py +0 -0
  192. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_architecture.py +0 -0
  193. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_artifact_write_route_class.py +0 -0
  194. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_aspect_coverage.py +0 -0
  195. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_asset_snapshot_class.py +0 -0
  196. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_ast_reading_resolves_spellings.py +0 -0
  197. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_attestation.py +0 -0
  198. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_audit_components.py +0 -0
  199. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_authorization_freshness.py +0 -0
  200. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_authorship_gates.py +0 -0
  201. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_band_concealment_class.py +0 -0
  202. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_band_concealment_p3.py +0 -0
  203. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_band_pressures.py +0 -0
  204. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_bands.py +0 -0
  205. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_body_or_signature_class.py +0 -0
  206. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_c_declarations.py +0 -0
  207. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_calibration_corpus.py +0 -0
  208. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_calibration_drift.py +0 -0
  209. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_calibration_tooling.py +0 -0
  210. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_catalog_selection.py +0 -0
  211. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_catalog_tier_promise.py +0 -0
  212. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_chat_primary_docs.py +0 -0
  213. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_check_refuses_plus_only_fragments.py +0 -0
  214. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_checkstyle_adapter.py +0 -0
  215. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_checkstyle_catalog.py +0 -0
  216. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_ci_history_recipe.py +0 -0
  217. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_claimed_languages.py +0 -0
  218. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_cli.py +0 -0
  219. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_clone_group_class.py +0 -0
  220. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_cobol_declarations.py +0 -0
  221. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_cognitive_complexity.py +0 -0
  222. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_cohort_statistics.py +0 -0
  223. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_concealment_properties.py +0 -0
  224. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_config_shape.py +0 -0
  225. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_consent_and_grant.py +0 -0
  226. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_consumer_migration.py +0 -0
  227. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_contract_claims.py +0 -0
  228. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_corroborate.py +0 -0
  229. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_coverage_by_language.py +0 -0
  230. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_cpp_declarations.py +0 -0
  231. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_criteria_completion.py +0 -0
  232. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_csharp_declarations.py +0 -0
  233. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_d15_composition.py +0 -0
  234. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_d15_goal_directed.py +0 -0
  235. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_dead_code.py +0 -0
  236. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_declaration_criteria_scope.py +0 -0
  237. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_declaration_edge_cases.py +0 -0
  238. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_declaration_grading.py +0 -0
  239. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_declaration_ranges.py +0 -0
  240. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_declaration_source.py +0 -0
  241. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_declarative_parsers.py +0 -0
  242. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_declared_authorship.py +0 -0
  243. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_declared_imports.py +0 -0
  244. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_delegated_security_pillar.py +0 -0
  245. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_derivation_mix.py +0 -0
  246. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_direct_runner_availability_class.py +0 -0
  247. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_discovery.py +0 -0
  248. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_doc_claims.py +0 -0
  249. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_docs_links.py +0 -0
  250. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_economic_context.py +0 -0
  251. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_empty_output_not_clean.py +0 -0
  252. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_empty_output_not_clean_adapters.py +0 -0
  253. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_environment_work_order.py +0 -0
  254. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_evidence_invariants.py +0 -0
  255. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_evidence_normalization.py +0 -0
  256. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_evidence_properties.py +0 -0
  257. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_exclusion_dialects.py +0 -0
  258. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_falsifier_standard.py +0 -0
  259. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_file_list_cap_class.py +0 -0
  260. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_first_run_elicitation.py +0 -0
  261. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_first_run_prompt.py +0 -0
  262. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_first_run_reelicitation.py +0 -0
  263. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_fix_breadth_window.py +0 -0
  264. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_fixed_form_fortran.py +0 -0
  265. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_format_ask.py +0 -0
  266. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_fortran_declarations.py +0 -0
  267. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_fortran_metrics.py +0 -0
  268. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_fortran_practice.py +0 -0
  269. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_git_argv.py +0 -0
  270. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_git_read_only.py +0 -0
  271. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_git_readonly_class.py +0 -0
  272. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_go_declarations.py +0 -0
  273. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_grammar_constructs.py +0 -0
  274. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_grammar_token_coverage.py +0 -0
  275. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_grant_only_user_tier.py +0 -0
  276. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_history.py +0 -0
  277. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_history_boundary.py +0 -0
  278. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_history_manifest.py +0 -0
  279. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_history_schema2.py +0 -0
  280. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_history_window.py +0 -0
  281. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_hostile_prompt.py +0 -0
  282. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_html_executive.py +0 -0
  283. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_html_section_parity_class.py +0 -0
  284. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_identity_docs.py +0 -0
  285. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_identity_resolution.py +0 -0
  286. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_idiom_divergence.py +0 -0
  287. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_in_loop_budgets.py +0 -0
  288. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_in_loop_check.py +0 -0
  289. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_installed_wheel_runtime.py +0 -0
  290. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_instruction_targets.py +0 -0
  291. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_java_range_guard.py +0 -0
  292. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_java_ranges.py +0 -0
  293. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_java_scored.py +0 -0
  294. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_java_wiring.py +0 -0
  295. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_js_complexity_operators.py +0 -0
  296. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_js_declarations.py +0 -0
  297. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_language_coverage.py +0 -0
  298. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_language_support_honesty.py +0 -0
  299. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_mcp_baseline_payload.py +0 -0
  300. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_mcp_history.py +0 -0
  301. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_mcp_server.py +0 -0
  302. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_migration_1_0.py +0 -0
  303. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_near_duplicates.py +0 -0
  304. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_network_disclosure.py +0 -0
  305. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_one_setup_across_surfaces_class.py +0 -0
  306. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_operator_named_paths.py +0 -0
  307. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_pairing_reads_imports.py +0 -0
  308. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_pattern_budget.py +0 -0
  309. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_phase6_claims.py +0 -0
  310. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_php_declarations.py +0 -0
  311. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_pillars_and_practice.py +0 -0
  312. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_pmd_adapter.py +0 -0
  313. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_pmd_audit_closures.py +0 -0
  314. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_policy_claims.py +0 -0
  315. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_pool_runs_by_config.py +0 -0
  316. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_population_floors.py +0 -0
  317. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_practice_nested_gates_class.py +0 -0
  318. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_precommit_staged.py +0 -0
  319. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_presentation_refusals.py +0 -0
  320. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_promises.py +0 -0
  321. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_prompt_escalation_once.py +0 -0
  322. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_prompt_honesty.py +0 -0
  323. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_prompt_location_escalation_class.py +0 -0
  324. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_python_complexity.py +0 -0
  325. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_python_declarations.py +0 -0
  326. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_read_boundary.py +0 -0
  327. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_readme_claims.py +0 -0
  328. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_release_needs_an_empty_ledger.py +0 -0
  329. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_release_plan.py +0 -0
  330. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_release_plan_status.py +0 -0
  331. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_report_remedy_copy.py +0 -0
  332. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_roles_recorded.py +0 -0
  333. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_root_grants.py +0 -0
  334. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_rubric_ignores_project_lint_config.py +0 -0
  335. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_ruby_declarations.py +0 -0
  336. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_runner.py +0 -0
  337. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_rust_declarations.py +0 -0
  338. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_sarif.py +0 -0
  339. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_scan_scope.py +0 -0
  340. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_scanner_unsafe_direction.py +0 -0
  341. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_scanning.py +0 -0
  342. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_schema_fidelity.py +0 -0
  343. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_scope_conformance.py +0 -0
  344. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_scoring_calibration.py +0 -0
  345. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_semantic_policy.py +0 -0
  346. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_setup_gate_completeness.py +0 -0
  347. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_setup_gate_independent_contract.py +0 -0
  348. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_setup_precondition.py +0 -0
  349. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_skill_install.py +0 -0
  350. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_sonar_resolve.py +0 -0
  351. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_source_index.py +0 -0
  352. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_spotbugs_adapter.py +0 -0
  353. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_spotbugs_catalog.py +0 -0
  354. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_stage8_contract.py +0 -0
  355. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_suite_isolation.py +0 -0
  356. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_swift_declarations.py +0 -0
  357. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_tdd_structure.py +0 -0
  358. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_terminal_asks_the_same_questions.py +0 -0
  359. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_test_commands.py +0 -0
  360. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_test_execution_class.py +0 -0
  361. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_three_presentations.py +0 -0
  362. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_tool_resolution.py +0 -0
  363. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
  364. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_tree_chosen_spawn.py +0 -0
  365. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_tree_reads_use_the_primitive.py +0 -0
  366. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_type_fields_not_functions_class.py +0 -0
  367. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_uat_falsifiers.py +0 -0
  368. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_unanchored_set_matches_corpus.py +0 -0
  369. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_unread_code.py +0 -0
  370. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_user_config_tier.py +0 -0
  371. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_verification_audit_closures.py +0 -0
  372. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_verified_grade.py +0 -0
  373. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_version_claim.py +0 -0
  374. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_wheel_contents.py +0 -0
  375. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_work_order.py +0 -0
  376. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
  377. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_work_order_items.py +0 -0
  378. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_work_order_selection.py +0 -0
  379. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_workflow_supply_chain.py +0 -0
  380. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_write_route_class.py +0 -0
  381. {maintainability_agent-3.4.0 → maintainability_agent-3.6.0}/tests/test_written_record.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maintainability-agent
3
- Version: 3.4.0
3
+ Version: 3.6.0
4
4
  Summary: Maintainability gate and AI remediation prompt generator for CI.
5
5
  Author: Marshall Guillory
6
6
  License: MIT
@@ -29,6 +29,7 @@ Requires-Dist: mcp<3,>=2; extra == "mcp"
29
29
  Provides-Extra: dev
30
30
  Requires-Dist: pytest>=8; extra == "dev"
31
31
  Requires-Dist: pytest-cov>=5; extra == "dev"
32
+ Requires-Dist: pytest-xdist>=3.6; extra == "dev"
32
33
  Requires-Dist: jsonschema>=4; extra == "dev"
33
34
  Requires-Dist: ruff>=0.5; extra == "dev"
34
35
  Requires-Dist: pip-audit>=2.7; extra == "dev"
@@ -45,12 +46,7 @@ Dynamic: license-file
45
46
  **A deterministic, offline maintainability audit whose output is a _bounded
46
47
  work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
47
48
  says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
48
- Version **3.4.0**.
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).
49
+ Version **3.6.0**.
54
50
 
55
51
  **Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
56
52
  COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
@@ -65,6 +61,51 @@ pip install "maintainability-agent[mcp]" # optional local MCP server for chat
65
61
  cp -r skills/maintainability-agent ~/.claude/skills/ # Claude Code slash command
66
62
  ```
67
63
 
64
+ **Install the analyzer pool too, or you get the built-in tier.** This tool
65
+ prefers established analyzers and falls back to its own detectors when none is
66
+ present. The fallback is honest — the report says `Estimate source: built-in
67
+ detectors` and the coverage section names what nothing examined — but it is a
68
+ weaker reading than the tool is capable of, and a first run without these is
69
+ the commonest reason it looks thin.
70
+
71
+ ```bash
72
+ pip install cohesion complexipy flake8 fortitude-lint interrogate lizard \
73
+ multimetric mypy pydocstyle pylint radon ruff vulture
74
+ npm install -g jscpd eslint # duplication + JavaScript/TypeScript
75
+ brew install pmd checkstyle spotbugs # JVM languages, optional
76
+ ```
77
+
78
+ Unpinned on purpose: this is the exact set CI installs and calibrates against,
79
+ and `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
80
+ disagree. Nothing here is required — the audit runs without any of it and tells
81
+ you what it could not measure.
82
+
83
+ **One command to a work order.** A config file is the whole setup — with one
84
+ present, nothing is asked and nothing is written into your tree:
85
+
86
+ ```bash
87
+ curl -O https://raw.githubusercontent.com/marshallguillory86/maintainability-agent/main/maintainability-audit.example.json
88
+ maintainability-audit --config maintainability-audit.example.json \
89
+ --output report.md --prompt-output prompt.md
90
+ ```
91
+
92
+ `prompt.md` is the bounded work order: the findings worth fixing, in order,
93
+ each with its location, why it matters and the command that verifies it — and
94
+ the standing rule that nothing else gets refactored. Paste it into your agent.
95
+ `report.md` is the evidence behind it. The prompt is the product.
96
+
97
+ **Want to see the output before pointing it at your own code?**
98
+ [`examples/demo`](examples/demo/) is a two-module order system with real
99
+ problems in it — an overgrown pricing function, a money path nothing tests, and
100
+ a block duplicated between billing and invoicing. Four items, three finding
101
+ classes, a copy-paste prompt each, and it reads in under a minute. The work
102
+ order it produces is checked in at
103
+ [`expected-prompt.md`](examples/demo/expected-prompt.md).
104
+
105
+ Without `--config`, an interactive run asks the first-run questions instead —
106
+ analyzer pool, depth, licence policy, whether to run your suite — because those
107
+ are choices this tool will not make on your behalf.
108
+
68
109
  ---
69
110
 
70
111
  ## Executive summary
@@ -128,15 +169,6 @@ The full argument, including what this deliberately does not compete on:
128
169
  [why this exists](docs/why-this-exists.md) and
129
170
  [philosophy](docs/philosophy.md).
130
171
 
131
- ## The road to 1.0
132
-
133
- 1.0 was the line drawn under a long arc of **subtraction** — what remained after
134
- every claim the project could not stand behind was removed. A scoring engine
135
- rebuilt after it was found to grade repo *size*; a headline claim about AI
136
- authorship retracted against a matched control; a score that is withheld rather
137
- than guessed. That arc is the credibility, and it is recorded in full, with the
138
- figures quoted from their approved summaries, in [the track record](docs/track-record.md).
139
-
140
172
  ## Install
141
173
 
142
174
  ```bash
@@ -380,19 +412,21 @@ it was generated against — a provenance record, not a claim about HEAD.
380
412
 
381
413
  | Metric | Value |
382
414
  |---|---:|
383
- | Maintainability estimate | 4.2 / 5 |
415
+ | Maintainability estimate | 4.5 / 5 |
384
416
  | Verified grade | B |
385
- | Files scanned | 476 |
417
+ | Files scanned | 511 |
386
418
  | Hard gate failures | 0 |
387
419
 
388
420
  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.
421
+ *floor* of 4.2 rather than the 4.5 point estimate, because an unmeasured aspect
422
+ prices at 0 when a grade has to be defended. Every threshold gate is opted
423
+ **on** for this repository's own CI, so drifting below the bar fails the build
424
+ rather than the README.
425
+
426
+ The tool reports warn-band declarations here and they are not treated as
427
+ defects — see [what counts as a defect](docs/product-intent.md#what-counts-as-a-defect-and-what-does-not).
428
+ Restyling this codebase to raise its own grade is explicitly not work: a tool
429
+ that games its own metric has broken the only promise that matters.
396
430
 
397
431
  ## Platform support
398
432
 
@@ -5,12 +5,7 @@
5
5
  **A deterministic, offline maintainability audit whose output is a _bounded
6
6
  work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
7
7
  says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
8
- Version **3.4.0**.
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).
8
+ Version **3.6.0**.
14
9
 
15
10
  **Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
16
11
  COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
@@ -25,6 +20,51 @@ pip install "maintainability-agent[mcp]" # optional local MCP server for chat
25
20
  cp -r skills/maintainability-agent ~/.claude/skills/ # Claude Code slash command
26
21
  ```
27
22
 
23
+ **Install the analyzer pool too, or you get the built-in tier.** This tool
24
+ prefers established analyzers and falls back to its own detectors when none is
25
+ present. The fallback is honest — the report says `Estimate source: built-in
26
+ detectors` and the coverage section names what nothing examined — but it is a
27
+ weaker reading than the tool is capable of, and a first run without these is
28
+ the commonest reason it looks thin.
29
+
30
+ ```bash
31
+ pip install cohesion complexipy flake8 fortitude-lint interrogate lizard \
32
+ multimetric mypy pydocstyle pylint radon ruff vulture
33
+ npm install -g jscpd eslint # duplication + JavaScript/TypeScript
34
+ brew install pmd checkstyle spotbugs # JVM languages, optional
35
+ ```
36
+
37
+ Unpinned on purpose: this is the exact set CI installs and calibrates against,
38
+ and `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
39
+ disagree. Nothing here is required — the audit runs without any of it and tells
40
+ you what it could not measure.
41
+
42
+ **One command to a work order.** A config file is the whole setup — with one
43
+ present, nothing is asked and nothing is written into your tree:
44
+
45
+ ```bash
46
+ curl -O https://raw.githubusercontent.com/marshallguillory86/maintainability-agent/main/maintainability-audit.example.json
47
+ maintainability-audit --config maintainability-audit.example.json \
48
+ --output report.md --prompt-output prompt.md
49
+ ```
50
+
51
+ `prompt.md` is the bounded work order: the findings worth fixing, in order,
52
+ each with its location, why it matters and the command that verifies it — and
53
+ the standing rule that nothing else gets refactored. Paste it into your agent.
54
+ `report.md` is the evidence behind it. The prompt is the product.
55
+
56
+ **Want to see the output before pointing it at your own code?**
57
+ [`examples/demo`](examples/demo/) is a two-module order system with real
58
+ problems in it — an overgrown pricing function, a money path nothing tests, and
59
+ a block duplicated between billing and invoicing. Four items, three finding
60
+ classes, a copy-paste prompt each, and it reads in under a minute. The work
61
+ order it produces is checked in at
62
+ [`expected-prompt.md`](examples/demo/expected-prompt.md).
63
+
64
+ Without `--config`, an interactive run asks the first-run questions instead —
65
+ analyzer pool, depth, licence policy, whether to run your suite — because those
66
+ are choices this tool will not make on your behalf.
67
+
28
68
  ---
29
69
 
30
70
  ## Executive summary
@@ -88,15 +128,6 @@ The full argument, including what this deliberately does not compete on:
88
128
  [why this exists](docs/why-this-exists.md) and
89
129
  [philosophy](docs/philosophy.md).
90
130
 
91
- ## The road to 1.0
92
-
93
- 1.0 was the line drawn under a long arc of **subtraction** — what remained after
94
- every claim the project could not stand behind was removed. A scoring engine
95
- rebuilt after it was found to grade repo *size*; a headline claim about AI
96
- authorship retracted against a matched control; a score that is withheld rather
97
- than guessed. That arc is the credibility, and it is recorded in full, with the
98
- figures quoted from their approved summaries, in [the track record](docs/track-record.md).
99
-
100
131
  ## Install
101
132
 
102
133
  ```bash
@@ -340,19 +371,21 @@ it was generated against — a provenance record, not a claim about HEAD.
340
371
 
341
372
  | Metric | Value |
342
373
  |---|---:|
343
- | Maintainability estimate | 4.2 / 5 |
374
+ | Maintainability estimate | 4.5 / 5 |
344
375
  | Verified grade | B |
345
- | Files scanned | 476 |
376
+ | Files scanned | 511 |
346
377
  | Hard gate failures | 0 |
347
378
 
348
379
  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.
380
+ *floor* of 4.2 rather than the 4.5 point estimate, because an unmeasured aspect
381
+ prices at 0 when a grade has to be defended. Every threshold gate is opted
382
+ **on** for this repository's own CI, so drifting below the bar fails the build
383
+ rather than the README.
384
+
385
+ The tool reports warn-band declarations here and they are not treated as
386
+ defects — see [what counts as a defect](docs/product-intent.md#what-counts-as-a-defect-and-what-does-not).
387
+ Restyling this codebase to raise its own grade is explicitly not work: a tool
388
+ that games its own metric has broken the only promise that matters.
356
389
 
357
390
  ## Platform support
358
391
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "maintainability-agent"
7
- version = "3.4.0"
7
+ version = "3.6.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
@@ -58,7 +58,7 @@ mcp = ["mcp>=2,<3"]
58
58
  # development dependency, never a runtime one: nothing the product
59
59
  # ships imports it, and the oracle exists so a measurement can be
60
60
  # checked against something other than its author.
61
- dev = ["pytest>=8", "pytest-cov>=5", "jsonschema>=4", "ruff>=0.5", "pip-audit>=2.7", "mcp>=2,<3", "PyYAML>=6", "setuptools>=70", "lizard>=1.17"]
61
+ dev = ["pytest>=8", "pytest-cov>=5", "pytest-xdist>=3.6", "jsonschema>=4", "ruff>=0.5", "pip-audit>=2.7", "mcp>=2,<3", "PyYAML>=6", "setuptools>=70", "lizard>=1.17"]
62
62
 
63
63
  [tool.setuptools.package-data]
64
64
  # `_assets` carries the runtime data the code cannot work without: the
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maintainability-agent
3
- Version: 3.4.0
3
+ Version: 3.6.0
4
4
  Summary: Maintainability gate and AI remediation prompt generator for CI.
5
5
  Author: Marshall Guillory
6
6
  License: MIT
@@ -29,6 +29,7 @@ Requires-Dist: mcp<3,>=2; extra == "mcp"
29
29
  Provides-Extra: dev
30
30
  Requires-Dist: pytest>=8; extra == "dev"
31
31
  Requires-Dist: pytest-cov>=5; extra == "dev"
32
+ Requires-Dist: pytest-xdist>=3.6; extra == "dev"
32
33
  Requires-Dist: jsonschema>=4; extra == "dev"
33
34
  Requires-Dist: ruff>=0.5; extra == "dev"
34
35
  Requires-Dist: pip-audit>=2.7; extra == "dev"
@@ -45,12 +46,7 @@ Dynamic: license-file
45
46
  **A deterministic, offline maintainability audit whose output is a _bounded
46
47
  work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
47
48
  says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
48
- Version **3.4.0**.
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).
49
+ Version **3.6.0**.
54
50
 
55
51
  **Languages parsed:** Python, Java, C, C++, C#, Go, Rust, PHP, Ruby, Swift,
56
52
  COBOL, Fortran (free-form *and* fixed-form), and the JS/TS/HTML family — each
@@ -65,6 +61,51 @@ pip install "maintainability-agent[mcp]" # optional local MCP server for chat
65
61
  cp -r skills/maintainability-agent ~/.claude/skills/ # Claude Code slash command
66
62
  ```
67
63
 
64
+ **Install the analyzer pool too, or you get the built-in tier.** This tool
65
+ prefers established analyzers and falls back to its own detectors when none is
66
+ present. The fallback is honest — the report says `Estimate source: built-in
67
+ detectors` and the coverage section names what nothing examined — but it is a
68
+ weaker reading than the tool is capable of, and a first run without these is
69
+ the commonest reason it looks thin.
70
+
71
+ ```bash
72
+ pip install cohesion complexipy flake8 fortitude-lint interrogate lizard \
73
+ multimetric mypy pydocstyle pylint radon ruff vulture
74
+ npm install -g jscpd eslint # duplication + JavaScript/TypeScript
75
+ brew install pmd checkstyle spotbugs # JVM languages, optional
76
+ ```
77
+
78
+ Unpinned on purpose: this is the exact set CI installs and calibrates against,
79
+ and `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
80
+ disagree. Nothing here is required — the audit runs without any of it and tells
81
+ you what it could not measure.
82
+
83
+ **One command to a work order.** A config file is the whole setup — with one
84
+ present, nothing is asked and nothing is written into your tree:
85
+
86
+ ```bash
87
+ curl -O https://raw.githubusercontent.com/marshallguillory86/maintainability-agent/main/maintainability-audit.example.json
88
+ maintainability-audit --config maintainability-audit.example.json \
89
+ --output report.md --prompt-output prompt.md
90
+ ```
91
+
92
+ `prompt.md` is the bounded work order: the findings worth fixing, in order,
93
+ each with its location, why it matters and the command that verifies it — and
94
+ the standing rule that nothing else gets refactored. Paste it into your agent.
95
+ `report.md` is the evidence behind it. The prompt is the product.
96
+
97
+ **Want to see the output before pointing it at your own code?**
98
+ [`examples/demo`](examples/demo/) is a two-module order system with real
99
+ problems in it — an overgrown pricing function, a money path nothing tests, and
100
+ a block duplicated between billing and invoicing. Four items, three finding
101
+ classes, a copy-paste prompt each, and it reads in under a minute. The work
102
+ order it produces is checked in at
103
+ [`expected-prompt.md`](examples/demo/expected-prompt.md).
104
+
105
+ Without `--config`, an interactive run asks the first-run questions instead —
106
+ analyzer pool, depth, licence policy, whether to run your suite — because those
107
+ are choices this tool will not make on your behalf.
108
+
68
109
  ---
69
110
 
70
111
  ## Executive summary
@@ -128,15 +169,6 @@ The full argument, including what this deliberately does not compete on:
128
169
  [why this exists](docs/why-this-exists.md) and
129
170
  [philosophy](docs/philosophy.md).
130
171
 
131
- ## The road to 1.0
132
-
133
- 1.0 was the line drawn under a long arc of **subtraction** — what remained after
134
- every claim the project could not stand behind was removed. A scoring engine
135
- rebuilt after it was found to grade repo *size*; a headline claim about AI
136
- authorship retracted against a matched control; a score that is withheld rather
137
- than guessed. That arc is the credibility, and it is recorded in full, with the
138
- figures quoted from their approved summaries, in [the track record](docs/track-record.md).
139
-
140
172
  ## Install
141
173
 
142
174
  ```bash
@@ -380,19 +412,21 @@ it was generated against — a provenance record, not a claim about HEAD.
380
412
 
381
413
  | Metric | Value |
382
414
  |---|---:|
383
- | Maintainability estimate | 4.2 / 5 |
415
+ | Maintainability estimate | 4.5 / 5 |
384
416
  | Verified grade | B |
385
- | Files scanned | 476 |
417
+ | Files scanned | 511 |
386
418
  | Hard gate failures | 0 |
387
419
 
388
420
  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.
421
+ *floor* of 4.2 rather than the 4.5 point estimate, because an unmeasured aspect
422
+ prices at 0 when a grade has to be defended. Every threshold gate is opted
423
+ **on** for this repository's own CI, so drifting below the bar fails the build
424
+ rather than the README.
425
+
426
+ The tool reports warn-band declarations here and they are not treated as
427
+ defects — see [what counts as a defect](docs/product-intent.md#what-counts-as-a-defect-and-what-does-not).
428
+ Restyling this codebase to raise its own grade is explicitly not work: a tool
429
+ that games its own metric has broken the only promise that matters.
396
430
 
397
431
  ## Platform support
398
432
 
@@ -187,6 +187,7 @@ tests/test_calibration_drift.py
187
187
  tests/test_calibration_tooling.py
188
188
  tests/test_catalog_selection.py
189
189
  tests/test_catalog_tier_promise.py
190
+ tests/test_chat_leads_with_the_work_order.py
190
191
  tests/test_chat_primary_docs.py
191
192
  tests/test_check_refuses_plus_only_fragments.py
192
193
  tests/test_checkstyle_adapter.py
@@ -222,6 +223,7 @@ tests/test_declarative_parsers.py
222
223
  tests/test_declared_authorship.py
223
224
  tests/test_declared_imports.py
224
225
  tests/test_delegated_security_pillar.py
226
+ tests/test_demo_tree.py
225
227
  tests/test_derivation_mix.py
226
228
  tests/test_determinism.py
227
229
  tests/test_dimension_ratchet.py
@@ -236,6 +238,7 @@ tests/test_environment_work_order.py
236
238
  tests/test_evidence_invariants.py
237
239
  tests/test_evidence_normalization.py
238
240
  tests/test_evidence_properties.py
241
+ tests/test_example_config_opens_claimed_languages.py
239
242
  tests/test_exclusion_dialects.py
240
243
  tests/test_falsifier_standard.py
241
244
  tests/test_file_list_cap_class.py
@@ -304,6 +307,7 @@ tests/test_practice_nested_gates_class.py
304
307
  tests/test_precommit_staged.py
305
308
  tests/test_presentation_refusals.py
306
309
  tests/test_promises.py
310
+ tests/test_prompt_does_not_issue_rates_when_unscored.py
307
311
  tests/test_prompt_escalation_once.py
308
312
  tests/test_prompt_honesty.py
309
313
  tests/test_prompt_location_escalation_class.py
@@ -342,6 +346,7 @@ tests/test_source_index.py
342
346
  tests/test_spotbugs_adapter.py
343
347
  tests/test_spotbugs_catalog.py
344
348
  tests/test_stage8_contract.py
349
+ tests/test_stdout_outputs.py
345
350
  tests/test_suite_isolation.py
346
351
  tests/test_swift_declarations.py
347
352
  tests/test_tdd_structure.py
@@ -2,6 +2,7 @@
2
2
  [dev]
3
3
  pytest>=8
4
4
  pytest-cov>=5
5
+ pytest-xdist>=3.6
5
6
  jsonschema>=4
6
7
  ruff>=0.5
7
8
  pip-audit>=2.7
@@ -1,3 +1,3 @@
1
1
  """Maintainability Audit CI."""
2
2
 
3
- __version__ = "3.4.0"
3
+ __version__ = "3.6.0"
@@ -178,13 +178,27 @@ def prompt_work_order(report: dict[str, Any]) -> list[str]:
178
178
  for index, item in enumerate(items, start=1):
179
179
  location = item["path"] + (f":{item['line']}" if item.get("line") else "")
180
180
  lines.append(f"{index}. **{item['title']}** — {item['target']}")
181
- lines.append(f" - Location: `{location}`")
181
+ # One row now stands for its whole class (D159), so a count
182
+ # above one says where the rest are rather than leaving the
183
+ # single location reading as the only instance.
184
+ count = item.get("class_count") or 1
185
+ files = item.get("class_paths") or 1
186
+ if count > 1:
187
+ where = f"across {files} files, " if files > 1 else ""
188
+ lines.append(f" - First of {count} {where}starting at: `{location}`")
189
+ else:
190
+ lines.append(f" - Location: `{location}`")
182
191
  lines.append(f" - Why it matters: {item['rationale']}")
183
192
  if item["class_delta"]:
184
193
  lines.append(
185
194
  f" - Clearing all {item['class_count']} of these is worth "
186
195
  f"+{item['class_delta']:.2f} to the maintainability estimate."
187
196
  )
197
+ elif count > 1:
198
+ lines.append(
199
+ f" - The other {count - 1} are listed in the report; the "
200
+ "score does not move until the class is cleared."
201
+ )
188
202
  lines.extend([
189
203
  "",
190
204
  f"Verify with: `{items[0]['verification']}`",
@@ -212,7 +226,28 @@ def prompt_pressure_section(score: dict[str, Any]) -> list[str]:
212
226
  statement an agent can prioritize against. Dimensions at or below 1.0
213
227
  are deliberately left out: they are already normal, and listing them
214
228
  invites busywork.
229
+
230
+ **Nothing here is printed when the overall estimate was withheld
231
+ (D163).** A corpus multiple *is* a score — it is a rate compared
232
+ against a calibrated median — so a run that refused to issue an
233
+ overall on too little evidence cannot turn around and rank this
234
+ repository's dimensions against that same corpus. P7 governs both.
235
+
236
+ The demo tree is the case that made it visible: the report said
237
+ `Not scored` and its own README said *"only the rates are
238
+ withheld"*, while the file the README calls the work order opened
239
+ with `declarations at 3.9x` and `Start with declarations`. The
240
+ complete Markdown report on the same run printed no multiples. Only
241
+ the advertised product file did.
242
+
243
+ The work order itself is unaffected and still names every finding —
244
+ a finding is an observation, not a rate, and withholding those would
245
+ leave an undersized repository with nothing at all.
215
246
  """
247
+ if not view.is_scored(score):
248
+ # The grade blockers still render below: those say *why* no
249
+ # number was issued, which is exactly what this reader needs.
250
+ return [*view.unanchored_caveat(score), *_grade_blocker_lines(score)]
216
251
  dimensions = score.get("dimensions") or {}
217
252
  elevated = sorted(
218
253
  # `is not None` first: an unmeasured dimension is legitimate --
@@ -246,13 +281,23 @@ def prompt_pressure_section(score: dict[str, Any]) -> list[str]:
246
281
  "",
247
282
  ]
248
283
  )
249
- for blocker in view.grade_blockers(score):
250
- lines.append(f"- Grade capped: {blocker}")
251
- if view.grade_blockers(score):
252
- lines.append("")
284
+ lines.extend(_grade_blocker_lines(score))
253
285
  return lines
254
286
 
255
287
 
288
+ def _grade_blocker_lines(score: dict[str, Any]) -> list[str]:
289
+ """Why the grade is capped — printed whether or not a number was issued.
290
+
291
+ Split out so the withheld-score path above can render it too: the
292
+ reasons a score was capped or refused are the one part of this
293
+ section that is not itself a rate.
294
+ """
295
+ blockers = view.grade_blockers(score)
296
+ if not blockers:
297
+ return []
298
+ return [*(f"- Grade capped: {blocker}" for blocker in blockers), ""]
299
+
300
+
256
301
  def _escalated_fingerprints(report: dict[str, Any]) -> set[str]:
257
302
  """Findings the history shows do not stay fixed.
258
303
 
@@ -57,7 +57,7 @@ from .config import PathNotAllowed, read_operator_file
57
57
  # followed. A schema-4 line read by an older build fails that one line's
58
58
  # parse and costs that scan, which is the tolerance `read_history` was
59
59
  # built with rather than a new risk.
60
- HISTORY_SCHEMA_VERSION = 4
60
+ HISTORY_SCHEMA_VERSION = 5
61
61
 
62
62
  DEFAULT_HISTORY_PATH = ".maintainability/history.jsonl"
63
63
 
@@ -70,7 +70,7 @@ DEFAULT_HISTORY_PATH = ".maintainability/history.jsonl"
70
70
  # score being added and not added here, after which trends silently span
71
71
  # a change in the instrument.
72
72
  COMPARABILITY_FIELDS: tuple[str, ...] = (
73
- "rubric_version",
73
+ "tool_version",
74
74
  "calibration",
75
75
  "thresholds_digest",
76
76
  "analyzers",
@@ -102,7 +102,14 @@ class ScanRecord:
102
102
  commit: str
103
103
  branch: str
104
104
  scope: str
105
- rubric_version: str
105
+ #: The version of *this tool* that produced the scan. Named
106
+ #: `rubric_version` until 3.5.0, which is what it was never: a
107
+ #: rubric version would move when the rubric moved, and this moves
108
+ #: on every release. A reader of a stored line saw
109
+ #: `"rubric_version": "3.4.0"` and concluded the rubric had changed
110
+ #: when a patch release was all that happened — on 38 of this
111
+ #: repository's 49 series breaks (D158).
112
+ tool_version: str
106
113
  calibration: float
107
114
  # A digest of the thresholds in force. Stored rather than the
108
115
  # thresholds themselves: the comparison is equality, and a digest
@@ -210,21 +217,28 @@ def comparability_key(record: ScanRecord) -> tuple[Any, ...]:
210
217
 
211
218
 
212
219
  # What each comparability field is, in words a reader can act on. The
213
- # stored names are terse and one of them actively misleads: the field
214
- # called `rubric_version` holds the *package* version, so a reader told
215
- # "rubric_version changed" hears that the rubric moved when a patch
216
- # release is all that happened — and on this repository's own history
217
- # that field accounts for 38 of 49 breaks. The name stays as stored
218
- # (renaming it is a migration of every written line); what the report
219
- # says about it is corrected here, which is where the claim is made.
220
+ # stored names are terse and prose is what a report should print: a
221
+ # break that names `thresholds_digest` tells a reader less than one
222
+ # saying the configured thresholds changed.
223
+ #
224
+ # `tool_version` was `rubric_version` until 3.5.0 and this map was
225
+ # where that lie was first corrected — the display said "the tool
226
+ # version" while the stored field still said otherwise. D158 finished
227
+ # it by renaming the field, so the map and the record now agree instead
228
+ # of one translating the other.
220
229
  FIELD_NAMES: dict[str, str] = {
221
- "rubric_version": "the tool version",
230
+ "tool_version": "the tool version",
222
231
  "calibration": "the calibration constant",
223
232
  "thresholds_digest": "the configured thresholds",
224
233
  "analyzers": "which analyzers contributed",
225
234
  "scored_languages": "the scored languages",
226
235
  "scope": "the scan scope",
227
- "delegated_producers": "a delegated pillar's producer or its version",
236
+ # Names the scoring model rather than the version, because that is
237
+ # what `_model_key` actually keys on. Saying "its version" sent a
238
+ # reader looking for a release that in the common case had not
239
+ # changed -- the v2 document breaks on `scoring_model`, and the
240
+ # version is only the v1 fallback.
241
+ "delegated_producers": "a delegated pillar's producer or its scoring model",
228
242
  }
229
243
 
230
244
 
@@ -408,6 +422,15 @@ def read_history(path: Path) -> list[ScanRecord]:
408
422
  try:
409
423
  payload = json.loads(line)
410
424
  payload.pop("history_schema_version", None)
425
+ # Schema 1-4 stored this as `rubric_version`. Renamed in 5
426
+ # because the name was never true (D158); every line written
427
+ # before that keeps loading, and keeps its place in a
428
+ # series, because the *value* never changed — only what it
429
+ # is called. A stored history is the one thing here that
430
+ # cannot be regenerated, so a rename that dropped it would
431
+ # cost more than the wrong name did.
432
+ if "rubric_version" in payload:
433
+ payload["tool_version"] = payload.pop("rubric_version")
411
434
  # Every sequence field back to a tuple. JSON has one list
412
435
  # type, so a field missed here returns as a list and the
413
436
  # record stops comparing equal to a freshly built one —
@@ -506,7 +529,7 @@ def _delegated_producers(report: dict[str, Any]) -> tuple[str, ...]:
506
529
  Sorted and joined into one string per pillar so the comparability
507
530
  key stays a plain value. Only delegated pillars carry a producer;
508
531
  the ones this tool measures itself are already covered by
509
- `rubric_version`.
532
+ `tool_version`.
510
533
 
511
534
  A pillar whose document names no version still contributes its
512
535
  producer, because "the same tool, version unknown" and "a different
@@ -575,7 +598,7 @@ def record_of(report: dict[str, Any], config: dict[str, Any], version: str,
575
598
  commit=report.get("git_commit") or "",
576
599
  branch=report.get("git_branch") or "",
577
600
  scope=report.get("mode") or "full",
578
- rubric_version=version,
601
+ tool_version=version,
579
602
  calibration=calibration,
580
603
  thresholds_digest=thresholds_digest(config.get("thresholds") or {}),
581
604
  analyzers=contributed,