maintainability-agent 4.4.2__tar.gz → 4.4.3__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 (483) hide show
  1. {maintainability_agent-4.4.2/src/maintainability_agent.egg-info → maintainability_agent-4.4.3}/PKG-INFO +3 -3
  2. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/README.md +2 -2
  3. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3/src/maintainability_agent.egg-info}/PKG-INFO +3 -3
  4. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_agent.egg-info/SOURCES.txt +2 -0
  5. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/__init__.py +1 -1
  6. maintainability_agent-4.4.3/src/maintainability_audit/_mcp_servers.py +107 -0
  7. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_self_update.py +20 -5
  8. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/mcp_server.py +25 -16
  9. maintainability_agent-4.4.3/tests/test_mcp_servers.py +191 -0
  10. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_self_update.py +60 -1
  11. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/LICENSE +0 -0
  12. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/pyproject.toml +0 -0
  13. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/setup.cfg +0 -0
  14. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
  15. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
  16. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_agent.egg-info/requires.txt +0 -0
  17. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_agent.egg-info/top_level.txt +0 -0
  18. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/__main__.py +0 -0
  19. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_adapters.py +0 -0
  20. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_analysis.py +0 -0
  21. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_analyzer_sections.py +0 -0
  22. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_anchor.py +0 -0
  23. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_arguments.py +0 -0
  24. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_aspects.py +0 -0
  25. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
  26. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_assets/standard.md +0 -0
  27. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_attestation.py +0 -0
  28. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_backfill.py +0 -0
  29. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_bands.py +0 -0
  30. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_banner.py +0 -0
  31. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_built_ins.py +0 -0
  32. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_calibration.py +0 -0
  33. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_catalog.py +0 -0
  34. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_changed_code_policy.py +0 -0
  35. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_charts.py +0 -0
  36. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_cognitive.py +0 -0
  37. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_config_defaults.py +0 -0
  38. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_conformance.py +0 -0
  39. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_corroborate.py +0 -0
  40. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_coverage_notes.py +0 -0
  41. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_criteria_scope.py +0 -0
  42. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_delegated_pillar.py +0 -0
  43. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_derive.py +0 -0
  44. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_discovery.py +0 -0
  45. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_documents.py +0 -0
  46. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_economics.py +0 -0
  47. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_economics_view.py +0 -0
  48. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_environment.py +0 -0
  49. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_evidence_reader.py +0 -0
  50. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_evidence_view.py +0 -0
  51. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_finding_match.py +0 -0
  52. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_first_run.py +0 -0
  53. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_formula.py +0 -0
  54. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_gates.py +0 -0
  55. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_generic.py +0 -0
  56. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_grammar.py +0 -0
  57. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_grant_ledger.py +0 -0
  58. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_handoff.py +0 -0
  59. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_history_view.py +0 -0
  60. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_hostile_prompt.py +0 -0
  61. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_hotspots.py +0 -0
  62. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_html_report_sections.py +0 -0
  63. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_html_view.py +0 -0
  64. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_identity.py +0 -0
  65. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_in_loop.py +0 -0
  66. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_in_loop_view.py +0 -0
  67. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_jvm_adapters.py +0 -0
  68. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_markdown_sections.py +0 -0
  69. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_masking.py +0 -0
  70. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_mcp_audit.py +0 -0
  71. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_mcp_gate.py +0 -0
  72. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_mcp_grants.py +0 -0
  73. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_mcp_refusals.py +0 -0
  74. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_mcp_resources.py +0 -0
  75. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_mcp_setup.py +0 -0
  76. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_metric_adapters.py +0 -0
  77. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_metrics_types.py +0 -0
  78. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_operator_reads.py +0 -0
  79. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_oracle.py +0 -0
  80. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_pillars.py +0 -0
  81. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_pipeline_results.py +0 -0
  82. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_practice.py +0 -0
  83. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_precommit.py +0 -0
  84. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_precommit_install.py +0 -0
  85. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_precommit_view.py +0 -0
  86. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_pressures.py +0 -0
  87. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_prompt_sections.py +0 -0
  88. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_c.py +0 -0
  89. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_cobol.py +0 -0
  90. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_core.py +0 -0
  91. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_cpp.py +0 -0
  92. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_csharp.py +0 -0
  93. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_fortran.py +0 -0
  94. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_go.py +0 -0
  95. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_java.py +0 -0
  96. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_js.py +0 -0
  97. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_kotlin.py +0 -0
  98. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_php.py +0 -0
  99. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_ruby.py +0 -0
  100. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_rust.py +0 -0
  101. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_shell.py +0 -0
  102. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ranges_swift.py +0 -0
  103. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ratchet.py +0 -0
  104. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_ratio_adapters.py +0 -0
  105. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_recurrence.py +0 -0
  106. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_run_comparison.py +0 -0
  107. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_runner.py +0 -0
  108. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_running_version.py +0 -0
  109. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_safe_write.py +0 -0
  110. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_scan_history.py +0 -0
  111. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_scan_view.py +0 -0
  112. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_second_source.py +0 -0
  113. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_security_delegate.py +0 -0
  114. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_security_work_order.py +0 -0
  115. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_selection.py +0 -0
  116. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_semantic.py +0 -0
  117. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_semantic_policy.py +0 -0
  118. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_semantic_ts.py +0 -0
  119. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_semantic_view.py +0 -0
  120. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_setup_errors.py +0 -0
  121. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_setup_persist.py +0 -0
  122. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
  123. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
  124. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
  125. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
  126. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
  127. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
  128. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_skill_install.py +0 -0
  129. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_stored_grants.py +0 -0
  130. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_tdd_view.py +0 -0
  131. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_test_commands.py +0 -0
  132. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_test_execution.py +0 -0
  133. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_test_pairing.py +0 -0
  134. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_tokens.py +0 -0
  135. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_tool_adapters.py +0 -0
  136. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_trends.py +0 -0
  137. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_user_config.py +0 -0
  138. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_verdict_adapters.py +0 -0
  139. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_verification.py +0 -0
  140. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_work_order.py +0 -0
  141. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_work_order_view.py +0 -0
  142. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_work_order_weights.py +0 -0
  143. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/_xml.py +0 -0
  144. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/baseline.py +0 -0
  145. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/cli.py +0 -0
  146. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/config.py +0 -0
  147. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/deadcode.py +0 -0
  148. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/declarations.py +0 -0
  149. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/duplication.py +0 -0
  150. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/evidence.py +0 -0
  151. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/git_tools.py +0 -0
  152. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/history.py +0 -0
  153. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/idioms.py +0 -0
  154. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/instructions.py +0 -0
  155. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/metrics.py +0 -0
  156. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/prompts.py +0 -0
  157. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/renderers.py +0 -0
  158. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/report.py +0 -0
  159. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/sarif.py +0 -0
  160. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/scoring.py +0 -0
  161. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/similarity.py +0 -0
  162. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/src/maintainability_audit/source.py +0 -0
  163. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_a_clone_names_every_copy.py +0 -0
  164. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_a_dangling_source_link_is_named_not_fatal.py +0 -0
  165. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_a_format_override_is_disclosed.py +0 -0
  166. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_a_matching_format_stays_silent.py +0 -0
  167. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_a_published_question_offers_what_it_accepts.py +0 -0
  168. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_a_rendered_docs_site_is_not_scored_as_source.py +0 -0
  169. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_a_setup_question_keeps_its_contract.py +0 -0
  170. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_acquisition_trust.py +0 -0
  171. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_adapter_docs.py +0 -0
  172. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_adapter_recordings.py +0 -0
  173. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_adapters.py +0 -0
  174. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_added_lines.py +0 -0
  175. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_an_absent_work_order_renders_nothing.py +0 -0
  176. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_an_unmeasured_pillar_reports_no_number.py +0 -0
  177. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analysis_coverage.py +0 -0
  178. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analysis_execution.py +0 -0
  179. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_bridge.py +0 -0
  180. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_config_isolation.py +0 -0
  181. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_estimate_claims.py +0 -0
  182. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_file_lists_are_batched.py +0 -0
  183. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_pinning.py +0 -0
  184. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_primary_estimate.py +0 -0
  185. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_provenance.py +0 -0
  186. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_provenance_exclusions.py +0 -0
  187. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_scoring_path.py +0 -0
  188. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_spread_range.py +0 -0
  189. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzer_xml_bounds.py +0 -0
  190. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzers_against_the_real_tools.py +0 -0
  191. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzers_never_write.py +0 -0
  192. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_analyzers_report_what_actually_failed.py +0 -0
  193. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_anchor_and_mode.py +0 -0
  194. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
  195. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_anchor_disclosure.py +0 -0
  196. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_annotations_match_behaviour.py +0 -0
  197. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_anticipated_refusals.py +0 -0
  198. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_architecture.py +0 -0
  199. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_artifact_write_route_class.py +0 -0
  200. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_aspect_coverage.py +0 -0
  201. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_asset_snapshot_class.py +0 -0
  202. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_ast_reading_resolves_spellings.py +0 -0
  203. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_attestation.py +0 -0
  204. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_audit_components.py +0 -0
  205. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_authorization_freshness.py +0 -0
  206. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_authorship_gates.py +0 -0
  207. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_backfill.py +0 -0
  208. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_band_concealment_class.py +0 -0
  209. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_band_concealment_p3.py +0 -0
  210. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_band_pressures.py +0 -0
  211. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_bands.py +0 -0
  212. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_behaviour_suites_are_tests.py +0 -0
  213. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_body_or_signature_class.py +0 -0
  214. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_both_setup_paths_ask_the_same_stage.py +0 -0
  215. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
  216. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_c_declarations.py +0 -0
  217. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_calibration_corpus.py +0 -0
  218. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_calibration_drift.py +0 -0
  219. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_calibration_tooling.py +0 -0
  220. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_catalog_selection.py +0 -0
  221. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_catalog_tier_promise.py +0 -0
  222. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_changed_code_policy.py +0 -0
  223. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_chat_leads_with_the_work_order.py +0 -0
  224. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_chat_primary_docs.py +0 -0
  225. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_check_refuses_plus_only_fragments.py +0 -0
  226. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_checkstyle_adapter.py +0 -0
  227. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_checkstyle_catalog.py +0 -0
  228. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_child_sandbox.py +0 -0
  229. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_ci_history_recipe.py +0 -0
  230. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
  231. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_ci_runs_once.py +0 -0
  232. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_claimed_languages.py +0 -0
  233. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_clean_sees_the_weakened_oracle.py +0 -0
  234. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_cli.py +0 -0
  235. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_clone_group_class.py +0 -0
  236. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_cobol_declarations.py +0 -0
  237. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_code_scanning_gets_alerts_not_the_record.py +0 -0
  238. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_cognitive_complexity.py +0 -0
  239. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_cohesion_with_nothing_to_read_is_not_applicable.py +0 -0
  240. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_cohort_statistics.py +0 -0
  241. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_concealment_properties.py +0 -0
  242. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_config_shape.py +0 -0
  243. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_conformance_reads_the_operators_ask.py +0 -0
  244. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_consent_and_grant.py +0 -0
  245. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_consent_is_per_repository.py +0 -0
  246. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_consent_survives_setup_and_is_asked.py +0 -0
  247. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_consent_without_command_has_a_remedy.py +0 -0
  248. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_consumer_migration.py +0 -0
  249. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_contract_claims.py +0 -0
  250. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_corpus_note_counts_come_from_the_corpus.py +0 -0
  251. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_corroborate.py +0 -0
  252. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_coverage_by_language.py +0 -0
  253. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_coverage_config_reaches_children.py +0 -0
  254. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_coverage_formats.py +0 -0
  255. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_cpp_declarations.py +0 -0
  256. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_criteria_completion.py +0 -0
  257. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_csharp_declarations.py +0 -0
  258. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_current_state_docs_name_every_parsed_language.py +0 -0
  259. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_d15_composition.py +0 -0
  260. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_d15_goal_directed.py +0 -0
  261. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_dead_code.py +0 -0
  262. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_declaration_criteria_scope.py +0 -0
  263. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_declaration_edge_cases.py +0 -0
  264. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_declaration_grading.py +0 -0
  265. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_declaration_ranges.py +0 -0
  266. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_declaration_source.py +0 -0
  267. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_declarative_parsers.py +0 -0
  268. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_declared_capabilities_match_the_delegate.py +0 -0
  269. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_declared_imports.py +0 -0
  270. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_delegated_security_pillar.py +0 -0
  271. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_demo_tree.py +0 -0
  272. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_derivation_mix.py +0 -0
  273. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_determinism.py +0 -0
  274. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_dimension_ratchet.py +0 -0
  275. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_direct_runner_availability_class.py +0 -0
  276. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_discovery.py +0 -0
  277. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_doc_claims.py +0 -0
  278. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_docs_links.py +0 -0
  279. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_economic_context.py +0 -0
  280. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_empty_output_not_clean.py +0 -0
  281. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_empty_output_not_clean_adapters.py +0 -0
  282. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_environment_work_order.py +0 -0
  283. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_every_built_presentation_is_offered.py +0 -0
  284. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_every_job_tests_the_pinned_oracle.py +0 -0
  285. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_every_language_counts_its_own_loop.py +0 -0
  286. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_every_language_has_a_loop_fixture.py +0 -0
  287. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_every_pool_install_is_the_same_pool.py +0 -0
  288. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_every_question_can_be_answered.py +0 -0
  289. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_every_surface_says_what_the_run_found.py +0 -0
  290. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_evidence_invariants.py +0 -0
  291. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_evidence_normalization.py +0 -0
  292. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_evidence_properties.py +0 -0
  293. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_example_config_opens_claimed_languages.py +0 -0
  294. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_exclude_additional_keeps_the_defaults.py +0 -0
  295. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_exclusion_dialects.py +0 -0
  296. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_exposure_never_outranks_band.py +0 -0
  297. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_falsifier_standard.py +0 -0
  298. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_file_list_cap_class.py +0 -0
  299. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_finding_identity.py +0 -0
  300. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_first_run_elicitation.py +0 -0
  301. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_first_run_prompt.py +0 -0
  302. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_first_run_reelicitation.py +0 -0
  303. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_first_stage_setup_wording_holds.py +0 -0
  304. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_fix_breadth_window.py +0 -0
  305. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_fixed_form_fortran.py +0 -0
  306. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_format_ask.py +0 -0
  307. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_fortran_declarations.py +0 -0
  308. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_fortran_metrics.py +0 -0
  309. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_fortran_practice.py +0 -0
  310. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_git_argv.py +0 -0
  311. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_git_read_only.py +0 -0
  312. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_git_readonly_class.py +0 -0
  313. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_go_declarations.py +0 -0
  314. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_grammar_constructs.py +0 -0
  315. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_grammar_token_coverage.py +0 -0
  316. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_grant_only_user_tier.py +0 -0
  317. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_grok_audit_of_3_11.py +0 -0
  318. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_history.py +0 -0
  319. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_history_boundary.py +0 -0
  320. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_history_manifest.py +0 -0
  321. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_history_schema2.py +0 -0
  322. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_history_window.py +0 -0
  323. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_hostile_prompt.py +0 -0
  324. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_html_executive.py +0 -0
  325. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_html_section_parity_class.py +0 -0
  326. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_identity_docs.py +0 -0
  327. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_identity_resolution.py +0 -0
  328. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_idiom_divergence.py +0 -0
  329. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_in_loop_budgets.py +0 -0
  330. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_in_loop_check.py +0 -0
  331. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_installed_wheel_runtime.py +0 -0
  332. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_instruction_targets.py +0 -0
  333. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_java_range_guard.py +0 -0
  334. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_java_ranges.py +0 -0
  335. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_java_scored.py +0 -0
  336. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_java_wiring.py +0 -0
  337. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_js_complexity_operators.py +0 -0
  338. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_js_declarations.py +0 -0
  339. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_kotlin_declarations.py +0 -0
  340. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_kotlin_metrics.py +0 -0
  341. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_language_coverage.py +0 -0
  342. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_language_support_honesty.py +0 -0
  343. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_list_tools_publishes_the_answer_path.py +0 -0
  344. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_local_gate.py +0 -0
  345. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_maintenance_signals.py +0 -0
  346. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_mcp_baseline_payload.py +0 -0
  347. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_mcp_format_contract.py +0 -0
  348. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_mcp_history.py +0 -0
  349. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_mcp_server.py +0 -0
  350. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_mcp_start_failure_names_what_is_installed.py +0 -0
  351. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_migration_1_0.py +0 -0
  352. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_missing_security_scanners_are_named_before_the_run.py +0 -0
  353. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_mutation_recorded.py +0 -0
  354. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_near_duplicates.py +0 -0
  355. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_network_disclosure.py +0 -0
  356. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_no_private_names.py +0 -0
  357. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_one_setup_across_surfaces_class.py +0 -0
  358. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_operator_named_paths.py +0 -0
  359. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_operator_named_reads.py +0 -0
  360. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_oracle_weakening_precision_bar.py +0 -0
  361. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_pairing_reads_imports.py +0 -0
  362. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_pattern_budget.py +0 -0
  363. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_phase6_claims.py +0 -0
  364. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_php_declarations.py +0 -0
  365. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_pillars_and_practice.py +0 -0
  366. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_pipeline_results.py +0 -0
  367. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_platform_claim.py +0 -0
  368. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_pmd_adapter.py +0 -0
  369. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_pmd_audit_closures.py +0 -0
  370. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_policy_claims.py +0 -0
  371. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_pool_runs_by_config.py +0 -0
  372. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_population_floors.py +0 -0
  373. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_practice_nested_gates_class.py +0 -0
  374. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_precommit_staged.py +0 -0
  375. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_preflight_before_consent_runs_nothing_from_the_tree.py +0 -0
  376. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_presentation_refusals.py +0 -0
  377. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_previous_release_reached_pypi.py +0 -0
  378. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_promises.py +0 -0
  379. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
  380. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_prompt_escalation_once.py +0 -0
  381. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_prompt_honesty.py +0 -0
  382. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_prompt_location_escalation_class.py +0 -0
  383. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_prove_falsifiers.py +0 -0
  384. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_python_complexity.py +0 -0
  385. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_python_declarations.py +0 -0
  386. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_read_boundary.py +0 -0
  387. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_readme_claims.py +0 -0
  388. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_recurrence.py +0 -0
  389. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_regular_file_reads_work_without_o_nonblock.py +0 -0
  390. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_release_needs_an_empty_ledger.py +0 -0
  391. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_release_plan.py +0 -0
  392. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_release_plan_status.py +0 -0
  393. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_rendered_docs.py +0 -0
  394. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_report_remedy_copy.py +0 -0
  395. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_reported_but_not_scored.py +0 -0
  396. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_root_grants.py +0 -0
  397. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_rubric_ignores_project_lint_config.py +0 -0
  398. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_ruby_declarations.py +0 -0
  399. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_run_comparison.py +0 -0
  400. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_runner.py +0 -0
  401. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_rust_declarations.py +0 -0
  402. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_sarif.py +0 -0
  403. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_scan_history.py +0 -0
  404. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_scan_scope.py +0 -0
  405. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_scanner_fingerprint_covers_the_measurement_path.py +0 -0
  406. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_scanner_unsafe_direction.py +0 -0
  407. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_scanning.py +0 -0
  408. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_schema_fidelity.py +0 -0
  409. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_scope_conformance.py +0 -0
  410. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_scoring_calibration.py +0 -0
  411. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_security_delegate_versions_agree.py +0 -0
  412. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_security_findings_keep_their_handoff.py +0 -0
  413. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_security_pillar_asserts_a_scanner_set.py +0 -0
  414. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_security_pillar_runs_and_shows.py +0 -0
  415. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_selection_covers_every_parsed_language.py +0 -0
  416. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_semantic_findings_stay_inside_the_audited_files.py +0 -0
  417. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_semantic_policy.py +0 -0
  418. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_setup_answers_are_the_same_setup.py +0 -0
  419. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_setup_gate_completeness.py +0 -0
  420. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_setup_gate_independent_contract.py +0 -0
  421. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_setup_instruction_describes_its_own_reply.py +0 -0
  422. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_setup_precondition.py +0 -0
  423. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_setup_writes_a_valid_config.py +0 -0
  424. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_shell_declarations.py +0 -0
  425. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_shell_metrics.py +0 -0
  426. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_skill_install.py +0 -0
  427. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_sonar_resolve.py +0 -0
  428. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_source_index.py +0 -0
  429. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_spotbugs_adapter.py +0 -0
  430. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_spotbugs_catalog.py +0 -0
  431. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_stage8_contract.py +0 -0
  432. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_stamped_documents_stay_honest.py +0 -0
  433. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_stdout_outputs.py +0 -0
  434. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_suite_isolation.py +0 -0
  435. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_swift_declarations.py +0 -0
  436. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_tdd_structure.py +0 -0
  437. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_terminal_asks_the_same_questions.py +0 -0
  438. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_test_commands.py +0 -0
  439. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_test_execution_class.py +0 -0
  440. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_agent_knows_when_it_is_stale.py +0 -0
  441. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_changelog_covers_the_shipping_version.py +0 -0
  442. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_chat_payload_has_a_budget.py +0 -0
  443. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_condition_says_what_it_measured.py +0 -0
  444. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_handoff_rules_are_their_own_module.py +0 -0
  445. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_pillar_row_reads_cleanly.py +0 -0
  446. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_presentation_question_stays_answerable.py +0 -0
  447. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_previous_release_was_tagged.py +0 -0
  448. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_prompt_does_not_take_back_what_it_withheld.py +0 -0
  449. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_prompt_keeps_listing_what_it_did_not_withhold.py +0 -0
  450. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_release_process_describes_itself.py +0 -0
  451. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_release_record_stays_well_formed.py +0 -0
  452. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_report_is_saved_not_sent.py +0 -0
  453. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_security_run_has_a_configurable_limit.py +0 -0
  454. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_security_work_order_is_drawn.py +0 -0
  455. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_suite_names_the_program_it_ran.py +0 -0
  456. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_tree_cannot_redirect_a_read.py +0 -0
  457. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_the_version_has_one_source.py +0 -0
  458. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_three_presentations.py +0 -0
  459. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_tool_resolution.py +0 -0
  460. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
  461. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_tree_chosen_spawn.py +0 -0
  462. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_tree_reads_use_the_primitive.py +0 -0
  463. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_trends.py +0 -0
  464. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_type_fields_not_functions_class.py +0 -0
  465. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_uat_falsifiers.py +0 -0
  466. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_unanchored_set_matches_corpus.py +0 -0
  467. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_unread_code.py +0 -0
  468. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_user_config_tier.py +0 -0
  469. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_verification_audit_closures.py +0 -0
  470. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_verified_grade.py +0 -0
  471. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_version_claim.py +0 -0
  472. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_version_stamping.py +0 -0
  473. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_wheel_contents.py +0 -0
  474. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_withheld_work_keeps_its_boundary.py +0 -0
  475. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_work_items_state_their_own_finding.py +0 -0
  476. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_work_order.py +0 -0
  477. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
  478. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_work_order_items.py +0 -0
  479. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_work_order_selection.py +0 -0
  480. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_workflow_supply_chain.py +0 -0
  481. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_write_boundary.py +0 -0
  482. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_write_route_class.py +0 -0
  483. {maintainability_agent-4.4.2 → maintainability_agent-4.4.3}/tests/test_written_record.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maintainability-agent
