maintainability-agent 4.4.4__tar.gz → 4.4.6__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 (486) hide show
  1. {maintainability_agent-4.4.4/src/maintainability_agent.egg-info → maintainability_agent-4.4.6}/PKG-INFO +28 -9
  2. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/README.md +27 -8
  3. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6/src/maintainability_agent.egg-info}/PKG-INFO +28 -9
  4. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/SOURCES.txt +2 -0
  5. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/__init__.py +1 -1
  6. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_adapters.py +23 -0
  7. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_analysis.py +6 -0
  8. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_jvm_adapters.py +15 -13
  9. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_metric_adapters.py +2 -4
  10. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ratio_adapters.py +4 -5
  11. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/cli.py +9 -2
  12. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_primary_estimate.py +2 -4
  13. maintainability_agent-4.4.6/tests/test_analyzers_leave_no_temp_dirs.py +88 -0
  14. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_artifact_write_route_class.py +15 -9
  15. maintainability_agent-4.4.6/tests/test_base_ref_only_where_it_exists.py +75 -0
  16. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_calibration_corpus.py +5 -3
  17. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_three_presentations.py +9 -7
  18. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_version_stamping.py +5 -3
  19. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/LICENSE +0 -0
  20. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/pyproject.toml +0 -0
  21. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/setup.cfg +0 -0
  22. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/dependency_links.txt +0 -0
  23. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/entry_points.txt +0 -0
  24. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/requires.txt +0 -0
  25. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_agent.egg-info/top_level.txt +0 -0
  26. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/__main__.py +0 -0
  27. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_analyzer_sections.py +0 -0
  28. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_anchor.py +0 -0
  29. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_arguments.py +0 -0
  30. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_aspects.py +0 -0
  31. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_assets/analyzer-catalog.json +0 -0
  32. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_assets/standard.md +0 -0
  33. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_attestation.py +0 -0
  34. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_backfill.py +0 -0
  35. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_bands.py +0 -0
  36. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_banner.py +0 -0
  37. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_built_ins.py +0 -0
  38. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_calibration.py +0 -0
  39. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_catalog.py +0 -0
  40. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_changed_code_policy.py +0 -0
  41. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_charts.py +0 -0
  42. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_cognitive.py +0 -0
  43. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_config_defaults.py +0 -0
  44. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_conformance.py +0 -0
  45. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_corroborate.py +0 -0
  46. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_coverage_notes.py +0 -0
  47. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_criteria_scope.py +0 -0
  48. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_delegated_pillar.py +0 -0
  49. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_derive.py +0 -0
  50. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_discovery.py +0 -0
  51. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_documents.py +0 -0
  52. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_economics.py +0 -0
  53. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_economics_view.py +0 -0
  54. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_environment.py +0 -0
  55. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_evidence_reader.py +0 -0
  56. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_evidence_view.py +0 -0
  57. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_finding_match.py +0 -0
  58. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_first_run.py +0 -0
  59. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_formula.py +0 -0
  60. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_gates.py +0 -0
  61. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_generic.py +0 -0
  62. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_grammar.py +0 -0
  63. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_grant_ledger.py +0 -0
  64. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_handoff.py +0 -0
  65. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_history_view.py +0 -0
  66. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_hostile_prompt.py +0 -0
  67. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_hotspots.py +0 -0
  68. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_html_report_sections.py +0 -0
  69. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_html_view.py +0 -0
  70. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_identity.py +0 -0
  71. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_in_loop.py +0 -0
  72. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_in_loop_view.py +0 -0
  73. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_markdown_sections.py +0 -0
  74. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_masking.py +0 -0
  75. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_audit.py +0 -0
  76. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_gate.py +0 -0
  77. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_grants.py +0 -0
  78. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_refusals.py +0 -0
  79. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_resources.py +0 -0
  80. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_servers.py +0 -0
  81. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_mcp_setup.py +0 -0
  82. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_metrics_types.py +0 -0
  83. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_operator_reads.py +0 -0
  84. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_oracle.py +0 -0
  85. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_pillars.py +0 -0
  86. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_pipeline_results.py +0 -0
  87. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_practice.py +0 -0
  88. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_precommit.py +0 -0
  89. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_precommit_install.py +0 -0
  90. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_precommit_view.py +0 -0
  91. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_pressures.py +0 -0
  92. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_prompt_sections.py +0 -0
  93. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_c.py +0 -0
  94. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_cobol.py +0 -0
  95. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_core.py +0 -0
  96. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_cpp.py +0 -0
  97. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_csharp.py +0 -0
  98. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_fortran.py +0 -0
  99. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_go.py +0 -0
  100. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_java.py +0 -0
  101. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_js.py +0 -0
  102. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_kotlin.py +0 -0
  103. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_php.py +0 -0
  104. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_ruby.py +0 -0
  105. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_rust.py +0 -0
  106. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_shell.py +0 -0
  107. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ranges_swift.py +0 -0
  108. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_ratchet.py +0 -0
  109. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_recurrence.py +0 -0
  110. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_run_comparison.py +0 -0
  111. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_runner.py +0 -0
  112. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_running_version.py +0 -0
  113. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_safe_write.py +0 -0
  114. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_scan_history.py +0 -0
  115. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_scan_view.py +0 -0
  116. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_second_source.py +0 -0
  117. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_security_delegate.py +0 -0
  118. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_security_work_order.py +0 -0
  119. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_selection.py +0 -0
  120. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_self_update.py +0 -0
  121. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_semantic.py +0 -0
  122. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_semantic_policy.py +0 -0
  123. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_semantic_ts.py +0 -0
  124. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_semantic_view.py +0 -0
  125. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_setup_errors.py +0 -0
  126. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_setup_persist.py +0 -0
  127. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/SKILL.md +0 -0
  128. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/agents/anthropic.yaml +0 -0
  129. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/agents/copilot.yaml +0 -0
  130. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/agents/openai.yaml +0 -0
  131. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/copilot/maintainability-agent.prompt.md +0 -0
  132. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_data/references/finding-taxonomy.md +0 -0
  133. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_skill_install.py +0 -0
  134. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_stored_grants.py +0 -0
  135. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_tdd_view.py +0 -0
  136. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_test_commands.py +0 -0
  137. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_test_execution.py +0 -0
  138. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_test_pairing.py +0 -0
  139. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_tokens.py +0 -0
  140. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_tool_adapters.py +0 -0
  141. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_trends.py +0 -0
  142. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_user_config.py +0 -0
  143. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_verdict_adapters.py +0 -0
  144. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_verification.py +0 -0
  145. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_work_order.py +0 -0
  146. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_work_order_view.py +0 -0
  147. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_work_order_weights.py +0 -0
  148. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/_xml.py +0 -0
  149. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/baseline.py +0 -0
  150. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/config.py +0 -0
  151. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/deadcode.py +0 -0
  152. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/declarations.py +0 -0
  153. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/duplication.py +0 -0
  154. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/evidence.py +0 -0
  155. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/git_tools.py +0 -0
  156. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/history.py +0 -0
  157. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/idioms.py +0 -0
  158. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/instructions.py +0 -0
  159. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/mcp_server.py +0 -0
  160. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/metrics.py +0 -0
  161. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/prompts.py +0 -0
  162. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/renderers.py +0 -0
  163. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/report.py +0 -0
  164. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/sarif.py +0 -0
  165. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/scoring.py +0 -0
  166. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/similarity.py +0 -0
  167. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/src/maintainability_audit/source.py +0 -0
  168. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_clone_names_every_copy.py +0 -0
  169. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_dangling_source_link_is_named_not_fatal.py +0 -0
  170. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_format_override_is_disclosed.py +0 -0
  171. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_matching_format_stays_silent.py +0 -0
  172. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_production_name_keeps_its_test_prefix.py +0 -0
  173. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_published_question_offers_what_it_accepts.py +0 -0
  174. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_rendered_docs_site_is_not_scored_as_source.py +0 -0
  175. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_a_setup_question_keeps_its_contract.py +0 -0
  176. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_acquisition_trust.py +0 -0
  177. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_adapter_docs.py +0 -0
  178. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_adapter_recordings.py +0 -0
  179. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_adapters.py +0 -0
  180. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_added_lines.py +0 -0
  181. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_an_absent_work_order_renders_nothing.py +0 -0
  182. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_an_unmeasured_pillar_reports_no_number.py +0 -0
  183. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analysis_coverage.py +0 -0
  184. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analysis_execution.py +0 -0
  185. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_bridge.py +0 -0
  186. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_config_isolation.py +0 -0
  187. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_estimate_claims.py +0 -0
  188. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_file_lists_are_batched.py +0 -0
  189. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_pinning.py +0 -0
  190. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_provenance.py +0 -0
  191. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_provenance_exclusions.py +0 -0
  192. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_scoring_path.py +0 -0
  193. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_spread_range.py +0 -0
  194. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzer_xml_bounds.py +0 -0
  195. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzers_against_the_real_tools.py +0 -0
  196. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzers_never_write.py +0 -0
  197. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_analyzers_report_what_actually_failed.py +0 -0
  198. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_anchor_and_mode.py +0 -0
  199. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_anchor_caveat_and_counts_follow_the_run.py +0 -0
  200. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_anchor_disclosure.py +0 -0
  201. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_annotations_match_behaviour.py +0 -0
  202. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_anticipated_refusals.py +0 -0
  203. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_architecture.py +0 -0
  204. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_aspect_coverage.py +0 -0
  205. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_asset_snapshot_class.py +0 -0
  206. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ast_reading_resolves_spellings.py +0 -0
  207. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_attestation.py +0 -0
  208. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_audit_components.py +0 -0
  209. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_authorization_freshness.py +0 -0
  210. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_authorship_gates.py +0 -0
  211. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_backfill.py +0 -0
  212. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_band_concealment_class.py +0 -0
  213. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_band_concealment_p3.py +0 -0
  214. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_band_pressures.py +0 -0
  215. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_bands.py +0 -0
  216. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_behaviour_suites_are_tests.py +0 -0
  217. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_body_or_signature_class.py +0 -0
  218. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_both_setup_paths_ask_the_same_stage.py +0 -0
  219. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_build_output_is_not_the_repositorys_code.py +0 -0
  220. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_c_declarations.py +0 -0
  221. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_calibration_drift.py +0 -0
  222. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_calibration_tooling.py +0 -0
  223. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_catalog_selection.py +0 -0
  224. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_catalog_tier_promise.py +0 -0
  225. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_changed_code_policy.py +0 -0
  226. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_chat_leads_with_the_work_order.py +0 -0
  227. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_chat_primary_docs.py +0 -0
  228. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_check_refuses_plus_only_fragments.py +0 -0
  229. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_checkstyle_adapter.py +0 -0
  230. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_checkstyle_catalog.py +0 -0
  231. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_child_sandbox.py +0 -0
  232. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ci_history_recipe.py +0 -0
  233. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ci_installs_the_analyzer_pool.py +0 -0
  234. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ci_runs_once.py +0 -0
  235. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_claimed_languages.py +0 -0
  236. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_clean_sees_the_weakened_oracle.py +0 -0
  237. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cli.py +0 -0
  238. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_clone_group_class.py +0 -0
  239. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cobol_declarations.py +0 -0
  240. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_code_scanning_gets_alerts_not_the_record.py +0 -0
  241. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cognitive_complexity.py +0 -0
  242. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cohesion_with_nothing_to_read_is_not_applicable.py +0 -0
  243. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cohort_statistics.py +0 -0
  244. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_concealment_properties.py +0 -0
  245. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_config_shape.py +0 -0
  246. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_conformance_reads_the_operators_ask.py +0 -0
  247. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consent_and_grant.py +0 -0
  248. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consent_is_per_repository.py +0 -0
  249. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consent_survives_setup_and_is_asked.py +0 -0
  250. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consent_without_command_has_a_remedy.py +0 -0
  251. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_consumer_migration.py +0 -0
  252. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_contract_claims.py +0 -0
  253. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_corpus_note_counts_come_from_the_corpus.py +0 -0
  254. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_corroborate.py +0 -0
  255. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_coverage_by_language.py +0 -0
  256. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_coverage_config_reaches_children.py +0 -0
  257. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_coverage_formats.py +0 -0
  258. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_cpp_declarations.py +0 -0
  259. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_criteria_completion.py +0 -0
  260. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_csharp_declarations.py +0 -0
  261. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_current_state_docs_name_every_parsed_language.py +0 -0
  262. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_d15_composition.py +0 -0
  263. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_d15_goal_directed.py +0 -0
  264. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_dead_code.py +0 -0
  265. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_criteria_scope.py +0 -0
  266. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_edge_cases.py +0 -0
  267. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_grading.py +0 -0
  268. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_ranges.py +0 -0
  269. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declaration_source.py +0 -0
  270. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declarative_parsers.py +0 -0
  271. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declared_capabilities_match_the_delegate.py +0 -0
  272. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_declared_imports.py +0 -0
  273. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_delegated_security_pillar.py +0 -0
  274. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_demo_tree.py +0 -0
  275. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_derivation_mix.py +0 -0
  276. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_determinism.py +0 -0
  277. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_dimension_ratchet.py +0 -0
  278. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_direct_runner_availability_class.py +0 -0
  279. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_discovery.py +0 -0
  280. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_doc_claims.py +0 -0
  281. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_docs_links.py +0 -0
  282. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_economic_context.py +0 -0
  283. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_empty_output_not_clean.py +0 -0
  284. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_empty_output_not_clean_adapters.py +0 -0
  285. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_environment_work_order.py +0 -0
  286. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_built_presentation_is_offered.py +0 -0
  287. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_job_tests_the_pinned_oracle.py +0 -0
  288. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_language_counts_its_own_loop.py +0 -0
  289. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_language_has_a_loop_fixture.py +0 -0
  290. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_pool_install_is_the_same_pool.py +0 -0
  291. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_question_can_be_answered.py +0 -0
  292. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_every_surface_says_what_the_run_found.py +0 -0
  293. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_evidence_invariants.py +0 -0
  294. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_evidence_normalization.py +0 -0
  295. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_evidence_properties.py +0 -0
  296. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_example_config_opens_claimed_languages.py +0 -0
  297. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_exclude_additional_keeps_the_defaults.py +0 -0
  298. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_exclusion_dialects.py +0 -0
  299. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_exposure_never_outranks_band.py +0 -0
  300. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_falsifier_standard.py +0 -0
  301. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_file_list_cap_class.py +0 -0
  302. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_finding_identity.py +0 -0
  303. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_first_run_elicitation.py +0 -0
  304. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_first_run_prompt.py +0 -0
  305. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_first_run_reelicitation.py +0 -0
  306. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_first_stage_setup_wording_holds.py +0 -0
  307. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fix_breadth_window.py +0 -0
  308. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fixed_form_fortran.py +0 -0
  309. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_format_ask.py +0 -0
  310. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fortran_declarations.py +0 -0
  311. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fortran_metrics.py +0 -0
  312. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_fortran_practice.py +0 -0
  313. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_git_argv.py +0 -0
  314. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_git_read_only.py +0 -0
  315. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_git_readonly_class.py +0 -0
  316. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_go_declarations.py +0 -0
  317. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_grammar_constructs.py +0 -0
  318. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_grammar_token_coverage.py +0 -0
  319. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_grant_only_user_tier.py +0 -0
  320. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_grok_audit_of_3_11.py +0 -0
  321. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history.py +0 -0
  322. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history_boundary.py +0 -0
  323. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history_manifest.py +0 -0
  324. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history_schema2.py +0 -0
  325. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_history_window.py +0 -0
  326. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_hostile_prompt.py +0 -0
  327. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_html_executive.py +0 -0
  328. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_html_section_parity_class.py +0 -0
  329. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_identity_docs.py +0 -0
  330. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_identity_resolution.py +0 -0
  331. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_idiom_divergence.py +0 -0
  332. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_in_loop_budgets.py +0 -0
  333. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_in_loop_check.py +0 -0
  334. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_installed_wheel_runtime.py +0 -0
  335. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_instruction_targets.py +0 -0
  336. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_java_range_guard.py +0 -0
  337. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_java_ranges.py +0 -0
  338. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_java_scored.py +0 -0
  339. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_java_wiring.py +0 -0
  340. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_js_complexity_operators.py +0 -0
  341. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_js_declarations.py +0 -0
  342. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_kotlin_declarations.py +0 -0
  343. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_kotlin_metrics.py +0 -0
  344. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_language_coverage.py +0 -0
  345. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_language_support_honesty.py +0 -0
  346. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_list_tools_publishes_the_answer_path.py +0 -0
  347. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_local_gate.py +0 -0
  348. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_maintenance_signals.py +0 -0
  349. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_baseline_payload.py +0 -0
  350. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_format_contract.py +0 -0
  351. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_history.py +0 -0
  352. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_server.py +0 -0
  353. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_servers.py +0 -0
  354. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mcp_start_failure_names_what_is_installed.py +0 -0
  355. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_migration_1_0.py +0 -0
  356. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_missing_security_scanners_are_named_before_the_run.py +0 -0
  357. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_mutation_recorded.py +0 -0
  358. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_near_duplicates.py +0 -0
  359. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_network_disclosure.py +0 -0
  360. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_no_private_names.py +0 -0
  361. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_one_setup_across_surfaces_class.py +0 -0
  362. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_operator_named_paths.py +0 -0
  363. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_operator_named_reads.py +0 -0
  364. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_oracle_weakening_precision_bar.py +0 -0
  365. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pairing_reads_imports.py +0 -0
  366. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pattern_budget.py +0 -0
  367. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_phase6_claims.py +0 -0
  368. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_php_declarations.py +0 -0
  369. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pillars_and_practice.py +0 -0
  370. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pipeline_results.py +0 -0
  371. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_platform_claim.py +0 -0
  372. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pmd_adapter.py +0 -0
  373. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pmd_audit_closures.py +0 -0
  374. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_policy_claims.py +0 -0
  375. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_pool_runs_by_config.py +0 -0
  376. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_population_floors.py +0 -0
  377. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_practice_nested_gates_class.py +0 -0
  378. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_precommit_staged.py +0 -0
  379. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_preflight_before_consent_runs_nothing_from_the_tree.py +0 -0
  380. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_presentation_refusals.py +0 -0
  381. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_previous_release_reached_pypi.py +0 -0
  382. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_promises.py +0 -0
  383. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prompt_does_not_issue_rates_when_unscored.py +0 -0
  384. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prompt_escalation_once.py +0 -0
  385. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prompt_honesty.py +0 -0
  386. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prompt_location_escalation_class.py +0 -0
  387. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_prove_falsifiers.py +0 -0
  388. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_python_complexity.py +0 -0
  389. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_python_declarations.py +0 -0
  390. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_read_boundary.py +0 -0
  391. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_readme_claims.py +0 -0
  392. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_recurrence.py +0 -0
  393. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_regular_file_reads_work_without_o_nonblock.py +0 -0
  394. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_release_needs_an_empty_ledger.py +0 -0
  395. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_release_plan.py +0 -0
  396. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_release_plan_status.py +0 -0
  397. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_rendered_docs.py +0 -0
  398. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_report_remedy_copy.py +0 -0
  399. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_reported_but_not_scored.py +0 -0
  400. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_root_grants.py +0 -0
  401. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_rubric_ignores_project_lint_config.py +0 -0
  402. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_ruby_declarations.py +0 -0
  403. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_run_comparison.py +0 -0
  404. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_runner.py +0 -0
  405. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_rust_declarations.py +0 -0
  406. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_sarif.py +0 -0
  407. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scan_history.py +0 -0
  408. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scan_scope.py +0 -0
  409. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scanner_fingerprint_covers_the_measurement_path.py +0 -0
  410. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scanner_unsafe_direction.py +0 -0
  411. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scanning.py +0 -0
  412. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_schema_fidelity.py +0 -0
  413. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scope_conformance.py +0 -0
  414. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_scoring_calibration.py +0 -0
  415. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_security_delegate_versions_agree.py +0 -0
  416. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_security_findings_keep_their_handoff.py +0 -0
  417. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_security_pillar_asserts_a_scanner_set.py +0 -0
  418. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_security_pillar_runs_and_shows.py +0 -0
  419. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_selection_covers_every_parsed_language.py +0 -0
  420. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_self_update.py +0 -0
  421. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_semantic_findings_stay_inside_the_audited_files.py +0 -0
  422. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_semantic_policy.py +0 -0
  423. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_answers_are_the_same_setup.py +0 -0
  424. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_gate_completeness.py +0 -0
  425. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_gate_independent_contract.py +0 -0
  426. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_instruction_describes_its_own_reply.py +0 -0
  427. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_precondition.py +0 -0
  428. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_setup_writes_a_valid_config.py +0 -0
  429. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_shell_declarations.py +0 -0
  430. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_shell_metrics.py +0 -0
  431. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_skill_install.py +0 -0
  432. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_sonar_resolve.py +0 -0
  433. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_source_index.py +0 -0
  434. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_spotbugs_adapter.py +0 -0
  435. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_spotbugs_catalog.py +0 -0
  436. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_stage8_contract.py +0 -0
  437. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_stamped_documents_stay_honest.py +0 -0
  438. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_stdout_outputs.py +0 -0
  439. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_suite_isolation.py +0 -0
  440. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_swift_declarations.py +0 -0
  441. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tdd_structure.py +0 -0
  442. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_terminal_asks_the_same_questions.py +0 -0
  443. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_test_commands.py +0 -0
  444. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_test_execution_class.py +0 -0
  445. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_agent_knows_when_it_is_stale.py +0 -0
  446. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_changelog_covers_the_shipping_version.py +0 -0
  447. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_chat_payload_has_a_budget.py +0 -0
  448. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_condition_says_what_it_measured.py +0 -0
  449. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_handoff_rules_are_their_own_module.py +0 -0
  450. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_pillar_row_reads_cleanly.py +0 -0
  451. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_presentation_question_stays_answerable.py +0 -0
  452. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_previous_release_was_tagged.py +0 -0
  453. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_prompt_does_not_take_back_what_it_withheld.py +0 -0
  454. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_prompt_keeps_listing_what_it_did_not_withhold.py +0 -0
  455. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_release_process_describes_itself.py +0 -0
  456. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_release_record_stays_well_formed.py +0 -0
  457. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_report_is_saved_not_sent.py +0 -0
  458. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_security_run_has_a_configurable_limit.py +0 -0
  459. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_security_work_order_is_drawn.py +0 -0
  460. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_suite_names_the_program_it_ran.py +0 -0
  461. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_tree_cannot_redirect_a_read.py +0 -0
  462. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_the_version_has_one_source.py +0 -0
  463. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tool_resolution.py +0 -0
  464. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tree_cannot_opt_the_host_in.py +0 -0
  465. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tree_chosen_spawn.py +0 -0
  466. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_tree_reads_use_the_primitive.py +0 -0
  467. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_trends.py +0 -0
  468. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_type_fields_not_functions_class.py +0 -0
  469. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_uat_falsifiers.py +0 -0
  470. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_unanchored_set_matches_corpus.py +0 -0
  471. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_unread_code.py +0 -0
  472. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_user_config_tier.py +0 -0
  473. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_verification_audit_closures.py +0 -0
  474. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_verified_grade.py +0 -0
  475. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_version_claim.py +0 -0
  476. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_wheel_contents.py +0 -0
  477. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_withheld_work_keeps_its_boundary.py +0 -0
  478. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_items_state_their_own_finding.py +0 -0
  479. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_order.py +0 -0
  480. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_order_binds_to_this_interpreter.py +0 -0
  481. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_order_items.py +0 -0
  482. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_work_order_selection.py +0 -0
  483. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_workflow_supply_chain.py +0 -0
  484. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_write_boundary.py +0 -0
  485. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/tests/test_write_route_class.py +0 -0
  486. {maintainability_agent-4.4.4 → maintainability_agent-4.4.6}/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.4
3
+ Version: 4.4.6
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.4**.
50
+ Version **4.4.6**.
51
51
 
52
52
  > ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
53
53
  >
@@ -90,10 +90,12 @@ npm install -g jscpd eslint # duplication + JavaScript/TypeScript
90
90
  brew install pmd checkstyle spotbugs # JVM languages, optional
91
91
  ```
92
92
 
93
- Unpinned on purpose: this is the exact set CI installs and calibrates against,
94
- and `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
95
- disagree. Nothing here is required — the audit runs without any of it and tells
96
- you what it could not measure.
93
+ This is the exact set CI installs, and
94
+ `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
95
+ disagree. CI installs it at the versions in `constraints/analyzers.txt`, the
96
+ ones the scale was calibrated with; add `-c constraints/analyzers.txt` from a
97
+ source checkout to match them. Nothing here is required — the audit runs
98
+ without any of it and tells you what it could not measure.
97
99
 
98
100
  **Install secure-code-agent for the security pillar.** Every audit runs it; it is
99
101
  installed alongside rather than as a dependency, so the two tools release
@@ -204,6 +206,7 @@ The full argument, including what this deliberately does not compete on:
204
206
  ```bash
205
207
  python3 -m pip install maintainability-agent
206
208
  maintainability-agent --root . --config maintainability-agent.json