3
- Version: 4.4.2
3
+ Version: 4.4.3
4
4
  Summary: Maintainability gate and AI remediation prompt generator for CI.
5
5
  Author: Marshall Guillory
6
6
  License: MIT
@@ -47,7 +47,7 @@ Dynamic: license-file
47
47
  **A deterministic, offline maintainability audit whose output is a _bounded
48
48
  work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
49
49
  says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
50
- Version **4.4.2**.
50
+ Version **4.4.3**.
51
51
 
52
52
  > ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
53
53
  >
@@ -517,7 +517,7 @@ instead of an invokable skill:
517
517
  This repo ships `action.yml`, usable as a composite action:
518
518
 
519
519
  ```yaml
520
- - uses: marshallguillory86/maintainability-agent@v4.4.2
520
+ - uses: marshallguillory86/maintainability-agent@v4.4.3
521
521
  with:
522
522
  config: maintainability-agent.json
523
523
  changed-only: main...HEAD
@@ -5,7 +5,7 @@
5
5
  **A deterministic, offline maintainability audit whose output is a _bounded
6
6
  work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
7
7
  says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
8
- Version **4.4.2**.
8
+ Version **4.4.3**.
9
9
 
10
10
  > ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
11
11
  >
@@ -475,7 +475,7 @@ instead of an invokable skill:
475
475
  This repo ships `action.yml`, usable as a composite action:
476
476
 
477
477
  ```yaml
478
- - uses: marshallguillory86/maintainability-agent@v4.4.2
478
+ - uses: marshallguillory86/maintainability-agent@v4.4.3
479
479
  with:
480
480
  config: maintainability-agent.json
481
481
  changed-only: main...HEAD
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maintainability-agent
3
- Version: 4.4.2
3
+ Version: 4.4.3
4
4
  Summary: Maintainability gate and AI remediation prompt generator for CI.
5
5
  Author: Marshall Guillory
6
6
  License: MIT
@@ -47,7 +47,7 @@ Dynamic: license-file
47
47
  **A deterministic, offline maintainability audit whose output is a _bounded
48
48
  work order_ for an AI coding agent** — a copy-paste prompt, per finding, that
49
49
  says *fix exactly these and refactor nothing else*. Chat-primary; CLI for CI.
50
- Version **4.4.2**.
50
+ Version **4.4.3**.
51
51
 
52
52
  > ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
53
53
  >
@@ -517,7 +517,7 @@ instead of an invokable skill:
517
517
  This repo ships `action.yml`, usable as a composite action:
518
518
 
519
519
  ```yaml
520
- - uses: marshallguillory86/maintainability-agent@v4.4.2
520
+ - uses: marshallguillory86/maintainability-agent@v4.4.3
521
521
  with:
522
522
  config: maintainability-agent.json
523
523
  changed-only: main...HEAD
@@ -63,6 +63,7 @@ src/maintainability_audit/_mcp_gate.py
63
63
  src/maintainability_audit/_mcp_grants.py
64
64
  src/maintainability_audit/_mcp_refusals.py
65
65
  src/maintainability_audit/_mcp_resources.py
66
+ src/maintainability_audit/_mcp_servers.py
66
67
  src/maintainability_audit/_mcp_setup.py
67
68
  src/maintainability_audit/_metric_adapters.py
68
69
  src/maintainability_audit/_metrics_types.py
@@ -342,6 +343,7 @@ tests/test_mcp_baseline_payload.py
342
343
  tests/test_mcp_format_contract.py
343
344
  tests/test_mcp_history.py
344
345
  tests/test_mcp_server.py
346
+ tests/test_mcp_servers.py
345
347
  tests/test_mcp_start_failure_names_what_is_installed.py
346
348
  tests/test_migration_1_0.py
347
349
  tests/test_missing_security_scanners_are_named_before_the_run.py
@@ -1,3 +1,3 @@
1
1
  """Maintainability Audit CI."""
2
2
 
3
- __version__ = "4.4.2"
3
+ __version__ = "4.4.3"
@@ -0,0 +1,107 @@
1
+ """Which MCP servers are running which version, so ``--update`` can stop stale ones.
2
+
3
+ A stdio MCP server holds the code it loaded at spawn. After an upgrade it
4
+ keeps serving the old version until it stops, and its host starts the new
5
+ one on the next call. 4.4.2 told the operator to run ``/mcp``, which in the
6
+ VS Code panel only lists servers (D232). Now each server records its pid and
7
+ version here, marks itself busy while an audit runs, and ``--update`` stops
8
+ the stale ones that are idle. A busy server is left alone; the next hourly
9
+ update stops it.
10
+ """
11
+
12
+ from __future__ import annotations
13
+
14
+ import json
15
+ import os
16
+ import signal
17
+ from collections.abc import Callable, Iterator
18
+ from contextlib import contextmanager
19
+ from dataclasses import dataclass
20
+ from pathlib import Path
21
+
22
+ from . import _runner
23
+
24
+
25
+ @dataclass(frozen=True)
26
+ class Stopped:
27
+ stopped: tuple[int, ...] = ()
28
+ busy: tuple[int, ...] = ()
29
+ gone: tuple[int, ...] = ()
30
+
31
+
32
+ def _servers(home: Path) -> Path:
33
+ return home / ".local" / "share" / "maintainability-agent" / "servers"
34
+
35
+
36
+ def register(home: Path, pid: int, version: str) -> Path:
37
+ folder = _servers(home)
38
+ folder.mkdir(parents=True, exist_ok=True)
39
+ record = folder / f"{pid}.json"
40
+ record.write_text(json.dumps({"pid": pid, "version": version}) + "\n", encoding="utf-8")
41
+ return record
42
+
43
+
44
+ def unregister(home: Path, pid: int) -> None:
45
+ (_servers(home) / f"{pid}.json").unlink(missing_ok=True)
46
+
47
+
48
+ @contextmanager
49
+ def busy(home: Path, pid: int) -> Iterator[None]:
50
+ folder = _servers(home)
51
+ folder.mkdir(parents=True, exist_ok=True)
52
+ marker = folder / f"{pid}.busy"
53
+ marker.touch()
54
+ try:
55
+ yield
56
+ finally:
57
+ marker.unlink(missing_ok=True)
58
+
59
+
60
+ def _alive(pid: int) -> bool:
61
+ try:
62
+ os.kill(pid, 0)
63
+ except ProcessLookupError:
64
+ return False
65
+ except PermissionError:
66
+ return True
67
+ return True
68
+
69
+
70
+ def _is_server(pid: int) -> bool:
71
+ """The pid is still an MA MCP server, not a reused pid of something else."""
72
+ result = _runner.run("mcp-servers", _runner.Invocation(argv=("ps", "-o", "command=", "-p", str(pid))),
73
+ timeout_seconds=10)
74
+ command = result.stdout or ""
75
+ return "maintainability" in command and "mcp" in command
76
+
77
+
78
+ def stop_stale(home: Path, installed: str, *,
79
+ alive: Callable[[int], bool] = _alive,
80
+ is_server: Callable[[int], bool] = _is_server,
81
+ kill: Callable[[int, int], None] = os.kill) -> Stopped:
82
+ folder = _servers(home)
83
+ stopped: list[int] = []
84
+ held: list[int] = []
85
+ gone: list[int] = []
86
+ for record in sorted(folder.glob("*.json")) if folder.is_dir() else []:
87
+ try:
88
+ data = json.loads(record.read_text(encoding="utf-8"))
89
+ pid, version = int(data["pid"]), str(data["version"])
90
+ except (OSError, ValueError, KeyError, TypeError):
91
+ record.unlink(missing_ok=True)
92
+ continue
93
+ if version == installed:
94
+ continue
95
+ if not alive(pid):
96
+ record.unlink(missing_ok=True)
97
+ gone.append(pid)
98
+ elif (folder / f"{pid}.busy").exists():
99
+ held.append(pid)
100
+ elif not is_server(pid):
101
+ record.unlink(missing_ok=True)
102
+ gone.append(pid)
103
+ else:
104
+ kill(pid, signal.SIGTERM)
105
+ record.unlink(missing_ok=True)
106
+ stopped.append(pid)
107
+ return Stopped(tuple(stopped), tuple(held), tuple(gone))
@@ -12,7 +12,8 @@ backwards — so this module holds no HTTP client and reads no release feed
12
12
  acquisition). Every child process goes through ``_runner.run`` (rule 7). A
13
13
  version that comes back lower than before is reported, never accepted
14
14
  silently; a higher one re-syncs the skill and records that the MCP server,
15
- which holds the code it loaded at spawn, needs a restart.
15
+ which holds the code it loaded at spawn, needs a restart; stale servers
16
+ that are not mid-audit are stopped so their host restarts them (D232).
16
17
  """
17
18
 
18
19
  from __future__ import annotations
@@ -23,7 +24,7 @@ import sys
23
24
  from dataclasses import dataclass
24
25
  from pathlib import Path
25
26
 
26
- from . import _runner
27
+ from . import _mcp_servers, _runner
27
28
 
28
29
  PACKAGE = "maintainability-agent"
29
30
  #: The launch agent, named for the product and the component (reverse DNS of
@@ -81,14 +82,28 @@ def update(python: str, uv: str | None, home: Path) -> UpdateResult:
81
82
  f"version went down from {before} to {after}",
82
83
  f"Refused: the install moved {before} to {after}, a downgrade.")
83
84
  if _key(after) == _key(before):
84
- return UpdateResult(before, after, False, False, None, f"Already up to date ({after}).")
85
+ return UpdateResult(before, after, False, False, None,
86
+ f"Already up to date ({after}).{_servers_note(home, after)}")
85
87
  _run([python, "-m", "maintainability_audit", "--install-skill"])
86
88
  state = _state_dir(home)
87
89
  state.mkdir(parents=True, exist_ok=True)
88
90
  (state / ".pending-restart").write_text(after + "\n", encoding="utf-8")
89
91
  return UpdateResult(before, after, True, True, None,
90
- f"Updated {before} -> {after}; skill re-synced. "
91
- "Restart the MCP server to use it (/mcp in Claude Code).")
92
+ f"Updated {before} -> {after}; skill re-synced.{_servers_note(home, after)}")
93
+
94
+
95
+ def _servers_note(home: Path, installed: str) -> str:
96
+ """Stop the MCP servers still on an older version (D232) and say so.
97
+ A host starts a stopped stdio server again on its next call."""
98
+ result = _mcp_servers.stop_stale(home, installed)
99
+ note = ""
100
+ if result.stopped:
101
+ note += (f" Stopped {len(result.stopped)} MCP server(s) on an older version;"
102
+ f" the host starts {installed} on its next call.")
103
+ if result.busy:
104
+ note += (f" {len(result.busy)} busy with an audit kept running;"
105
+ " the next update stops it.")
106
+ return note
92
107
 
93
108
 
94
109
  def update_action() -> int:
@@ -16,9 +16,11 @@ string, or invokes a shell.
16
16
  from __future__ import annotations
17
17
 
18
18
  import argparse
19
+ import os
19
20
  from pathlib import Path
20
21
  from typing import Any
21
22
 
23
+ from . import _mcp_servers
22
24
  from ._catalog import PolicyError as PolicyError
23
25
 
24
26
  # Redundant aliases on purpose: every name the split moved to
@@ -263,21 +265,23 @@ def _run_audit_tool(ledger, tool_error, repository_root, config_path, changed_on
263
265
  """
264
266
  try:
265
267
  _apply_call_consents(ledger, repository_root, setup, grant, setup_answers)
266
- return audit_repository(
267
- repository_root,
268
- config_path,
269
- changed_only,
270
- run_analyzers,
271
- format,
272
- record_history,
273
- baseline_path,
274
- write_baseline,
275
- include_prompt,
276
- # Interactive door never assumes go (D27); CLI default is "run".
277
- action=action,
278
- roots=ledger.current(),
279
- output_path=output_path,
280
- )
268
+ # Busy while auditing: `--update` never stops a server mid-audit (D232).
269
+ with _mcp_servers.busy(Path.home(), os.getpid()):
270
+ return audit_repository(
271
+ repository_root,
272
+ config_path,
273
+ changed_only,
274
+ run_analyzers,
275
+ format,
276
+ record_history,
277
+ baseline_path,
278
+ write_baseline,
279
+ include_prompt,
280
+ # Interactive door never assumes go (D27); CLI default is "run".
281
+ action=action,
282
+ roots=ledger.current(),
283
+ output_path=output_path,
284
+ )
281
285
  except ANTICIPATED_REFUSALS as refusal:
282
286
  raise tool_error(str(refusal)) from refusal
283
287
 
@@ -548,7 +552,12 @@ def _parser() -> argparse.ArgumentParser:
548
552
 
549
553
  def main(argv: list[str] | None = None) -> int:
550
554
  args = _parser().parse_args(argv)
551
- create_server(roots=allowed_roots(tuple(args.allow_root))).run("stdio")
555
+ # Recorded so `--update` can stop this server once it is stale (D232).
556
+ _mcp_servers.register(Path.home(), os.getpid(), VERSION)
557
+ try:
558
+ create_server(roots=allowed_roots(tuple(args.allow_root))).run("stdio")
559
+ finally:
560
+ _mcp_servers.unregister(Path.home(), os.getpid())
552
561
  return 0
553
562
 
554
563
 
@@ -0,0 +1,191 @@
1
+ """D232: running MCP servers are registered so ``--update`` can stop stale ones.
2
+
3
+ Written by the Claude Sonnet test seat (Codex at its usage limit); Codex reviews.
4
+ After an upgrade the old server kept serving old code and /mcp reloads
5
+ nothing. ``_mcp_servers`` keeps one record per server under
6
+ ``<home>/.local/share/maintainability-agent/servers`` and stops, by SIGTERM,
7
+ those running an older version that are not mid-audit.
8
+
9
+ Seams: ``alive``, ``is_server`` and ``kill`` are injected fakes, so no real
10
+ process is signalled. ``home`` is always ``tmp_path``.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import importlib
16
+ import json
17
+ import os
18
+ import signal
19
+ from pathlib import Path
20
+
21
+ import pytest
22
+
23
+ from maintainability_audit import mcp_server
24
+
25
+
26
+ def _ms():
27
+ return importlib.import_module("maintainability_audit._mcp_servers")
28
+
29
+
30
+ def _servers(home: Path) -> Path:
31
+ return home / ".local" / "share" / "maintainability-agent" / "servers"
32
+
33
+
34
+ class _Kill:
35
+ def __init__(self) -> None:
36
+ self.calls: list[tuple[int, int]] = []
37
+
38
+ def __call__(self, pid: int, sig: int) -> None:
39
+ self.calls.append((pid, sig))
40
+
41
+
42
+ def _stop(home: Path, installed: str, *, alive=True, server=True):
43
+ kill = _Kill()
44
+ result = _ms().stop_stale(home, installed, alive=lambda pid: alive,
45
+ is_server=lambda pid: server, kill=kill)
46
+ return result, kill
47
+
48
+
49
+ def test_register_writes_pid_and_version(tmp_path) -> None:
50
+ path = _ms().register(tmp_path, 4242, "4.4.0")
51
+ assert path == _servers(tmp_path) / "4242.json"
52
+ assert json.loads(path.read_text(encoding="utf-8")) == {"pid": 4242, "version": "4.4.0"}
53
+
54
+
55
+ def test_unregister_removes_record_and_tolerates_absence(tmp_path) -> None:
56
+ ms = _ms()
57
+ path = ms.register(tmp_path, 7, "1.0.0")
58
+ ms.unregister(tmp_path, 7)
59
+ assert not path.exists()
60
+ ms.unregister(tmp_path, 7) # absent: no error
61
+
62
+
63
+ def test_busy_marker_exists_only_inside_block(tmp_path) -> None:
64
+ marker = _servers(tmp_path) / "9.busy"
65
+ with _ms().busy(tmp_path, 9):
66
+ assert marker.exists()
67
+ assert not marker.exists()
68
+
69
+
70
+ def test_busy_marker_removed_when_body_raises(tmp_path) -> None:
71
+ marker = _servers(tmp_path) / "9.busy"
72
+ with pytest.raises(RuntimeError), _ms().busy(tmp_path, 9):
73
+ raise RuntimeError("audit blew up")
74
+ assert not marker.exists()
75
+
76
+
77
+ def test_stale_live_server_is_sigtermed_and_record_removed(tmp_path) -> None:
78
+ ms = _ms()
79
+ path = ms.register(tmp_path, 100, "4.4.0")
80
+ result, kill = _stop(tmp_path, "4.5.0")
81
+ assert kill.calls == [(100, signal.SIGTERM)]
82
+ assert result.stopped == (100,) and result.busy == () and result.gone == ()
83
+ assert not path.exists()
84
+
85
+
86
+ def test_current_version_server_is_untouched(tmp_path) -> None:
87
+ path = _ms().register(tmp_path, 100, "4.5.0")
88
+ result, kill = _stop(tmp_path, "4.5.0")
89
+ assert kill.calls == []
90
+ assert (result.stopped, result.busy, result.gone) == ((), (), ())
91
+ assert path.exists()
92
+
93
+
94
+ def test_dead_pid_record_is_removed_and_reported_gone(tmp_path) -> None:
95
+ path = _ms().register(tmp_path, 100, "4.4.0")
96
+ result, kill = _stop(tmp_path, "4.5.0", alive=False)
97
+ assert kill.calls == []
98
+ assert result.gone == (100,)
99
+ assert not path.exists()
100
+
101
+
102
+ def test_busy_server_is_left_alone_and_reported_busy(tmp_path) -> None:
103
+ ms = _ms()
104
+ path = ms.register(tmp_path, 100, "4.4.0")
105
+ with ms.busy(tmp_path, 100):
106
+ result, kill = _stop(tmp_path, "4.5.0")
107
+ assert kill.calls == []
108
+ assert result.busy == (100,) and result.stopped == ()
109
+ assert path.exists()
110
+
111
+
112
+ def test_reused_pid_is_never_killed(tmp_path) -> None:
113
+ path = _ms().register(tmp_path, 100, "4.4.0")
114
+ result, kill = _stop(tmp_path, "4.5.0", server=False)
115
+ assert kill.calls == []
116
+ assert result.gone == (100,) and result.stopped == ()
117
+ assert not path.exists()
118
+
119
+
120
+ def test_garbage_record_is_removed_without_crashing(tmp_path) -> None:
121
+ ms = _ms()
122
+ ms.register(tmp_path, 1, "4.4.0") # makes the directory
123
+ bad = _servers(tmp_path) / "555.json"
124
+ bad.write_text("{not json", encoding="utf-8")
125
+ result, kill = _stop(tmp_path, "4.5.0")
126
+ assert not bad.exists()
127
+ assert 555 not in result.stopped
128
+ assert (555, signal.SIGTERM) not in kill.calls
129
+
130
+
131
+ def test_stop_stale_without_servers_dir_is_empty(tmp_path) -> None:
132
+ result, kill = _stop(tmp_path, "4.5.0")
133
+ assert (result.stopped, result.busy, result.gone) == ((), (), ())
134
+ assert kill.calls == []
135
+
136
+
137
+ # mcp_server wiring ---------------------------------------------------------
138
+
139
+ def test_main_registers_during_run_and_unregisters_after(tmp_path, monkeypatch) -> None:
140
+ monkeypatch.setenv("HOME", str(tmp_path))
141
+ record = _servers(tmp_path) / f"{os.getpid()}.json"
142
+ seen: dict = {}
143
+
144
+ class _Stub:
145
+ def run(self, transport: str) -> None:
146
+ seen["during"] = json.loads(record.read_text(encoding="utf-8"))
147
+
148
+ monkeypatch.setattr(mcp_server, "create_server", lambda **_kw: _Stub())
149
+ assert mcp_server.main(["--allow-root", str(tmp_path)]) == 0
150
+ assert seen["during"] == {"pid": os.getpid(), "version": mcp_server.VERSION}
151
+ assert not record.exists()
152
+
153
+
154
+ def test_main_unregisters_when_run_raises(tmp_path, monkeypatch) -> None:
155
+ monkeypatch.setenv("HOME", str(tmp_path))
156
+ record = _servers(tmp_path) / f"{os.getpid()}.json"
157
+
158
+ seen: dict = {}
159
+
160
+ class _Stub:
161
+ def run(self, transport: str) -> None:
162
+ seen["registered"] = record.exists()
163
+ raise RuntimeError("transport died")
164
+
165
+ monkeypatch.setattr(mcp_server, "create_server", lambda **_kw: _Stub())
166
+ with pytest.raises(RuntimeError):
167
+ mcp_server.main(["--allow-root", str(tmp_path)])
168
+ assert seen["registered"] is True
169
+ assert not record.exists()
170
+
171
+
172
+ def test_audit_tool_holds_busy_marker_while_auditing(tmp_path, monkeypatch) -> None:
173
+ monkeypatch.setenv("HOME", str(tmp_path))
174
+ marker = _servers(tmp_path) / f"{os.getpid()}.busy"
175
+ seen: dict = {}
176
+
177
+ def fake_audit(*_args, **_kwargs):
178
+ seen["busy"] = marker.exists()
179
+ return {"audit_ran": False}
180
+
181
+ class _Ledger:
182
+ def current(self):
183
+ return ()
184
+
185
+ monkeypatch.setattr(mcp_server, "audit_repository", fake_audit)
186
+ monkeypatch.setattr(mcp_server, "_apply_call_consents", lambda *a, **k: None)
187
+ mcp_server._run_audit_tool(
188
+ _Ledger(), RuntimeError, str(tmp_path), None, None, None, None, None,
189
+ None, False, True, "run", None, None, None)
190
+ assert seen["busy"] is True
191
+ assert not marker.exists()
@@ -159,6 +159,7 @@ def test_version_order_is_numeric_not_lexical(fake, tmp_path) -> None:
159
159
  # 5 -- upgrade --------------------------------------------------------------
160
160
 
161
161
  def test_upgrade_syncs_skill_writes_marker_and_says_restart(fake, tmp_path) -> None:
162
+ """Covers existing behaviour: skill sync and marker (the "/mcp" assertion moved to D232)."""
162
163
  runner = fake(["4.4.0", "4.5.0"])
163
164
  result = _su().update(PY, UV, tmp_path)
164
165
  assert [PY, "-m", "maintainability_audit", "--install-skill"] in [
@@ -167,7 +168,65 @@ def test_upgrade_syncs_skill_writes_marker_and_says_restart(fake, tmp_path) -> N
167
168
  assert result.restart_needed is True
168
169
  assert not result.error
169
170
  assert _marker(tmp_path).read_text(encoding="utf-8").strip() == "4.5.0"
170
- assert "/mcp" in result.message
171
+
172
+
173
+ # 5b -- D232: stop stale MCP servers --------------------------------------
174
+
175
+ def _stopper(monkeypatch, *, stopped=(), busy=(), gone=()):
176
+ """Replace ``_mcp_servers.stop_stale`` with a fake returning fixed pids."""
177
+ ms = importlib.import_module("maintainability_audit._mcp_servers")
178
+ calls = []
179
+
180
+ def fake_stop(home, installed, **kwargs):
181
+ calls.append((home, installed))
182
+ return ms.Stopped(stopped=tuple(stopped), busy=tuple(busy), gone=tuple(gone))
183
+
184
+ monkeypatch.setattr(ms, "stop_stale", fake_stop)
185
+ return calls
186
+
187
+
188
+ def test_upgrade_stops_stale_servers_and_says_so(fake, tmp_path, monkeypatch) -> None:
189
+ """D232: the message reports the stop and never points at /mcp."""
190
+ fake(["4.4.0", "4.5.0"])
191
+ calls = _stopper(monkeypatch, stopped=(101,))
192
+ message = _su().update(PY, UV, tmp_path).message
193
+ assert calls == [(tmp_path, "4.5.0")]
194
+ assert "Stopped 1" in message and "next call" in message
195
+ assert "/mcp" not in message
196
+
197
+
198
+ def test_upgrade_with_busy_server_says_next_update_stops_it(fake, tmp_path,
199
+ monkeypatch) -> None:
200
+ """D232: a mid-audit server is skipped and named as busy."""
201
+ fake(["4.4.0", "4.5.0"])
202
+ _stopper(monkeypatch, busy=(202,))
203
+ message = _su().update(PY, UV, tmp_path).message
204
+ assert "1 busy" in message and "next update" in message
205
+ assert "/mcp" not in message
206
+
207
+
208
+ def test_upgrade_message_never_mentions_mcp_command_with_no_servers(
209
+ fake, tmp_path, monkeypatch) -> None:
210
+ """D232: even with nothing to stop, the old /mcp advice is gone."""
211
+ fake(["4.4.0", "4.5.0"])
212
+ _stopper(monkeypatch)
213
+ assert "/mcp" not in _su().update(PY, UV, tmp_path).message
214
+
215
+
216
+ def test_already_up_to_date_still_stops_stale_servers(fake, tmp_path, monkeypatch) -> None:
217
+ """D232: a server left behind by an earlier upgrade is stopped by a later no-op update."""
218
+ fake(["4.5.0", "4.5.0"])
219
+ calls = _stopper(monkeypatch, stopped=(101,))
220
+ _su().update(PY, UV, tmp_path)
221
+ assert calls == [(tmp_path, "4.5.0")]
222
+
223
+
224
+ def test_up_to_date_with_nothing_stale_message_unchanged(fake, tmp_path,
225
+ monkeypatch) -> None:
226
+ """D232: nothing stale keeps the plain message."""
227
+ fake(["4.5.0", "4.5.0"])
228
+ _stopper(monkeypatch)
229
+ assert _su().update(PY, UV, tmp_path).message == "Already up to date (4.5.0)."
171
230
 
172
231
 
173
232
  # 6 -- up to date -----------------------------------------------------------