209
+ maintainability-agent --update # later: upgrade, re-sync the skill, restart stale MCP servers
207
210
  ```
208
211
 
209
212
  Or run from a source checkout without installing:
@@ -267,6 +270,21 @@ withheld estimate. For PR work, add `--changed-only main...HEAD` to audit the
267
270
  diff; on a change too small to support a rate, the estimate and grade are
268
271
  withheld and the scope is named as the reason.
269
272
 
273
+ **Hold the code a change touches to a stricter bar.** `policy.changed_code` in
274
+ `maintainability-agent.json` sets tighter function limits for what a change
275
+ adds or alters, so a team can gate new work without first fixing every old
276
+ function:
277
+
278
+ ```json
279
+ "policy": {"changed_code": {"max_function_lines": 40, "max_complexity": 10}}
280
+ ```
281
+
282
+ On a `--changed-only` run, a function the change touched is held to it and
283
+ untouched code is judged by the standard as before. A policy only tightens — a
284
+ looser limit is refused when the config loads — and it decides the gate, never
285
+ the grade: breaches fail `--fail-on-gate` and are listed under *Changed-code
286
+ policy*, and the score is unchanged.
287
+
270
288
  ### Checking that the agent did the work
271
289
 
272
290
  The work order tells an agent to fix exactly these findings and refactor nothing
@@ -503,8 +521,9 @@ maintainability-agent --install-skill # writes ~/.claude/skills
503
521
  ```
504
522
 
505
523
  `maintainability-agent --update` upgrades the install to the newest release —
506
- never a downgrade — re-syncs the skill, and says when the MCP server needs a
507
- restart; `maintainability-agent --install-updater` runs it hourly (macOS launch
524
+ never a downgrade — re-syncs the skill, and stops any MCP server still on an
525
+ older version that is not mid-audit, so the host starts the new one on its
526
+ next call; `maintainability-agent --install-updater` runs it hourly (macOS launch
508
527
  agent). Run `--install-skill` by hand after any other upgrade — a drifted skill
509
528
  teaches agents a dead workflow,
510
529
  so a differing installed copy is refused with the list of differences. Per-host
@@ -517,7 +536,7 @@ instead of an invokable skill:
517
536
  This repo ships `action.yml`, usable as a composite action:
518
537
 
519
538
  ```yaml
520
- - uses: marshallguillory86/maintainability-agent@v4.4.4
539
+ - uses: marshallguillory86/maintainability-agent@v4.4.6
521
540
  with:
522
541
  config: maintainability-agent.json
523
542
  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.4**.
8
+ Version **4.4.6**.
9
9
 
10
10
  > ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
11
11
  >
@@ -48,10 +48,12 @@ npm install -g jscpd eslint # duplication + JavaScript/TypeScript
48
48
  brew install pmd checkstyle spotbugs # JVM languages, optional
49
49
  ```
50
50
 
51
- Unpinned on purpose: this is the exact set CI installs and calibrates against,
52
- and `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
53
- disagree. Nothing here is required — the audit runs without any of it and tells
54
- you what it could not measure.
51
+ This is the exact set CI installs, and
52
+ `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
53
+ disagree. CI installs it at the versions in `constraints/analyzers.txt`, the
54
+ ones the scale was calibrated with; add `-c constraints/analyzers.txt` from a
55
+ source checkout to match them. Nothing here is required — the audit runs
56
+ without any of it and tells you what it could not measure.
55
57
 
56
58
  **Install secure-code-agent for the security pillar.** Every audit runs it; it is
57
59
  installed alongside rather than as a dependency, so the two tools release
@@ -162,6 +164,7 @@ The full argument, including what this deliberately does not compete on:
162
164
  ```bash
163
165
  python3 -m pip install maintainability-agent
164
166
  maintainability-agent --root . --config maintainability-agent.json
167
+ maintainability-agent --update # later: upgrade, re-sync the skill, restart stale MCP servers
165
168
  ```
166
169
 
167
170
  Or run from a source checkout without installing:
@@ -225,6 +228,21 @@ withheld estimate. For PR work, add `--changed-only main...HEAD` to audit the
225
228
  diff; on a change too small to support a rate, the estimate and grade are
226
229
  withheld and the scope is named as the reason.
227
230
 
231
+ **Hold the code a change touches to a stricter bar.** `policy.changed_code` in
232
+ `maintainability-agent.json` sets tighter function limits for what a change
233
+ adds or alters, so a team can gate new work without first fixing every old
234
+ function:
235
+
236
+ ```json
237
+ "policy": {"changed_code": {"max_function_lines": 40, "max_complexity": 10}}
238
+ ```
239
+
240
+ On a `--changed-only` run, a function the change touched is held to it and
241
+ untouched code is judged by the standard as before. A policy only tightens — a
242
+ looser limit is refused when the config loads — and it decides the gate, never
243
+ the grade: breaches fail `--fail-on-gate` and are listed under *Changed-code
244
+ policy*, and the score is unchanged.
245
+
228
246
  ### Checking that the agent did the work
229
247
 
230
248
  The work order tells an agent to fix exactly these findings and refactor nothing
@@ -461,8 +479,9 @@ maintainability-agent --install-skill # writes ~/.claude/skills
461
479
  ```
462
480
 
463
481
  `maintainability-agent --update` upgrades the install to the newest release —
464
- never a downgrade — re-syncs the skill, and says when the MCP server needs a
465
- restart; `maintainability-agent --install-updater` runs it hourly (macOS launch
482
+ never a downgrade — re-syncs the skill, and stops any MCP server still on an
483
+ older version that is not mid-audit, so the host starts the new one on its
484
+ next call; `maintainability-agent --install-updater` runs it hourly (macOS launch
466
485
  agent). Run `--install-skill` by hand after any other upgrade — a drifted skill
467
486
  teaches agents a dead workflow,
468
487
  so a differing installed copy is refused with the list of differences. Per-host
@@ -475,7 +494,7 @@ instead of an invokable skill:
475
494
  This repo ships `action.yml`, usable as a composite action:
476
495
 
477
496
  ```yaml
478
- - uses: marshallguillory86/maintainability-agent@v4.4.4
497
+ - uses: marshallguillory86/maintainability-agent@v4.4.6
479
498
  with:
480
499
  config: maintainability-agent.json
481
500
  changed-only: main...HEAD
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: maintainability-agent
3
- Version: 4.4.4
3
+ Version: 4.4.6
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.4**.
50
+ Version **4.4.6**.
51
51
 
52
52
  > ## **Calibrated against 201 mature open-source repositories in fifteen languages.**
53
53
  >
@@ -90,10 +90,12 @@ npm install -g jscpd eslint # duplication + JavaScript/TypeScript
90
90
  brew install pmd checkstyle spotbugs # JVM languages, optional
91
91
  ```
92
92
 
93
- Unpinned on purpose: this is the exact set CI installs and calibrates against,
94
- and `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
95
- disagree. Nothing here is required — the audit runs without any of it and tells
96
- you what it could not measure.
93
+ This is the exact set CI installs, and
94
+ `test_the_readme_names_the_analyzer_pool_ci_installs` fails if the two ever
95
+ disagree. CI installs it at the versions in `constraints/analyzers.txt`, the
96
+ ones the scale was calibrated with; add `-c constraints/analyzers.txt` from a
97
+ source checkout to match them. Nothing here is required — the audit runs
98
+ without any of it and tells you what it could not measure.
97
99
 
98
100
  **Install secure-code-agent for the security pillar.** Every audit runs it; it is
99
101
  installed alongside rather than as a dependency, so the two tools release
@@ -204,6 +206,7 @@ The full argument, including what this deliberately does not compete on:
204
206
  ```bash
205
207
  python3 -m pip install maintainability-agent
206
208
  maintainability-agent --root . --config maintainability-agent.json
209
+ maintainability-agent --update # later: upgrade, re-sync the skill, restart stale MCP servers
207
210
  ```
208
211
 
209
212
  Or run from a source checkout without installing:
@@ -267,6 +270,21 @@ withheld estimate. For PR work, add `--changed-only main...HEAD` to audit the
267
270
  diff; on a change too small to support a rate, the estimate and grade are
268
271
  withheld and the scope is named as the reason.
269
272
 
273
+ **Hold the code a change touches to a stricter bar.** `policy.changed_code` in
274
+ `maintainability-agent.json` sets tighter function limits for what a change
275
+ adds or alters, so a team can gate new work without first fixing every old
276
+ function:
277
+
278
+ ```json
279
+ "policy": {"changed_code": {"max_function_lines": 40, "max_complexity": 10}}
280
+ ```
281
+
282
+ On a `--changed-only` run, a function the change touched is held to it and
283
+ untouched code is judged by the standard as before. A policy only tightens — a
284
+ looser limit is refused when the config loads — and it decides the gate, never
285
+ the grade: breaches fail `--fail-on-gate` and are listed under *Changed-code
286
+ policy*, and the score is unchanged.
287
+
270
288
  ### Checking that the agent did the work
271
289
 
272
290
  The work order tells an agent to fix exactly these findings and refactor nothing
@@ -503,8 +521,9 @@ maintainability-agent --install-skill # writes ~/.claude/skills
503
521
  ```
504
522
 
505
523
  `maintainability-agent --update` upgrades the install to the newest release —
506
- never a downgrade — re-syncs the skill, and says when the MCP server needs a
507
- restart; `maintainability-agent --install-updater` runs it hourly (macOS launch
524
+ never a downgrade — re-syncs the skill, and stops any MCP server still on an
525
+ older version that is not mid-audit, so the host starts the new one on its
526
+ next call; `maintainability-agent --install-updater` runs it hourly (macOS launch
508
527
  agent). Run `--install-skill` by hand after any other upgrade — a drifted skill
509
528
  teaches agents a dead workflow,
510
529
  so a differing installed copy is refused with the list of differences. Per-host
@@ -517,7 +536,7 @@ instead of an invokable skill:
517
536
  This repo ships `action.yml`, usable as a composite action:
518
537
 
519
538
  ```yaml
520
- - uses: marshallguillory86/maintainability-agent@v4.4.4
539
+ - uses: marshallguillory86/maintainability-agent@v4.4.6
521
540
  with:
522
541
  config: maintainability-agent.json
523
542
  changed-only: main...HEAD
@@ -185,6 +185,7 @@ tests/test_analyzer_scoring_path.py
185
185
  tests/test_analyzer_spread_range.py
186
186
  tests/test_analyzer_xml_bounds.py
187
187
  tests/test_analyzers_against_the_real_tools.py
188
+ tests/test_analyzers_leave_no_temp_dirs.py
188
189
  tests/test_analyzers_never_write.py
189
190
  tests/test_analyzers_report_what_actually_failed.py
190
191
  tests/test_anchor_and_mode.py
@@ -206,6 +207,7 @@ tests/test_band_concealment_class.py
206
207
  tests/test_band_concealment_p3.py
207
208
  tests/test_band_pressures.py
208
209
  tests/test_bands.py
210
+ tests/test_base_ref_only_where_it_exists.py
209
211
  tests/test_behaviour_suites_are_tests.py
210
212
  tests/test_body_or_signature_class.py
211
213
  tests/test_both_setup_paths_ask_the_same_stage.py
@@ -1,3 +1,3 @@
1
1
  """Maintainability Audit CI."""
2
2
 
3
- __version__ = "4.4.4"
3
+ __version__ = "4.4.6"
@@ -236,6 +236,29 @@ class BaseAdapter:
236
236
  # Empty means "trust the catalog entry".
237
237
  languages: tuple[str, ...] = ()
238
238
 
239
+ def scratch(self) -> Path:
240
+ """This run's scratch directory, made on first use (D235).
241
+
242
+ Four adapters made one with `mkdtemp` in their constructors and
243
+ never removed it, so every adapter object left a directory whether
244
+ or not its tool ran: 74,535 of them on one machine. Made here only
245
+ when a run needs it; `release` removes it.
246
+ """
247
+ made = getattr(self, "_scratch_dir", None)
248
+ if made is None:
249
+ import tempfile
250
+
251
+ made = Path(tempfile.mkdtemp(prefix=f"{self.slug}-"))
252
+ self._scratch_dir = made
253
+ return made
254
+
255
+ def release(self) -> None:
256
+ """Remove the scratch directory, if a run made one."""
257
+ made = getattr(self, "_scratch_dir", None)
258
+ if made is not None:
259
+ shutil.rmtree(made, ignore_errors=True)
260
+ self._scratch_dir = None
261
+
239
262
  def version_argv(self) -> tuple[str, ...]:
240
263
  return (self.executable, self.version_flag)
241
264
 
@@ -422,6 +422,12 @@ def _run_one(root: Path, adapter: Any, probe: Probe, timeout: int,
422
422
  "concern it covers is reported unexamined."
423
423
  ),
424
424
  )
425
+ finally:
426
+ # Every path, the backstop's included: a scratch dir left behind is
427
+ # one per run, forever (D235).
428
+ release = getattr(adapter, "release", None)
429
+ if release is not None:
430
+ release()
425
431
 
426
432
 
427
433
  def _cover_one(selected: Selected, root: Path, probe: Probe, timeout: int,
@@ -14,7 +14,6 @@ from __future__ import annotations
14
14
 
15
15
  import dataclasses
16
16
  import json
17
- import tempfile
18
17
  from collections.abc import Iterable, Sequence
19
18
  from pathlib import Path
20
19
  from typing import Any
@@ -167,7 +166,6 @@ class CheckstyleAdapter(BaseAdapter):
167
166
  findings_exit_codes=tuple(range(254)),
168
167
  languages=("java",),
169
168
  )
170
- self._work = Path(tempfile.mkdtemp(prefix="checkstyle-"))
171
169
 
172
170
  def has_targets(self, root: Path, excludes: Sequence[str] = ()) -> bool:
173
171
  """Whether any .java file survives the exclusions (never spawn empty)."""
@@ -189,7 +187,7 @@ class CheckstyleAdapter(BaseAdapter):
189
187
  # resolves its optional checkstyle-suppressions.xml against
190
188
  # the working directory, and the audited tree must not be
191
189
  # able to suppress its own findings (audit M2).
192
- cwd=self._work,
190
+ cwd=self.scratch(),
193
191
  )
194
192
 
195
193
  def _read(self, result: ToolResult) -> Extraction:
@@ -265,15 +263,19 @@ class SpotBugsAdapter(BaseAdapter):
265
263
  # default detectors include the SECURITY category. A bundled
266
264
  # exclude filter — written to this adapter's own scratch dir,
267
265
  # never read from the audited tree — keeps that boundary real
268
- # instead of documentation (48293d3 audit M1).
269
- self._work = Path(tempfile.mkdtemp(prefix="spotbugs-"))
270
- self._exclude = self._work / "exclude-security.xml"
271
- self._exclude.write_text(
272
- "<FindBugsFilter>\n"
273
- ' <Match><Bug category="SECURITY"/></Match>\n'
274
- "</FindBugsFilter>\n",
275
- encoding="utf-8",
276
- )
266
+ # instead of documentation (48293d3 audit M1). Written when a run
267
+ # needs it, into a scratch dir removed after the run (D235).
268
+
269
+ def _exclude_filter(self) -> Path:
270
+ path = self.scratch() / "exclude-security.xml"
271
+ if not path.exists():
272
+ path.write_text(
273
+ "<FindBugsFilter>\n"
274
+ ' <Match><Bug category="SECURITY"/></Match>\n'
275
+ "</FindBugsFilter>\n",
276
+ encoding="utf-8",
277
+ )
278
+ return path
277
279
 
278
280
  def version_argv(self) -> tuple[str, ...]:
279
281
  return ("spotbugs", "-version")
@@ -347,7 +349,7 @@ class SpotBugsAdapter(BaseAdapter):
347
349
  dirs = self._target_dirs(root, class_dirs)
348
350
  return Invocation(
349
351
  argv=("spotbugs", "-textui", "-exitcode", "-xml:withMessages",
350
- "-exclude", str(self._exclude),
352
+ "-exclude", str(self._exclude_filter()),
351
353
  *(str(directory) for directory in dirs)),
352
354
  findings_exit_codes=self.findings_exit_codes,
353
355
  )
@@ -14,7 +14,6 @@ import csv
14
14
  import io
15
15
  import json
16
16
  import re
17
- import tempfile
18
17
  from collections.abc import Iterable, Sequence
19
18
  from pathlib import Path
20
19
 
@@ -196,7 +195,6 @@ class ComplexipyAdapter(BaseAdapter):
196
195
  slug="complexipy", emits="metric", executable="complexipy",
197
196
  concepts=("cognitive_complexity",), findings_exit_codes=(0, 1),
198
197
  )
199
- self._work = Path(tempfile.mkdtemp(prefix="complexipy-"))
200
198
 
201
199
  def target_files(self, root: Path, excludes: Sequence[str] = ()) -> tuple[str, ...]:
202
200
  return expand_files(root.resolve(), excludes)
@@ -212,11 +210,11 @@ class ComplexipyAdapter(BaseAdapter):
212
210
  return Invocation(
213
211
  argv=(self.executable, *targets, "--output-format", "json", "--quiet"),
214
212
  findings_exit_codes=self.findings_exit_codes,
215
- cwd=self._work,
213
+ cwd=self.scratch(),
216
214
  )
217
215
 
218
216
  def _read(self, result: ToolResult) -> Extraction:
219
- report = self._work / "complexipy-results.json"
217
+ report = self.scratch() / "complexipy-results.json"
220
218
  if not report.exists():
221
219
  raise ValueError("complexipy wrote no results file")
222
220
  entries = json.loads(report.read_text(encoding="utf-8"))
@@ -20,7 +20,6 @@ for analyzability and testability. Two kinds of number, two modules.
20
20
  from __future__ import annotations
21
21
 
22
22
  import json
23
- import tempfile
24
23
  from collections.abc import Iterable, Sequence
25
24
  from pathlib import Path
26
25
 
@@ -64,8 +63,8 @@ class JscpdAdapter(BaseAdapter):
64
63
  # picks the destination when it builds the invocation and reads it
65
64
  # back when parsing. A scratch directory rather than the scanned
66
65
  # tree: writing into the repository under audit would change what
67
- # the next tool sees.
68
- self._report_dir = Path(tempfile.mkdtemp(prefix="jscpd-"))
66
+ # the next tool sees. Made on first use and removed after the
67
+ # run (`BaseAdapter.scratch`, D235).
69
68
 
70
69
  def version_argv(self) -> tuple[str, ...]:
71
70
  return _npx("jscpd", "--version")
@@ -91,11 +90,11 @@ class JscpdAdapter(BaseAdapter):
91
90
  ignore = ("--ignore", ",".join(patterns)) if patterns else ()
92
91
  return Invocation(
93
92
  argv=(*_npx("jscpd"), str(root), "--reporters", "json", "--silent",
94
- *ignore, "--output", str(self._report_dir)),
93
+ *ignore, "--output", str(self.scratch())),
95
94
  )
96
95
 
97
96
  def _read(self, result: ToolResult) -> Extraction:
98
- report = self._report_dir / "jscpd-report.json"
97
+ report = self.scratch() / "jscpd-report.json"
99
98
  raw = report.read_text(encoding="utf-8") if report.exists() else result.stdout
100
99
  if not raw.strip():
101
100
  # No report file and no stdout is "ran, produced nothing",
@@ -43,7 +43,7 @@ from .config import (
43
43
  load_config,
44
44
  repository_path,
45
45
  )
46
- from .git_tools import changed_paths
46
+ from .git_tools import GitCommandFailed, changed_paths
47
47
  from .instructions import (
48
48
  INSTRUCTION_TARGETS,
49
49
  UnknownTarget,
@@ -492,7 +492,14 @@ def main(argv: list[str] | None = None) -> int:
492
492
  return 0
493
493
 
494
494
  selection = _selection_from(parser, args.work)
495
- only_paths = changed_paths(root, args.changed_only) if args.changed_only else None
495
+ try:
496
+ only_paths = changed_paths(root, args.changed_only) if args.changed_only else None
497
+ except GitCommandFailed as unresolved:
498
+ # A range git cannot resolve is a bad input, said so by name, not a
499
+ # traceback a pipeline cannot tell from a broken tool (D234).
500
+ print(f"maintainability-agent: --changed-only {args.changed_only} cannot be "
501
+ f"resolved ({unresolved})", file=sys.stderr)
502
+ return 2
496
503
  external_findings = read_sarif_inputs(args.sarif_input)
497
504
  report = build_report(root, config, only_paths=only_paths,
498
505
  changed_revspec=args.changed_only,
@@ -31,8 +31,6 @@ calibration constant against the new path is 3.6.
31
31
  from __future__ import annotations
32
32
 
33
33
  import subprocess
34
- import tempfile
35
- from pathlib import Path
36
34
 
37
35
  import pytest
38
36
 
@@ -44,9 +42,9 @@ from maintainability_audit.scoring import score_evidence
44
42
 
45
43
 
46
44
  @pytest.fixture
47
- def evidence():
45
+ def evidence(tmp_path):
48
46
  """A committed tree of ordinary small functions, scored cleanly."""
49
- root = Path(tempfile.mkdtemp()) / "r"
47
+ root = tmp_path / "r"
50
48
  root.mkdir()
51
49
  subprocess.run(["git", "init", "-q", str(root)], check=True)
52
50
  (root / "README.md").write_text("# r\n", encoding="utf-8")
@@ -0,0 +1,88 @@
1
+ """An analyzer leaves nothing behind in the system temp directory (D235).
2
+
3
+ Four adapters — jscpd, complexipy, checkstyle, spotbugs — made a scratch
4
+ directory with `tempfile.mkdtemp` in their constructors and never removed
5
+ it. Every adapter object built left a directory, whether or not its tool
6
+ ever ran: the registry is built on every audit and many times in every
7
+ test run, so one machine's temp directory held 74,535 of them (21,294
8
+ `jscpd-`, 20,185 `complexipy-`, 16,952 `checkstyle-`, 16,104 `spotbugs-`)
9
+ on a disk at 98%, and removing them freed 13.5 GB.
10
+
11
+ A scratch directory is now made only when a tool is about to run, and is
12
+ removed once its output has been read, whatever the outcome.
13
+ """
14
+
15
+ from __future__ import annotations
16
+
17
+ import tempfile
18
+ from pathlib import Path
19
+ from types import SimpleNamespace
20
+
21
+ import pytest
22
+
23
+ from maintainability_audit import _analysis
24
+ from maintainability_audit._generic import DECLARED, declared_adapter
25
+ from maintainability_audit._runner import Outcome, ToolResult
26
+ from maintainability_audit._tool_adapters import ADAPTERS
27
+
28
+ SCRATCH_ADAPTERS = ("jscpd", "complexipy", "checkstyle", "spotbugs")
29
+
30
+
31
+ @pytest.fixture
32
+ def temp_root(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> Path:
33
+ """The system temp directory, redirected to one this test can count."""
34
+ root = tmp_path / "system-temp"
35
+ root.mkdir()
36
+ monkeypatch.setattr(tempfile, "tempdir", str(root))
37
+ return root
38
+
39
+
40
+ def test_building_every_adapter_makes_no_directory(temp_root: Path) -> None:
41
+ adapters = [make() for make in ADAPTERS.values()] + [declared_adapter(slug) for slug in DECLARED]
42
+
43
+ assert len(adapters) > 10
44
+ assert list(temp_root.iterdir()) == []
45
+
46
+
47
+ @pytest.mark.parametrize("slug", SCRATCH_ADAPTERS)
48
+ def test_a_run_removes_its_scratch_directory_whatever_the_outcome(
49
+ slug: str, temp_root: Path, tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None:
50
+ tree = tmp_path / "tree"
51
+ tree.mkdir()
52
+ (tree / "A.java").write_text("class A {}\n", encoding="utf-8")
53
+ (tree / "a.py").write_text("x = 1\n", encoding="utf-8")
54
+ (tree / "build" / "classes").mkdir(parents=True)
55
+ (tree / "build" / "classes" / "A.class").write_bytes(b"\xca\xfe\xba\xbe")
56
+ monkeypatch.setattr(_analysis, "run", lambda tool, invocation, **k: ToolResult(
57
+ slug=tool, outcome=Outcome.RAN, stdout="", stderr="", exit_code=0))
58
+ probe = SimpleNamespace(check=lambda tool, argv: SimpleNamespace(
59
+ usable=True, version="1", outcome=Outcome.RAN, detail=""))
60
+
61
+ _analysis._run_one(tree, ADAPTERS[slug](), probe, 60, _analysis.Analysis())
62
+
63
+ assert list(temp_root.iterdir()) == []
64
+
65
+
66
+ def test_no_test_makes_a_temp_directory_it_never_removes() -> None:
67
+ """The suite's own share of the same leak: `mkdtemp` is never cleaned up.
68
+
69
+ `tmp_path` is pytest's and is pruned; `TemporaryDirectory` removes
70
+ itself. A bare `mkdtemp` in a test leaves one directory per run.
71
+ """
72
+ tests = Path(__file__).resolve().parent
73
+ offenders = sorted(
74
+ path.name for path in tests.glob("*.py")
75
+ if path.name != Path(__file__).name and "mkdtemp(" in path.read_text(encoding="utf-8")
76
+ )
77
+ assert offenders == [], f"these tests leave a temp directory behind: {offenders}"
78
+
79
+
80
+ def test_every_test_writes_its_temp_files_under_pytests_own_base(
81
+ tmp_path: Path, tmp_path_factory: pytest.TempPathFactory) -> None:
82
+ """A test that builds an adapter and calls it piecemeal never reaches the
83
+ release in `_run_one`; the suite left 29 directories that way after the
84
+ adapters were fixed. So no test can write to the system temp directory —
85
+ and not into `tmp_path` either, which is often the tree under audit."""
86
+ temp = Path(tempfile.gettempdir()).resolve()
87
+ assert temp.is_relative_to(tmp_path_factory.getbasetemp().resolve())
88
+ assert not temp.is_relative_to(tmp_path.resolve())
@@ -93,10 +93,16 @@ def test_no_artifact_writer_reaches_for_a_raw_write_text() -> None:
93
93
  )
94
94
 
95
95
 
96
- def _inward_symlink_repo() -> Path:
96
+ @pytest.fixture
97
+ def inward_repo():
97
98
  """A repo under ``/var`` (unresolved on macOS) whose ``.maintainability``
98
- is a symlink back into ``src`` -- the redirect ``tmp_path`` cannot make."""
99
- base = Path(tempfile.mkdtemp(dir="/var/tmp"))
99
+ is a symlink back into ``src`` -- the redirect ``tmp_path`` cannot make.
100
+ Removed afterwards; a bare ``mkdtemp`` left one per run (D235)."""
101
+ with tempfile.TemporaryDirectory(dir="/var/tmp") as base:
102
+ yield _inward_symlink_repo(Path(base))
103
+
104
+
105
+ def _inward_symlink_repo(base: Path) -> Path:
100
106
  root = base / "repo"
101
107
  (root / "src").mkdir(parents=True)
102
108
  (root / "src" / "app.py").write_text("x = 1\n", encoding="utf-8")
@@ -109,12 +115,12 @@ def _report(root: Path) -> dict:
109
115
 
110
116
 
111
117
  @pytest.mark.parametrize("spelling", ["/var", "/private/var"])
112
- def test_write_baseline_refuses_the_inward_route_on_either_spelling(spelling: str) -> None:
118
+ def test_write_baseline_refuses_the_inward_route_on_either_spelling(spelling: str, inward_repo: Path) -> None:
113
119
  """``.maintainability -> src`` is refused whether the grant is named
114
120
  ``/var/...`` or its ``/private/var/...`` real path. Binding the check
115
121
  to ``target.parent`` checked the symlink against itself and let both
116
122
  through."""
117
- root = _inward_symlink_repo()
123
+ root = inward_repo
118
124
  if spelling == "/private/var":
119
125
  root = Path(os.path.realpath(root))
120
126
  target = root / ".maintainability" / "baseline.json"
@@ -125,11 +131,11 @@ def test_write_baseline_refuses_the_inward_route_on_either_spelling(spelling: st
125
131
  assert not (Path(os.path.realpath(root)) / "src" / "baseline.json").exists()
126
132
 
127
133
 
128
- def test_write_baseline_refuses_to_truncate_a_non_json_file() -> None:
134
+ def test_write_baseline_refuses_to_truncate_a_non_json_file(inward_repo: Path) -> None:
129
135
  """``write_baseline(baseline_path="README.md")`` truncated source once
130
136
  (D34). A stage-and-replace still unlinks that inode, so the refusal is
131
137
  on the existing bytes not being JSON, before any stage begins."""
132
- root = _inward_symlink_repo()
138
+ root = inward_repo
133
139
  readme = root / "README.md"
134
140
  readme.write_text("# real docs\n", encoding="utf-8")
135
141
  report = _report(root)
@@ -138,11 +144,11 @@ def test_write_baseline_refuses_to_truncate_a_non_json_file() -> None:
138
144
  assert readme.read_text(encoding="utf-8") == "# real docs\n"
139
145
 
140
146
 
141
- def test_a_baseline_outside_the_tree_is_still_allowed() -> None:
147
+ def test_a_baseline_outside_the_tree_is_still_allowed(inward_repo: Path) -> None:
142
148
  """The predating contract: a person may keep a baseline outside the
143
149
  audited tree. Outside the grant the tree cannot plant a route, so the
144
150
  write proceeds -- the refusals above do not become a new bound."""
145
- root = _inward_symlink_repo()
151
+ root = inward_repo
146
152
  outside = root.parent / "backups" / "baseline.json"
147
153
  write_baseline(str(outside), _report(root))
148
154
  assert json.loads(outside.read_text(encoding="utf-8"))["version"] == 3